* [PATCH 2/2] arm64: kernel: use seq_puts() instead of seq_printf()
From: Jingoo Han @ 2014-01-29 4:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140128155156.GC24617@arm.com>
On Wednesday, January 29, 2014 12:52 AM, Catalin Marinas wrote:
> On Tue, Jan 28, 2014 at 01:36:18AM +0000, Jingoo Han wrote:
> > For a constant format without additional arguments, use seq_puts()
> > instead of seq_printf(). Also, it fixes the following checkpatch
> > warning.
> >
> > WARNING: Prefer seq_puts to seq_printf
> >
> > Signed-off-by: Jingoo Han <jg1.han@samsung.com>
> > ---
> > arch/arm64/kernel/setup.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> > index c8e9eff..4507691 100644
> > --- a/arch/arm64/kernel/setup.c
> > +++ b/arch/arm64/kernel/setup.c
> > @@ -416,7 +416,7 @@ static int c_show(struct seq_file *m, void *v)
> > seq_printf(m, "%s ", hwcap_str[i]);
> >
> > seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
> > - seq_printf(m, "CPU architecture: AArch64\n");
> > + seq_puts(m, "CPU architecture: AArch64\n");
> > seq_printf(m, "CPU variant\t: 0x%x\n", (read_cpuid_id() >> 20) & 15);
> > seq_printf(m, "CPU part\t: 0x%03x\n", (read_cpuid_id() >> 4) & 0xfff);
> > seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
>
> Just ignore the checkpatch warning. I prefer the consistency of
> seq_printf() in this function.
(+cc Joe Perches, Dan Carpenter)
Personally, I don't like the checkpatch warning.
However, I respect your opinion on the consistency.
Thank you for your comment.
Best regards,
Jingoo Han
^ permalink raw reply
* [RFC PATCH 2/3] ARM/ARM64: KVM: Add support for PSCI v0.2 emulation
From: Anup Patel @ 2014-01-29 4:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140128210410.GA26671@cbox>
On Wed, Jan 29, 2014 at 2:34 AM, Christoffer Dall
<christoffer.dall@linaro.org> wrote:
> On Tue, Jan 21, 2014 at 06:31:40PM +0530, 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)
>> +#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 /* __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))
>> + *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);
>
> Which tree does this patch apply to? It looks like you'll get a
> conflict with:
> 478a823 arm: KVM: Don't return PSCI_INVAL if waitqueue is inactive
This patchset applies on v3.13 tag of Torvalds tree.
I generally base my patches on latest stable/rc tag of Torvalds tree
so that I can provide KVM patches to folks interested in trying KVM
on X-Gene with latest Linux stable/rc.
I will make sure that revised patchset applies on top of
478a823 arm: KVM: Don't return PSCI_INVAL if waitqueue is inactive
>
>> }
>>
>> 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);
>> +}
>
> Why don't we just try one after the other? Do they conflict in some
> way?
Atleast the functions IDs are totally different in v0.2 and v0.1
Also, in v0.2 we have separate function IDs for 32bit and 64bit
VCPU calling same PSCI function.
>
> I assume PSCI calls are never going to be in the critical path and calls
> into PSCI are pretty much expected to be slow as a dog anyhow, so if we
> could avoid the extra churn in user space code and potential user
> confusion (providing PSCI 0.2 kernel but too old user space tool for
> example), I think that would be preferred.
Yes, PSCI calls will not be in critical path except few functions such as
PSCI CPU_SUSPEND and CPU_ON.
For example,
On real HW, people are very much interested in time taken to resume a
HW CPU from suspended state because this affects responsiveness of
a system.
>
>> 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
>>
>
> Thanks,
> --
> Christoffer
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
--
Anup
^ permalink raw reply
* [RFC PATCH 3/3] KVM: Documentation: Add info regarding KVM_ARM_VCPU_PSCI_0_2 feature
From: Anup Patel @ 2014-01-29 4:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140128210535.GB26671@cbox>
On Wed, Jan 29, 2014 at 2:35 AM, Christoffer Dall
<christoffer.dall@linaro.org> wrote:
> On Tue, Jan 21, 2014 at 06:31:41PM +0530, Anup Patel wrote:
>> We have in-kernel emulation of PSCI v0.2 in KVM ARM/ARM64. To provide
>> PSCI v0.2 interface to VCPUs, we have to enable KVM_ARM_VCPU_PSCI_0_2
>> feature when doing KVM_ARM_VCPU_INIT ioctl.
>>
>> The patch updates documentation of KVM_ARM_VCPU_INIT ioctl to provide
>> info regarding KVM_ARM_VCPU_PSCI_0_2 feature.
>>
>> Signed-off-by: Anup Patel <anup.patel@linaro.org>
>> Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
>> ---
>> Documentation/virtual/kvm/api.txt | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
>> index aad3244..a15fcdd 100644
>> --- a/Documentation/virtual/kvm/api.txt
>> +++ b/Documentation/virtual/kvm/api.txt
>> @@ -2346,6 +2346,8 @@ Possible features:
>> Depends on KVM_CAP_ARM_PSCI.
>> - KVM_ARM_VCPU_EL1_32BIT: Starts the CPU in a 32bit mode.
>> Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only).
>> + - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 for CPU.
>
> nit: s/for CPU/for the CPU/
OK, I'll update this.
>
>> + Depends on KVM_CAP_ARM_PSCI_0_2.
>>
>>
>> 4.83 KVM_ARM_PREFERRED_TARGET
>> --
>> 1.7.9.5
>>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
--
Anup
^ permalink raw reply
* Tegra baseline test results for v3.13
From: Paul Walmsley @ 2014-01-29 4:29 UTC (permalink / raw)
To: linux-arm-kernel
Here are some basic Tegra test results for Linux v3.13.
Logs and other details at:
http://nvt.pwsan.com/pub/linux/testlogs/test_v3.13/20140119190136/
Test summary
------------
Build: zImage:
Pass: ( 2/ 2): multi_v7_defconfig, tegra_defconfig
Boot to userspace: multi_v7_defconfig:
Pass: ( 2/ 2): tegra114-dalmore-headless, tegra30-beaver
Boot to userspace: tegra_defconfig:
Pass: ( 2/ 2): tegra114-dalmore-headless, tegra30-beaver
vmlinux object size
(delta in bytes from test_v3.13-rc8 (7e22e91102c6b9df7c4ae2168910e19d2bb14cd6)):
text data bss total kernel
+28 -24 0 +4 multi_v7_defconfig
+380 0 0 +380 tegra_defconfig
Boot-time memory difference
(delta in bytes from test_v3.13-rc8 (7e22e91102c6b9df7c4ae2168910e19d2bb14cd6))
avail rsrvd high freed board kconfig dtb
. . . . tegra114-dalmore-hea multi_v7_defconfig tegra114-dalmore
. . . . tegra114-dalmore-hea tegra_defconfig tegra114-dalmore
. . . . tegra30-beaver multi_v7_defconfig tegra30-beaver
. . . . tegra30-beaver tegra_defconfig tegra30-beaver
^ permalink raw reply
* [linux-sunxi] Re: [PATCH RFC 4/6] net: rfkill: gpio: add device tree support
From: Chen-Yu Tsai @ 2014-01-29 4:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140127142400.GI3867@lukather>
Hi,
On Mon, Jan 27, 2014 at 10:24 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Fri, Jan 17, 2014 at 02:47:29PM +0800, Chen-Yu Tsai wrote:
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> ---
>> .../devicetree/bindings/rfkill/rfkill-gpio.txt | 26 ++++++++++++++++++++++
>> net/rfkill/rfkill-gpio.c | 23 +++++++++++++++++++
>> 2 files changed, 49 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/rfkill/rfkill-gpio.txt
>>
>> diff --git a/Documentation/devicetree/bindings/rfkill/rfkill-gpio.txt b/Documentation/devicetree/bindings/rfkill/rfkill-gpio.txt
>> new file mode 100644
>> index 0000000..8a07ea4
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/rfkill/rfkill-gpio.txt
>> @@ -0,0 +1,26 @@
>> +GPIO controlled RFKILL devices
>> +
>> +Required properties:
>> +- compatible : Must be "rfkill-gpio".
>> +- rfkill-name : Name of RFKILL device
>> +- rfkill-type : Type of RFKILL device: 1 for WiFi, 2 for BlueTooth
>> +- NAME_shutdown-gpios : GPIO phandle to shutdown control
>> + (phandle must be the second)
>
> Can't it be handled by a regulator?
>
>> +- NAME_reset-gpios : GPIO phandle to reset control
>
> And this one using the reset framework?
The driver is already used in platform device and ACPI fashions.
AFAIK, ACPI only passes the GPIO lines. Preferably the behavior
and requirements between the different usages remain the same.
Cheers
ChenYu
^ permalink raw reply
* [PATCH v3 3/6] misc: fuse: Add efuse driver for Tegra
From: Jim Lin @ 2014-01-29 2:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390952176-30402-4-git-send-email-pdeschrijver@nvidia.com>
On Wed, 2014-01-29 at 07:36 +0800, Peter De Schrijver wrote:
> Implement fuse driver for Tegra20, Tegra30, Tegra114 and Tegra124.
>
> Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
> ---
> Documentation/ABI/testing/sysfs-driver-tegra-fuse | 8 +
> drivers/misc/fuse/Makefile | 1 +
> drivers/misc/fuse/tegra/Makefile | 7 +
> drivers/misc/fuse/tegra/fuse-tegra.c | 228 ++++++++++++++++
> drivers/misc/fuse/tegra/fuse-tegra20.c | 136 ++++++++++
> drivers/misc/fuse/tegra/fuse-tegra30.c | 178 +++++++++++++
> drivers/misc/fuse/tegra/fuse.h | 82 ++++++
Could we move this fuse.h to other folder under /include/linux
(like /include/linux/platform_data)
for other driver to include?
So other driver can invoke function to read fuse data if needed.
--nvpublic
^ permalink raw reply
* [PATCH v3 2/8] clk: sunxi: update clock-output-names dt binding documentation
From: Chen-Yu Tsai @ 2014-01-29 1:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52D89BB1.3030206@elopez.com.ar>
Hi Maxime,
On Fri, Jan 17, 2014 at 10:55 AM, Emilio L?pez <emilio@elopez.com.ar> wrote:
> Hi,
>
> El 09/01/14 05:52, Chen-Yu Tsai escribi?:
>
>> clock-output-names is now required for most of sunxi clock nodes, to
>> provide the name of the corresponding clock. Add the new requirements,
>> exceptions, as well as examples.
>>
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> ---
>> Documentation/devicetree/bindings/clock/sunxi.txt | 36
>> +++++++++++++++++++----
>> 1 file changed, 31 insertions(+), 5 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt
>> b/Documentation/devicetree/bindings/clock/sunxi.txt
>> index 0c127cd..8a9147d 100644
>> --- a/Documentation/devicetree/bindings/clock/sunxi.txt
>> +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
>> @@ -44,10 +44,18 @@ Required properties for all clocks:
>> multiplexed clocks, the list order must match the hardware
>> programming order.
>> - #clock-cells : from common clock binding; shall be set to 0 except for
>> - "allwinner,*-gates-clk" where it shall be set to 1
>> + "allwinner,*-gates-clk", "allwinner,sun4i-pll5-clk" and
>> + "allwinner,sun4i-pll6-clk" where it shall be set to 1
>>
>> -Additionally, "allwinner,*-gates-clk" clocks require:
>> -- clock-output-names : the corresponding gate names that the clock
>> controls
>> +Additionally, most clocks require "clock-output-names":
>> +- "allwinner,*-gates-clk" : the corresponding gate names that the clock
>> controls
>> +- "allwinner,sun4i-pll5-clk" : "pll5_ddr", "pll5_mbus"
>> +- "allwinner,sun4i-pll6-clk" : "pll6_sata", "pll6_other"
>> +- "allwinner,sun4i-cpu-clk", "allwinner,sun4i-axi-clk",
>> + "allwinner,sun4i-ahb-clk", "allwinner,sun4i-ahb-clk",
>> + "allwinner,sun4i-apb1-mux-clk", "allwinner,sun4i-apb1-clk"
>> + do not need "clock-output-names"
>> +- all others clocks : the corresponding module name of that clock
>
>
> As we discussed on IRC, I wonder if such verbosity is actually needed. Maybe
> we should dictate that all clocks must list their corresponding outputs on
> clock-output-names (with it being the module name if it only has one
> output).
Maxime, could we get your input on this?
Thanks
ChenYu
^ permalink raw reply
* [REGRESSION] Biscted to 'memblock, nobootmem: add memblock_virt_alloc_low()'
From: Sören Brinkmann @ 2014-01-29 1:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <35c4753f-bcb5-46df-b273-e5b39db163f0@CO9EHSMHS018.ehs.local>
Never mind. I just saw, Zynq is not the only affected ARM platform and
the issue is already being discussed on the list:
https://lkml.org/lkml/2014/1/28/52
S?ren
^ permalink raw reply
* [REGRESSION] Biscted to 'memblock, nobootmem: add memblock_virt_alloc_low()'
From: Sören Brinkmann @ 2014-01-29 0:44 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
I just found that the current Linux tree
(HEAD@ d891ea23d5203e5c47439b2a174f86a00b356a6c ) fails to boot on
Zynq (ARM).
The system runs into a panic relatively early (full boot log attached):
[ 0.000000] Unable to handle kernel paging request at virtual address ffffffc0
[ 0.000000] pgd = c0004000
[ 0.000000] [ffffffc0] *pgd=2e7f6821, *pte=00000000, *ppte=00000000
[ 0.000000] Internal error: Oops: 817 [#1] PREEMPT SMP ARM
[ 0.000000] Modules linked in:
[ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 3.13.0-xilinx-08988-gd891ea23d520 #22
[ 0.000000] task: c0385ab0 ti: c037c000 task.ti: c037c000
[ 0.000000] PC is at __memzero+0x4c/0x80
[ 0.000000] LR is at 0x0
[ 0.000000] pc : [<c01d9ccc>] lr : [<00000000>] psr: 000001d3
[ 0.000000] sp : c037df0c ip : 00000000 fp : 00000000
[ 0.000000] r10: ffffffff r9 : ffffffff r8 : 3fffffc0
[ 0.000000] r7 : ffffffff r6 : ffffffc0 r5 : 00000040 r4 : 0000001c
[ 0.000000] r3 : 00000000 r2 : 00000000 r1 : ffffffdc r0 : ffffffc0
[ 0.000000] Flags: nzcv IRQs off FIQs off Mode SVC_32 ISA ARM Segment kernel
[ 0.000000] Control: 18c5387d Table: 0000404a DAC: 00000015
[ 0.000000] Process swapper (pid: 0, stack limit = 0xc037c240)
[ 0.000000] Stack: (0xc037df0c to 0xc037e000)
[ 0.000000] df00: c0365cfc ffffffff 00000000 ffffffff 0000001c
[ 0.000000] df20: ffffffff 00000000 00000000 413fc090 c038704c c0365f08 ffffffff c0370368
[ 0.000000] df40: ffff1000 0002e7f5 00001000 00000007 c038dff0 c0370368 c039ebf4 c037dfd4
[ 0.000000] df60: c0370368 c039ebf4 c08ef12c c038704c c038dff0 c035aabc ffffffff 18c5387d
[ 0.000000] df80: ffffffff 0000406a 413fc090 c03843c0 00000000 c025eb74 c02f23a9 c037dfb4
[ 0.000000] dfa0: c0008200 c037c000 00000001 c039e840 ffffffff 0000406a c03843c0 c0357854
[ 0.000000] dfc0: 00000000 00000000 00000000 00000000 00000000 c0372918 18c5387d c0384410
[ 0.000000] dfe0: c0372914 c038717c 0000406a 413fc090 00000000 00008074 00000000 00000000
[ 0.000000] Code: e3110020 18a0500c 18a0500c e3110010 (18a0500c)
[ 0.000000] ---[ end trace 15c15b4afa9eff8e ]---
[ 0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
I bisected this issue down to commit:
ad6492b80f60a2139fa9bf8fd79b182fe5e3647c is the first bad commit
commit ad6492b80f60a2139fa9bf8fd79b182fe5e3647c
Author: Yinghai Lu <yinghai@kernel.org>
Date: Mon Jan 27 17:06:49 2014 -0800
memblock, nobootmem: add memblock_virt_alloc_low()
The new memblock_virt APIs are used to replaced old bootmem API.
We need to allocate page below 4G for swiotlb.
That should fix regression on Andrew's system that is using swiotlb.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
:040000 040000 75086461d0b57fca2e767b9be2e660a3fc34fc8b 2365645efe4f6ad75fcfaab3e59da2d9cf0968a2 M arch
:040000 040000 106df01421a1d64347ee050c854e2540064a060b fab0ad7e09604c1ce795abdee894896619822838 M include
:040000 040000 f67991f1b98d03d9791883a5b714bb1d8e6ae596 f6067483b5d7a5688bd873e75a3b4e89df104234 M lib
Reverting that commit on top of HEAD results in a booting system again.
I also attached my kernel config.
Is this somehow related to this discussion regarding the non-DMAabble
memory (though that case doesn't seem to panic):
https://lkml.org/lkml/2014/1/27/212 ?
Thanks,
S?ren
-------------- next part --------------
U-Boot 2013.10 (Jan 13 2014 - 14:43:20)
I2C: ready
Memory: ECC disabled
DRAM: 1 GiB
MMC: zynq_sdhci: 0
SF: Detected S25FL128S_64K with page size 512 Bytes, erase size 128 KiB, total 32 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: Gem.e000b000
Hit any key to stop autoboot: 3 \b\b\b 2 \b\b\b 1 \b\b\b 0
TFTPing Linux to RAM...
Gem.e000b000 Waiting for PHY auto negotiation to complete...... done
Using Gem.e000b000 device
TFTP from server 10.10.70.101; our IP address is 10.10.70.102
Filename 'uImage'.
Load address: 0x3000000
Loading: *\b##################################################T ###############
#################################################################
#
104.5 KiB/s
done
Bytes transferred = 1919032 (1d4838 hex)
Gem.e000b000:7 is connected to Gem.e000b000. Reconnecting to Gem.e000b000
Gem.e000b000 Waiting for PHY auto negotiation to complete....... done
Using Gem.e000b000 device
TFTP from server 10.10.70.101; our IP address is 10.10.70.102
Filename 'devicetree.dtb'.
Load address: 0x2a00000
Loading: *\b#
65.4 KiB/s
done
Bytes transferred = 3363 (d23 hex)
Gem.e000b000:7 is connected to Gem.e000b000. Reconnecting to Gem.e000b000
Gem.e000b000 Waiting for PHY auto negotiation to complete....... done
Using Gem.e000b000 device
TFTP from server 10.10.70.101; our IP address is 10.10.70.102
Filename 'uramdisk.image.gz'.
Load address: 0x2000000
Loading: *\b#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##########################################################
11.9 MiB/s
done
Bytes transferred = 5619967 (55c0ff hex)
## Booting kernel from Legacy Image at 03000000 ...
Image Name: Linux-3.13.0-xilinx-08988-gd891e
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1918968 Bytes = 1.8 MiB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK
## Loading init Ramdisk from Legacy Image at 02000000 ...
Image Name:
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 5619903 Bytes = 5.4 MiB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
## Flattened Device Tree blob at 02a00000
Booting using the fdt blob at 0x2a00000
Loading Kernel Image ... OK
Loading Ramdisk to 1faa3000, end 1ffff0bf ... OK
Loading Device Tree to 1fa9f000, end 1faa2d22 ... OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 3.13.0-xilinx-08988-gd891ea23d520 (sorenb at xsjandreislx) (gcc version 4.7.1 (Ubuntu/Linaro 4.7.1-5ubuntu1~ppa1) ) #22 SMP PREEMPT Tue Jan 28 16:18:49 PST 2014
[ 0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] Machine model: Zynq ZC706 Development Board
[ 0.000000] bootconsole [earlycon0] enabled
[ 0.000000] cma: CMA: reserved 16 MiB at 2e800000
[ 0.000000] Memory policy: Data cache writealloc
[ 0.000000] Unable to handle kernel paging request at virtual address ffffffc0
[ 0.000000] pgd = c0004000
[ 0.000000] [ffffffc0] *pgd=2e7f6821, *pte=00000000, *ppte=00000000
[ 0.000000] Internal error: Oops: 817 [#1] PREEMPT SMP ARM
[ 0.000000] Modules linked in:
[ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 3.13.0-xilinx-08988-gd891ea23d520 #22
[ 0.000000] task: c0385ab0 ti: c037c000 task.ti: c037c000
[ 0.000000] PC is at __memzero+0x4c/0x80
[ 0.000000] LR is at 0x0
[ 0.000000] pc : [<c01d9ccc>] lr : [<00000000>] psr: 000001d3
[ 0.000000] sp : c037df0c ip : 00000000 fp : 00000000
[ 0.000000] r10: ffffffff r9 : ffffffff r8 : 3fffffc0
[ 0.000000] r7 : ffffffff r6 : ffffffc0 r5 : 00000040 r4 : 0000001c
[ 0.000000] r3 : 00000000 r2 : 00000000 r1 : ffffffdc r0 : ffffffc0
[ 0.000000] Flags: nzcv IRQs off FIQs off Mode SVC_32 ISA ARM Segment kernel
[ 0.000000] Control: 18c5387d Table: 0000404a DAC: 00000015
[ 0.000000] Process swapper (pid: 0, stack limit = 0xc037c240)
[ 0.000000] Stack: (0xc037df0c to 0xc037e000)
[ 0.000000] df00: c0365cfc ffffffff 00000000 ffffffff 0000001c
[ 0.000000] df20: ffffffff 00000000 00000000 413fc090 c038704c c0365f08 ffffffff c0370368
[ 0.000000] df40: ffff1000 0002e7f5 00001000 00000007 c038dff0 c0370368 c039ebf4 c037dfd4
[ 0.000000] df60: c0370368 c039ebf4 c08ef12c c038704c c038dff0 c035aabc ffffffff 18c5387d
[ 0.000000] df80: ffffffff 0000406a 413fc090 c03843c0 00000000 c025eb74 c02f23a9 c037dfb4
[ 0.000000] dfa0: c0008200 c037c000 00000001 c039e840 ffffffff 0000406a c03843c0 c0357854
[ 0.000000] dfc0: 00000000 00000000 00000000 00000000 00000000 c0372918 18c5387d c0384410
[ 0.000000] dfe0: c0372914 c038717c 0000406a 413fc090 00000000 00008074 00000000 00000000
[ 0.000000] Code: e3110020 18a0500c 18a0500c e3110010 (18a0500c)
[ 0.000000] ---[ end trace 15c15b4afa9eff8e ]---
[ 0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
-------------- next part --------------
#
# Automatically generated file; DO NOT EDIT.
# Linux/arm 3.13.0 Kernel Configuration
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_HAVE_PROC_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_ARM_PATCH_PHYS_VIRT=y
CONFIG_GENERIC_BUG=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_EXTABLE_SORT=y
#
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_CROSS_COMPILE=""
# CONFIG_COMPILE_TEST is not set
CONFIG_LOCALVERSION="-xilinx"
CONFIG_LOCALVERSION_AUTO=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_XZ is not set
# CONFIG_KERNEL_LZO is not set
# CONFIG_KERNEL_LZ4 is not set
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_FHANDLE is not set
#
# IRQ subsystem
#
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_DEBUG=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
CONFIG_KTIME_SCALAR=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_ARCH_HAS_TICK_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
CONFIG_NO_HZ_IDLE=y
# CONFIG_NO_HZ_FULL is not set
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
#
# CPU/Task time and stats accounting
#
CONFIG_TICK_CPU_ACCOUNTING=y
# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
# CONFIG_IRQ_TIME_ACCOUNTING is not set
# CONFIG_BSD_PROCESS_ACCT is not set
#
# RCU Subsystem
#
CONFIG_TREE_PREEMPT_RCU=y
CONFIG_PREEMPT_RCU=y
CONFIG_RCU_STALL_COMMON=y
# CONFIG_RCU_USER_QS is not set
CONFIG_RCU_FANOUT=32
CONFIG_RCU_FANOUT_LEAF=16
# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_RCU_FAST_NO_HZ is not set
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_RCU_BOOST is not set
# CONFIG_RCU_NOCB_CPU is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GENERIC_SCHED_CLOCK=y
# CONFIG_CGROUPS is not set
# CONFIG_CHECKPOINT_RESTORE is not set
# CONFIG_NAMESPACES is not set
# CONFIG_SCHED_AUTOGROUP is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
# CONFIG_RD_LZ4 is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
CONFIG_HAVE_UID16=y
CONFIG_EXPERT=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_EMBEDDED=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_PERF_USE_VMALLOC=y
#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
# CONFIG_JUMP_LABEL is not set
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_HW_BREAKPOINT=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_CC_STACKPROTECTOR=y
CONFIG_CC_STACKPROTECTOR=y
# CONFIG_CC_STACKPROTECTOR_NONE is not set
CONFIG_CC_STACKPROTECTOR_REGULAR=y
# CONFIG_CC_STACKPROTECTOR_STRONG is not set
CONFIG_HAVE_CONTEXT_TRACKING=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_OLD_SIGACTION=y
#
# GCOV-based kernel profiling
#
# CONFIG_GCOV_KERNEL is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
# CONFIG_MODULE_SIG is not set
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_BSGLIB is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
# CONFIG_BLK_CMDLINE_PARSER is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
CONFIG_EFI_PARTITION=y
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_UNINLINE_SPIN_UNLOCK=y
CONFIG_FREEZER=y
#
# System Type
#
CONFIG_MMU=y
CONFIG_ARCH_MULTIPLATFORM=y
# CONFIG_ARCH_INTEGRATOR is not set
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_AT91 is not set
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_GEMINI is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_DOVE is not set
# CONFIG_ARCH_KIRKWOOD is not set
# CONFIG_ARCH_MV78XX0 is not set
# CONFIG_ARCH_ORION5X is not set
# CONFIG_ARCH_MMP is not set
# CONFIG_ARCH_KS8695 is not set
# CONFIG_ARCH_W90X900 is not set
# CONFIG_ARCH_LPC32XX is not set
# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_MSM_NODT is not set
# CONFIG_ARCH_SHMOBILE_LEGACY is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C24XX is not set
# CONFIG_ARCH_S3C64XX is not set
# CONFIG_ARCH_S5P64X0 is not set
# CONFIG_ARCH_S5PC100 is not set
# CONFIG_ARCH_S5PV210 is not set
# CONFIG_ARCH_EXYNOS is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP1 is not set
#
# Multiple platform selection
#
#
# CPU Core family selection
#
# CONFIG_ARCH_MULTI_V6 is not set
CONFIG_ARCH_MULTI_V7=y
CONFIG_ARCH_MULTI_V6_V7=y
# CONFIG_ARCH_MULTI_CPU_AUTO is not set
# CONFIG_ARCH_MVEBU is not set
# CONFIG_ARCH_BCM is not set
# CONFIG_ARCH_BERLIN is not set
# CONFIG_ARCH_HIGHBANK is not set
# CONFIG_ARCH_HI3xxx is not set
# CONFIG_ARCH_KEYSTONE is not set
# CONFIG_ARCH_MSM_DT is not set
# CONFIG_ARCH_MXC is not set
# CONFIG_ARCH_OMAP3 is not set
# CONFIG_ARCH_OMAP4 is not set
# CONFIG_SOC_OMAP5 is not set
# CONFIG_SOC_AM33XX is not set
# CONFIG_SOC_AM43XX is not set
# CONFIG_ARCH_ROCKCHIP is not set
# CONFIG_ARCH_SOCFPGA is not set
# CONFIG_PLAT_SPEAR is not set
# CONFIG_ARCH_STI is not set
# CONFIG_ARCH_SHMOBILE_MULTI is not set
# CONFIG_ARCH_SUNXI is not set
# CONFIG_ARCH_SIRF is not set
# CONFIG_ARCH_TEGRA is not set
# CONFIG_ARCH_U8500 is not set
# CONFIG_ARCH_VEXPRESS is not set
# CONFIG_ARCH_VIRT is not set
# CONFIG_ARCH_WM8850 is not set
CONFIG_ARCH_ZYNQ=y
#
# Processor Type
#
CONFIG_CPU_V7=y
CONFIG_CPU_32v6K=y
CONFIG_CPU_32v7=y
CONFIG_CPU_ABRT_EV7=y
CONFIG_CPU_PABRT_V7=y
CONFIG_CPU_CACHE_V7=y
CONFIG_CPU_CACHE_VIPT=y
CONFIG_CPU_COPY_V6=y
CONFIG_CPU_TLB_V7=y
CONFIG_CPU_HAS_ASID=y
CONFIG_CPU_CP15=y
CONFIG_CPU_CP15_MMU=y
#
# Processor Features
#
# CONFIG_ARM_LPAE is not set
# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
CONFIG_ARM_THUMB=y
# CONFIG_ARM_THUMBEE is not set
CONFIG_ARM_VIRT_EXT=y
CONFIG_SWP_EMULATE=y
# CONFIG_CPU_ICACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_CPU_BPREDICT_DISABLE is not set
CONFIG_KUSER_HELPERS=y
CONFIG_OUTER_CACHE=y
CONFIG_OUTER_CACHE_SYNC=y
CONFIG_MIGHT_HAVE_CACHE_L2X0=y
CONFIG_CACHE_L2X0=y
CONFIG_CACHE_PL310=y
CONFIG_ARM_L1_CACHE_SHIFT_6=y
CONFIG_ARM_L1_CACHE_SHIFT=6
CONFIG_ARM_DMA_MEM_BUFFERABLE=y
CONFIG_ARM_NR_BANKS=8
CONFIG_MULTI_IRQ_HANDLER=y
# CONFIG_ARM_ERRATA_430973 is not set
CONFIG_PL310_ERRATA_588369=y
# CONFIG_ARM_ERRATA_643719 is not set
CONFIG_ARM_ERRATA_720789=y
CONFIG_PL310_ERRATA_727915=y
CONFIG_PL310_ERRATA_753970=y
CONFIG_ARM_ERRATA_754322=y
CONFIG_ARM_ERRATA_754327=y
CONFIG_ARM_ERRATA_764369=y
CONFIG_PL310_ERRATA_769419=y
CONFIG_ARM_ERRATA_775420=y
# CONFIG_ARM_ERRATA_798181 is not set
# CONFIG_ARM_ERRATA_773022 is not set
CONFIG_ICST=y
#
# Bus support
#
CONFIG_ARM_AMBA=y
# CONFIG_PCI_SYSCALL is not set
# CONFIG_PCCARD is not set
#
# Kernel Features
#
CONFIG_HAVE_SMP=y
CONFIG_SMP=y
CONFIG_SMP_ON_UP=y
CONFIG_ARM_CPU_TOPOLOGY=y
CONFIG_SCHED_MC=y
CONFIG_SCHED_SMT=y
CONFIG_HAVE_ARM_SCU=y
# CONFIG_HAVE_ARM_ARCH_TIMER is not set
CONFIG_HAVE_ARM_TWD=y
# CONFIG_MCPM is not set
# CONFIG_BIG_LITTLE is not set
CONFIG_VMSPLIT_3G=y
# CONFIG_VMSPLIT_2G is not set
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_NR_CPUS=4
CONFIG_HOTPLUG_CPU=y
# CONFIG_ARM_PSCI is not set
CONFIG_ARCH_NR_GPIO=0
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_PREEMPT_COUNT=y
CONFIG_HZ_FIXED=0
CONFIG_HZ_100=y
# CONFIG_HZ_200 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
# CONFIG_HZ_500 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
CONFIG_SCHED_HRTICK=y
# CONFIG_THUMB2_KERNEL is not set
CONFIG_AEABI=y
# CONFIG_OABI_COMPAT is not set
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
CONFIG_HAVE_ARCH_PFN_VALID=y
CONFIG_HIGHMEM=y
# CONFIG_HIGHPTE is not set
CONFIG_HW_PERF_EVENTS=y
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_NO_BOOTMEM=y
CONFIG_MEMORY_ISOLATION=y
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_COMPACTION is not set
CONFIG_MIGRATION=y
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_BOUNCE=y
# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_CROSS_MEMORY_ATTACH=y
# CONFIG_CLEANCACHE is not set
# CONFIG_FRONTSWAP is not set
CONFIG_CMA=y
# CONFIG_CMA_DEBUG is not set
# CONFIG_ZBUD is not set
CONFIG_FORCE_MAX_ZONEORDER=11
CONFIG_ALIGNMENT_TRAP=y
# CONFIG_UACCESS_WITH_MEMCPY is not set
# CONFIG_SECCOMP is not set
CONFIG_SWIOTLB=y
CONFIG_IOMMU_HELPER=y
# CONFIG_XEN is not set
#
# Boot options
#
CONFIG_USE_OF=y
CONFIG_ATAGS=y
# CONFIG_DEPRECATED_PARAM_STRUCT is not set
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
# CONFIG_ARM_APPENDED_DTB is not set
CONFIG_CMDLINE="console=ttyPS0,115200n8 root=/dev/ram rw initrd=0x00800000,16M earlyprintk mtdparts=physmap-flash.0:512K(nor-fsbl),512K(nor-u-boot),5M(nor-linux),9M(nor-user),1M(nor-scratch),-(nor-rootfs)"
CONFIG_CMDLINE_FROM_BOOTLOADER=y
# CONFIG_CMDLINE_EXTEND is not set
# CONFIG_CMDLINE_FORCE is not set
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_AUTO_ZRELADDR=y
#
# CPU Power Management
#
#
# CPU Idle
#
# CONFIG_CPU_IDLE is not set
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
#
# Floating point emulation
#
#
# At least one emulation must be selected
#
CONFIG_VFP=y
CONFIG_VFPv3=y
CONFIG_NEON=y
CONFIG_KERNEL_MODE_NEON=y
#
# Userspace binary formats
#
CONFIG_BINFMT_ELF=y
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_SCRIPT=y
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
CONFIG_COREDUMP=y
#
# Power management options
#
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_PM_SLEEP=y
CONFIG_PM_SLEEP_SMP=y
# CONFIG_PM_AUTOSLEEP is not set
# CONFIG_PM_WAKELOCKS is not set
CONFIG_PM_RUNTIME=y
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
# CONFIG_APM_EMULATION is not set
CONFIG_PM_CLK=y
# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
CONFIG_CPU_PM=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARM_CPU_SUSPEND=y
# CONFIG_NET is not set
CONFIG_HAVE_BPF_JIT=y
#
# Device Drivers
#
#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
CONFIG_FW_LOADER_USER_HELPER=y
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_GENERIC_CPU_DEVICES is not set
# CONFIG_DMA_SHARED_BUFFER is not set
CONFIG_DMA_CMA=y
#
# Default contiguous memory area size:
#
CONFIG_CMA_SIZE_MBYTES=16
CONFIG_CMA_SIZE_SEL_MBYTES=y
# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
# CONFIG_CMA_SIZE_SEL_MIN is not set
# CONFIG_CMA_SIZE_SEL_MAX is not set
CONFIG_CMA_ALIGNMENT=8
CONFIG_CMA_AREAS=7
#
# Bus devices
#
# CONFIG_ARM_CCI is not set
# CONFIG_MTD is not set
CONFIG_DTC=y
CONFIG_OF=y
#
# Device Tree and Open Firmware support
#
CONFIG_PROC_DEVICETREE=y
# CONFIG_OF_SELFTEST is not set
CONFIG_OF_FLATTREE=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
# CONFIG_PARPORT is not set
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_NULL_BLK is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
#
# DRBD disabled because PROC_FS or INET not selected
#
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=16384
# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
#
# Misc devices
#
# CONFIG_SENSORS_LIS3LV02D is not set
# CONFIG_ATMEL_PWM is not set
# CONFIG_DUMMY_IRQ is not set
# CONFIG_ATMEL_SSC is not set
# CONFIG_ENCLOSURE_SERVICES is not set
CONFIG_SRAM=y
# CONFIG_C2PORT is not set
#
# EEPROM support
#
# CONFIG_EEPROM_93CX6 is not set
#
# Texas Instruments shared transport line discipline
#
#
# Altera FPGA firmware download module
#
#
# Intel MIC Host Driver
#
#
# Intel MIC Card Driver
#
#
# SCSI device support
#
CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
CONFIG_CHR_DEV_SG=y
# CONFIG_CHR_DEV_SCH is not set
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
# CONFIG_SCSI_SCAN_ASYNC is not set
#
# SCSI Transports
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_BOOT_SYSFS is not set
# CONFIG_SCSI_UFSHCD is not set
# CONFIG_LIBFC is not set
# CONFIG_LIBFCOE is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
# CONFIG_TARGET_CORE is not set
#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
# CONFIG_INPUT_POLLDEV is not set
CONFIG_INPUT_SPARSEKMAP=y
# CONFIG_INPUT_MATRIXKMAP is not set
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_SAMSUNG is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
CONFIG_MOUSE_PS2_ALPS=y
CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_CYPRESS=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
# CONFIG_MOUSE_PS2_ELANTECH is not set
# CONFIG_MOUSE_PS2_SENTELIC is not set
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_AMBAKMI is not set
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
# CONFIG_SERIO_ALTERA_PS2 is not set
# CONFIG_SERIO_PS2MULT is not set
# CONFIG_SERIO_ARC_PS2 is not set
# CONFIG_SERIO_APBPS2 is not set
# CONFIG_SERIO_OLPC_APSP is not set
# CONFIG_GAMEPORT is not set
#
# Character devices
#
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_CONSOLE_SLEEP=y
CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_TRACE_SINK is not set
# CONFIG_DEVKMEM is not set
#
# Serial drivers
#
# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
# CONFIG_SERIAL_AMBA_PL010 is not set
# CONFIG_SERIAL_AMBA_PL011 is not set
# CONFIG_SERIAL_KGDB_NMI is not set
# CONFIG_SERIAL_UARTLITE is not set
# CONFIG_SERIAL_SH_SCI is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_CONSOLE_POLL=y
# CONFIG_SERIAL_SCCNXP is not set
# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not set
CONFIG_SERIAL_XILINX_PS_UART=y
CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
# CONFIG_SERIAL_ARC is not set
# CONFIG_SERIAL_FSL_LPUART is not set
# CONFIG_SERIAL_ST_ASC is not set
# CONFIG_TTY_PRINTK is not set
# CONFIG_HVC_DCC is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
# CONFIG_I2C is not set
# CONFIG_SPI is not set
# CONFIG_HSI is not set
#
# PPS support
#
CONFIG_PPS=y
# CONFIG_PPS_DEBUG is not set
#
# PPS clients support
#
# CONFIG_PPS_CLIENT_KTIMER is not set
# CONFIG_PPS_CLIENT_LDISC is not set
# CONFIG_PPS_CLIENT_GPIO is not set
#
# PPS generators support
#
#
# PTP clock support
#
CONFIG_PTP_1588_CLOCK=y
#
# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
#
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_POWER_AVS is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
# CONFIG_SSB is not set
CONFIG_BCMA_POSSIBLE=y
#
# Broadcom specific AMBA
#
# CONFIG_BCMA is not set
#
# Multifunction device drivers
#
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_CROS_EC is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_KEMPLD is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_ABX500_CORE is not set
# CONFIG_MFD_SYSCON is not set
# CONFIG_MFD_TI_AM335X_TSCADC is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_T7L66XB is not set
# CONFIG_MFD_TC6387XB is not set
# CONFIG_MFD_TC6393XB is not set
# CONFIG_VEXPRESS_CONFIG is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
#
# CONFIG_TEGRA_HOST1X is not set
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
# CONFIG_FB is not set
# CONFIG_EXYNOS_VIDEO is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Console display driver support
#
CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
#
# HID support
#
# CONFIG_HID is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_EDAC is not set
CONFIG_RTC_LIB=y
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_VIRT_DRIVERS is not set
#
# Virtio drivers
#
# CONFIG_VIRTIO_MMIO is not set
#
# Microsoft Hyper-V guest support
#
# CONFIG_STAGING is not set
CONFIG_CLKDEV_LOOKUP=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_COMMON_CLK=y
#
# Common Clock Framework
#
# CONFIG_COMMON_CLK_AXI_CLKGEN is not set
# CONFIG_COMMON_CLK_QCOM is not set
#
# Hardware Spinlock drivers
#
CONFIG_CLKSRC_OF=y
CONFIG_CADENCE_TTC_TIMER=y
CONFIG_ARM_GLOBAL_TIMER=y
CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
# CONFIG_MAILBOX is not set
# CONFIG_IOMMU_SUPPORT is not set
#
# Remoteproc drivers
#
# CONFIG_STE_MODEM_RPROC is not set
#
# Rpmsg drivers
#
# CONFIG_PM_DEVFREQ is not set
# CONFIG_EXTCON is not set
# CONFIG_MEMORY is not set
# CONFIG_IIO is not set
# CONFIG_PWM is not set
CONFIG_IRQCHIP=y
CONFIG_ARM_GIC=y
# CONFIG_IPACK_BUS is not set
# CONFIG_RESET_CONTROLLER is not set
# CONFIG_FMC is not set
#
# PHY Subsystem
#
# CONFIG_GENERIC_PHY is not set
# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set
# CONFIG_PHY_EXYNOS_DP_VIDEO is not set
# CONFIG_POWERCAP is not set
#
# File systems
#
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
CONFIG_EXT4_FS=y
# CONFIG_EXT4_FS_POSIX_ACL is not set
# CONFIG_EXT4_FS_SECURITY is not set
# CONFIG_EXT4_DEBUG is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_JBD2=y
# CONFIG_JBD2_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_BTRFS_FS is not set
# CONFIG_NILFS2_FS is not set
# CONFIG_FS_POSIX_ACL is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
CONFIG_INOTIFY_USER=y
# CONFIG_FANOTIFY is not set
# CONFIG_QUOTA is not set
# CONFIG_QUOTACTL is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
#
# Caches
#
# CONFIG_FSCACHE is not set
#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
# CONFIG_UDF_FS is not set
#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_CONFIGFS_FS=y
CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_LOGFS is not set
# CONFIG_CRAMFS is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_QNX6FS_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_PSTORE is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
# CONFIG_F2FS_FS is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_MAC_ROMAN is not set
# CONFIG_NLS_MAC_CELTIC is not set
# CONFIG_NLS_MAC_CENTEURO is not set
# CONFIG_NLS_MAC_CROATIAN is not set
# CONFIG_NLS_MAC_CYRILLIC is not set
# CONFIG_NLS_MAC_GAELIC is not set
# CONFIG_NLS_MAC_GREEK is not set
# CONFIG_NLS_MAC_ICELAND is not set
# CONFIG_NLS_MAC_INUIT is not set
# CONFIG_NLS_MAC_ROMANIAN is not set
# CONFIG_NLS_MAC_TURKISH is not set
# CONFIG_NLS_UTF8 is not set
#
# Kernel hacking
#
#
# printk and dmesg options
#
CONFIG_PRINTK_TIME=y
CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
# CONFIG_BOOT_PRINTK_DELAY is not set
CONFIG_DYNAMIC_DEBUG=y
#
# Compile-time checks and compiler options
#
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_INFO_REDUCED is not set
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_READABLE_ASM is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_SECTION_MISMATCH=y
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
CONFIG_DEBUG_KERNEL=y
#
# Memory Debugging
#
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
CONFIG_HAVE_DEBUG_KMEMLEAK=y
# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_DEBUG_PER_CPU_MAPS is not set
# CONFIG_DEBUG_HIGHMEM is not set
# CONFIG_DEBUG_SHIRQ is not set
#
# Debug Lockups and Hangs
#
CONFIG_LOCKUP_DETECTOR=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_PANIC_TIMEOUT=0
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
CONFIG_TIMER_STATS=y
# CONFIG_DEBUG_PREEMPT is not set
#
# Lock Debugging (spinlocks, mutexes, etc...)
#
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_PI_LIST=y
# CONFIG_RT_MUTEX_TESTER is not set
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
CONFIG_LOCKDEP=y
# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_LOCKDEP is not set
CONFIG_DEBUG_ATOMIC_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
CONFIG_TRACE_IRQFLAGS=y
CONFIG_STACKTRACE=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_WRITECOUNT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_DEBUG_CREDENTIALS is not set
#
# RCU Debugging
#
CONFIG_PROVE_RCU=y
# CONFIG_PROVE_RCU_REPEATEDLY is not set
# CONFIG_PROVE_RCU_DELAY is not set
# CONFIG_SPARSE_RCU_POINTER is not set
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_RCU_CPU_STALL_TIMEOUT=60
# CONFIG_RCU_CPU_STALL_VERBOSE is not set
# CONFIG_RCU_CPU_STALL_INFO is not set
# CONFIG_RCU_TRACE is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_NOTIFIER_ERROR_INJECTION is not set
# CONFIG_FAULT_INJECTION is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
#
# Runtime Testing
#
# CONFIG_LKDTM is not set
# CONFIG_TEST_LIST_SORT is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_RBTREE_TEST is not set
# CONFIG_INTERVAL_TREE_TEST is not set
# CONFIG_PERCPU_TEST is not set
# CONFIG_ATOMIC64_SELFTEST is not set
# CONFIG_TEST_STRING_HELPERS is not set
# CONFIG_TEST_KSTRTOX is not set
# CONFIG_DMA_API_DEBUG is not set
# CONFIG_TEST_MODULE is not set
# CONFIG_TEST_USER_COPY is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
# CONFIG_KGDB_TESTS is not set
CONFIG_KGDB_KDB=y
# CONFIG_KDB_KEYBOARD is not set
CONFIG_KDB_CONTINUE_CATASTROPHIC=0
CONFIG_ARM_PTDUMP=y
# CONFIG_STRICT_DEVMEM is not set
CONFIG_ARM_UNWIND=y
# CONFIG_DEBUG_USER is not set
CONFIG_DEBUG_LL=y
# CONFIG_DEBUG_ZYNQ_UART0 is not set
CONFIG_DEBUG_ZYNQ_UART1=y
# CONFIG_DEBUG_ICEDCC is not set
# CONFIG_DEBUG_SEMIHOSTING is not set
# CONFIG_DEBUG_LL_UART_8250 is not set
# CONFIG_DEBUG_LL_UART_PL01X is not set
CONFIG_DEBUG_LL_INCLUDE="debug/zynq.S"
# CONFIG_DEBUG_UART_PL01X is not set
# CONFIG_DEBUG_UART_8250 is not set
CONFIG_DEBUG_UNCOMPRESS=y
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_EARLY_PRINTK=y
# CONFIG_OC_ETM is not set
# CONFIG_PID_IN_CONTEXTIDR is not set
# CONFIG_DEBUG_SET_MODULE_RONX is not set
#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY_DMESG_RESTRICT is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_DEFAULT_SECURITY=""
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=m
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP2=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_PCRYPT is not set
CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CRYPTO_CRYPTD=y
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
CONFIG_CRYPTO_ABLK_HELPER=y
#
# Authenticated Encryption with Associated Data
#
# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_GCM is not set
# CONFIG_CRYPTO_SEQIV is not set
#
# Block modes
#
# CONFIG_CRYPTO_CBC is not set
# CONFIG_CRYPTO_CTR is not set
# CONFIG_CRYPTO_CTS is not set
# CONFIG_CRYPTO_ECB is not set
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_PCBC is not set
# CONFIG_CRYPTO_XTS is not set
#
# Hash modes
#
# CONFIG_CRYPTO_CMAC is not set
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
CONFIG_CRYPTO_CRC32C=y
# CONFIG_CRYPTO_CRC32 is not set
# CONFIG_CRYPTO_CRCT10DIF is not set
# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_RMD128 is not set
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not set
# CONFIG_CRYPTO_SHA1 is not set
# CONFIG_CRYPTO_SHA1_ARM is not set
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_WP512 is not set
#
# Ciphers
#
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_AES_ARM=y
CONFIG_CRYPTO_AES_ARM_BS=y
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
# CONFIG_CRYPTO_DES is not set
# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_SEED is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_TWOFISH is not set
#
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
# CONFIG_CRYPTO_LZ4 is not set
# CONFIG_CRYPTO_LZ4HC is not set
#
# Random Number Generation
#
CONFIG_CRYPTO_ANSI_CPRNG=m
CONFIG_CRYPTO_HW=y
# CONFIG_BINARY_PRINTF is not set
#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_IO=y
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
# CONFIG_CRC_CCITT is not set
CONFIG_CRC16=y
# CONFIG_CRC_T10DIF is not set
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
# CONFIG_CRC32_SELFTEST is not set
CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC32_SLICEBY4 is not set
# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_BIT is not set
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
# CONFIG_CRC8 is not set
# CONFIG_RANDOM32_SELFTEST is not set
CONFIG_ZLIB_INFLATE=y
# CONFIG_XZ_DEC is not set
# CONFIG_XZ_DEC_BCJ is not set
CONFIG_DECOMPRESS_GZIP=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
# CONFIG_AVERAGE is not set
# CONFIG_CORDIC is not set
# CONFIG_DDR is not set
# CONFIG_VIRTUALIZATION is not set
^ permalink raw reply
* [PATCH 4/4] mtd: nand: remove the NAND_MAX_PAGESIZE/NAND_MAX_OOBSIZE
From: Brian Norris @ 2014-01-29 0:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1387555350-989-5-git-send-email-shijie8@gmail.com>
On Sat, Dec 21, 2013 at 12:02:30AM +0800, Huang Shijie wrote:
> There is no reference to these two macros now.
> Just remove them.
>
> Signed-off-by: Huang Shijie <shijie8@gmail.com>
Now that patch 3 is fixed, I've pushed this patch as well. Thanks for
cleaning this up!
Brian
^ permalink raw reply
* [PATCH fix] mtd: nand: kill the the NAND_MAX_PAGESIZE/NAND_MAX_OOBSIZE for nand_buffers{}
From: Brian Norris @ 2014-01-29 0:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1389594432-23482-1-git-send-email-b32955@freescale.com>
On Mon, Jan 13, 2014 at 02:27:12PM +0800, Huang Shijie wrote:
> The patch converts the arrays to buffer pointers for nand_buffers{}.
>
> The cafe_nand.c is the only NAND_OWN_BUFFERS user which allocates
> a nand_buffers{} itself.
>
> This patch disables the DMA for nand_scan_ident, and restore the DMA
> status after we finish the nand_scan_ident. By this way, we can get the
> mtd->writesize and mtd->oobsize, and then allocates the cafe->dmabuf
> with them.
>
> Since the cafe_nand.c uses the NAND_ECC_HW_SYNDROME ECC mode, we do not
> allocate the buffers for @ecccalc and @ecccode.
>
> Signed-off-by: Huang Shijie <b32955@freescale.com>
> ---
>
> fix: Setup the DMA address after we have allocated the DMA buffer.
Thanks, looks OK. Pushed to l2-mtd.git/next.
Brian
^ permalink raw reply
* [PATCH v3 6/6] ARM: tegra: remove fuse files from mach-tegra
From: Peter De Schrijver @ 2014-01-28 23:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390952176-30402-1-git-send-email-pdeschrijver@nvidia.com>
All fuse related functionality is now provided by the tegra fuse driver.
Hence all the fuse related files in mach-tegra can be removed.
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
arch/arm/mach-tegra/fuse.c | 252 ----------------------------
arch/arm/mach-tegra/fuse.h | 61 -------
arch/arm/mach-tegra/tegra114_speedo.c | 105 ------------
arch/arm/mach-tegra/tegra20_speedo.c | 110 ------------
arch/arm/mach-tegra/tegra30_speedo.c | 293 ---------------------------------
5 files changed, 0 insertions(+), 821 deletions(-)
delete mode 100644 arch/arm/mach-tegra/fuse.c
delete mode 100644 arch/arm/mach-tegra/fuse.h
delete mode 100644 arch/arm/mach-tegra/tegra114_speedo.c
delete mode 100644 arch/arm/mach-tegra/tegra20_speedo.c
delete mode 100644 arch/arm/mach-tegra/tegra30_speedo.c
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
deleted file mode 100644
index c9ac23b..0000000
--- a/arch/arm/mach-tegra/fuse.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * arch/arm/mach-tegra/fuse.c
- *
- * Copyright (C) 2010 Google, Inc.
- * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
- *
- * Author:
- * Colin Cross <ccross@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/export.h>
-#include <linux/random.h>
-#include <linux/clk.h>
-#include <linux/tegra-soc.h>
-
-#include "fuse.h"
-#include "iomap.h"
-#include "apbio.h"
-
-/* Tegra20 only */
-#define FUSE_UID_LOW 0x108
-#define FUSE_UID_HIGH 0x10c
-
-/* Tegra30 and later */
-#define FUSE_VENDOR_CODE 0x200
-#define FUSE_FAB_CODE 0x204
-#define FUSE_LOT_CODE_0 0x208
-#define FUSE_LOT_CODE_1 0x20c
-#define FUSE_WAFER_ID 0x210
-#define FUSE_X_COORDINATE 0x214
-#define FUSE_Y_COORDINATE 0x218
-
-#define FUSE_SKU_INFO 0x110
-
-#define TEGRA20_FUSE_SPARE_BIT 0x200
-#define TEGRA30_FUSE_SPARE_BIT 0x244
-
-int tegra_sku_id;
-int tegra_cpu_process_id;
-int tegra_core_process_id;
-int tegra_chip_id;
-int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */
-int tegra_soc_speedo_id;
-enum tegra_revision tegra_revision;
-
-static struct clk *fuse_clk;
-static int tegra_fuse_spare_bit;
-static void (*tegra_init_speedo_data)(void);
-
-/* The BCT to use at boot is specified by board straps that can be read
- * through a APB misc register and decoded. 2 bits, i.e. 4 possible BCTs.
- */
-int tegra_bct_strapping;
-
-#define STRAP_OPT 0x008
-#define GMI_AD0 (1 << 4)
-#define GMI_AD1 (1 << 5)
-#define RAM_ID_MASK (GMI_AD0 | GMI_AD1)
-#define RAM_CODE_SHIFT 4
-
-static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
- [TEGRA_REVISION_UNKNOWN] = "unknown",
- [TEGRA_REVISION_A01] = "A01",
- [TEGRA_REVISION_A02] = "A02",
- [TEGRA_REVISION_A03] = "A03",
- [TEGRA_REVISION_A03p] = "A03 prime",
- [TEGRA_REVISION_A04] = "A04",
-};
-
-static void tegra_fuse_enable_clk(void)
-{
- if (IS_ERR(fuse_clk))
- fuse_clk = clk_get_sys(NULL, "fuse");
- if (IS_ERR(fuse_clk))
- return;
- clk_prepare_enable(fuse_clk);
-}
-
-static void tegra_fuse_disable_clk(void)
-{
- if (IS_ERR(fuse_clk))
- return;
- clk_disable_unprepare(fuse_clk);
-}
-
-u32 tegra_fuse_readl(unsigned long offset)
-{
- return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
-}
-
-bool tegra_spare_fuse(int bit)
-{
- bool ret;
-
- tegra_fuse_enable_clk();
-
- ret = tegra_fuse_readl(tegra_fuse_spare_bit + bit * 4);
-
- tegra_fuse_disable_clk();
-
- return ret;
-}
-
-static enum tegra_revision tegra_get_revision(u32 id)
-{
- u32 minor_rev = (id >> 16) & 0xf;
-
- switch (minor_rev) {
- case 1:
- return TEGRA_REVISION_A01;
- case 2:
- return TEGRA_REVISION_A02;
- case 3:
- if (tegra_chip_id == TEGRA20 &&
- (tegra_spare_fuse(18) || tegra_spare_fuse(19)))
- return TEGRA_REVISION_A03p;
- else
- return TEGRA_REVISION_A03;
- case 4:
- return TEGRA_REVISION_A04;
- default:
- return TEGRA_REVISION_UNKNOWN;
- }
-}
-
-static void tegra_get_process_id(void)
-{
- u32 reg;
-
- tegra_fuse_enable_clk();
-
- reg = tegra_fuse_readl(tegra_fuse_spare_bit);
- tegra_cpu_process_id = (reg >> 6) & 3;
- reg = tegra_fuse_readl(tegra_fuse_spare_bit);
- tegra_core_process_id = (reg >> 12) & 3;
-
- tegra_fuse_disable_clk();
-}
-
-u32 tegra_read_chipid(void)
-{
- return readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804);
-}
-
-static void __init tegra20_fuse_init_randomness(void)
-{
- u32 randomness[2];
-
- randomness[0] = tegra_fuse_readl(FUSE_UID_LOW);
- randomness[1] = tegra_fuse_readl(FUSE_UID_HIGH);
-
- add_device_randomness(randomness, sizeof(randomness));
-}
-
-/* Applies to Tegra30 or later */
-static void __init tegra30_fuse_init_randomness(void)
-{
- u32 randomness[7];
-
- randomness[0] = tegra_fuse_readl(FUSE_VENDOR_CODE);
- randomness[1] = tegra_fuse_readl(FUSE_FAB_CODE);
- randomness[2] = tegra_fuse_readl(FUSE_LOT_CODE_0);
- randomness[3] = tegra_fuse_readl(FUSE_LOT_CODE_1);
- randomness[4] = tegra_fuse_readl(FUSE_WAFER_ID);
- randomness[5] = tegra_fuse_readl(FUSE_X_COORDINATE);
- randomness[6] = tegra_fuse_readl(FUSE_Y_COORDINATE);
-
- add_device_randomness(randomness, sizeof(randomness));
-}
-
-void __init tegra_init_fuse(void)
-{
- u32 id;
- u32 randomness[5];
-
- u32 reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));
- reg |= 1 << 28;
- writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));
-
- /*
- * Enable FUSE clock. This needs to be hardcoded because the clock
- * subsystem is not active during early boot.
- */
- reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x14));
- reg |= 1 << 7;
- writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x14));
- fuse_clk = ERR_PTR(-EINVAL);
-
- reg = tegra_fuse_readl(FUSE_SKU_INFO);
- randomness[0] = reg;
- tegra_sku_id = reg & 0xFF;
-
- reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);
- randomness[1] = reg;
- tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
-
- id = tegra_read_chipid();
- randomness[2] = id;
- tegra_chip_id = (id >> 8) & 0xff;
-
- switch (tegra_chip_id) {
- case TEGRA20:
- tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
- tegra_init_speedo_data = &tegra20_init_speedo_data;
- break;
- case TEGRA30:
- tegra_fuse_spare_bit = TEGRA30_FUSE_SPARE_BIT;
- tegra_init_speedo_data = &tegra30_init_speedo_data;
- break;
- case TEGRA114:
- tegra_init_speedo_data = &tegra114_init_speedo_data;
- break;
- default:
- pr_warn("Tegra: unknown chip id %d\n", tegra_chip_id);
- tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
- tegra_init_speedo_data = &tegra_get_process_id;
- }
-
- tegra_revision = tegra_get_revision(id);
- tegra_init_speedo_data();
- randomness[3] = (tegra_cpu_process_id << 16) | tegra_core_process_id;
- randomness[4] = (tegra_cpu_speedo_id << 16) | tegra_soc_speedo_id;
-
- add_device_randomness(randomness, sizeof(randomness));
- switch (tegra_chip_id) {
- case TEGRA20:
- tegra20_fuse_init_randomness();
- break;
- case TEGRA30:
- case TEGRA114:
- default:
- tegra30_fuse_init_randomness();
- break;
- }
-
- pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
- tegra_revision_name[tegra_revision],
- tegra_sku_id, tegra_cpu_process_id,
- tegra_core_process_id);
-}
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
deleted file mode 100644
index b17c4ba..0000000
--- a/arch/arm/mach-tegra/fuse.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2010 Google, Inc.
- * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
- *
- * Author:
- * Colin Cross <ccross@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef __MACH_TEGRA_FUSE_H
-#define __MACH_TEGRA_FUSE_H
-
-#define SKU_ID_T20 8
-#define SKU_ID_T25SE 20
-#define SKU_ID_AP25 23
-#define SKU_ID_T25 24
-#define SKU_ID_AP25E 27
-#define SKU_ID_T25E 28
-
-#ifndef __ASSEMBLY__
-
-extern int tegra_sku_id;
-extern int tegra_cpu_process_id;
-extern int tegra_core_process_id;
-extern int tegra_chip_id;
-extern int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */
-extern int tegra_soc_speedo_id;
-
-unsigned long long tegra_chip_uid(void);
-bool tegra_spare_fuse(int bit);
-u32 tegra_fuse_readl(unsigned long offset);
-
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-void tegra20_init_speedo_data(void);
-#else
-static inline void tegra20_init_speedo_data(void) {}
-#endif
-
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
-void tegra30_init_speedo_data(void);
-#else
-static inline void tegra30_init_speedo_data(void) {}
-#endif
-
-#ifdef CONFIG_ARCH_TEGRA_114_SOC
-void tegra114_init_speedo_data(void);
-#else
-static inline void tegra114_init_speedo_data(void) {}
-#endif
-#endif /* __ASSEMBLY__ */
-
-#endif
diff --git a/arch/arm/mach-tegra/tegra114_speedo.c b/arch/arm/mach-tegra/tegra114_speedo.c
deleted file mode 100644
index 7c73716..0000000
--- a/arch/arm/mach-tegra/tegra114_speedo.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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/kernel.h>
-#include <linux/bug.h>
-#include <linux/tegra-soc.h>
-
-#include "fuse.h"
-
-#define CORE_PROCESS_CORNERS_NUM 2
-#define CPU_PROCESS_CORNERS_NUM 2
-
-enum {
- THRESHOLD_INDEX_0,
- THRESHOLD_INDEX_1,
- THRESHOLD_INDEX_COUNT,
-};
-
-static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
- {1123, UINT_MAX},
- {0, UINT_MAX},
-};
-
-static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
- {1695, UINT_MAX},
- {0, UINT_MAX},
-};
-
-static void rev_sku_to_speedo_ids(int rev, int sku, int *threshold)
-{
- u32 tmp;
-
- switch (sku) {
- case 0x00:
- case 0x10:
- case 0x05:
- case 0x06:
- tegra_cpu_speedo_id = 1;
- tegra_soc_speedo_id = 0;
- *threshold = THRESHOLD_INDEX_0;
- break;
-
- case 0x03:
- case 0x04:
- tegra_cpu_speedo_id = 2;
- tegra_soc_speedo_id = 1;
- *threshold = THRESHOLD_INDEX_1;
- break;
-
- default:
- pr_err("Tegra114 Unknown SKU %d\n", sku);
- tegra_cpu_speedo_id = 0;
- tegra_soc_speedo_id = 0;
- *threshold = THRESHOLD_INDEX_0;
- break;
- }
-
- if (rev == TEGRA_REVISION_A01) {
- tmp = tegra_fuse_readl(0x270) << 1;
- tmp |= tegra_fuse_readl(0x26c);
- if (!tmp)
- tegra_cpu_speedo_id = 0;
- }
-}
-
-void tegra114_init_speedo_data(void)
-{
- u32 cpu_speedo_val;
- u32 core_speedo_val;
- int threshold;
- int i;
-
- BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
- THRESHOLD_INDEX_COUNT);
- BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
- THRESHOLD_INDEX_COUNT);
-
- rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id, &threshold);
-
- cpu_speedo_val = tegra_fuse_readl(0x12c) + 1024;
- core_speedo_val = tegra_fuse_readl(0x134);
-
- for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++)
- if (cpu_speedo_val < cpu_process_speedos[threshold][i])
- break;
- tegra_cpu_process_id = i;
-
- for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++)
- if (core_speedo_val < core_process_speedos[threshold][i])
- break;
- tegra_core_process_id = i;
-}
diff --git a/arch/arm/mach-tegra/tegra20_speedo.c b/arch/arm/mach-tegra/tegra20_speedo.c
deleted file mode 100644
index 3b1bb53..0000000
--- a/arch/arm/mach-tegra/tegra20_speedo.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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/kernel.h>
-#include <linux/bug.h>
-#include <linux/tegra-soc.h>
-
-#include "fuse.h"
-
-#define CPU_SPEEDO_LSBIT 20
-#define CPU_SPEEDO_MSBIT 29
-#define CPU_SPEEDO_REDUND_LSBIT 30
-#define CPU_SPEEDO_REDUND_MSBIT 39
-#define CPU_SPEEDO_REDUND_OFFS (CPU_SPEEDO_REDUND_MSBIT - CPU_SPEEDO_MSBIT)
-
-#define CORE_SPEEDO_LSBIT 40
-#define CORE_SPEEDO_MSBIT 47
-#define CORE_SPEEDO_REDUND_LSBIT 48
-#define CORE_SPEEDO_REDUND_MSBIT 55
-#define CORE_SPEEDO_REDUND_OFFS (CORE_SPEEDO_REDUND_MSBIT - CORE_SPEEDO_MSBIT)
-
-#define SPEEDO_MULT 4
-
-#define PROCESS_CORNERS_NUM 4
-
-#define SPEEDO_ID_SELECT_0(rev) ((rev) <= 2)
-#define SPEEDO_ID_SELECT_1(sku) \
- (((sku) != 20) && ((sku) != 23) && ((sku) != 24) && \
- ((sku) != 27) && ((sku) != 28))
-
-enum {
- SPEEDO_ID_0,
- SPEEDO_ID_1,
- SPEEDO_ID_2,
- SPEEDO_ID_COUNT,
-};
-
-static const u32 cpu_process_speedos[][PROCESS_CORNERS_NUM] = {
- {315, 366, 420, UINT_MAX},
- {303, 368, 419, UINT_MAX},
- {316, 331, 383, UINT_MAX},
-};
-
-static const u32 core_process_speedos[][PROCESS_CORNERS_NUM] = {
- {165, 195, 224, UINT_MAX},
- {165, 195, 224, UINT_MAX},
- {165, 195, 224, UINT_MAX},
-};
-
-void tegra20_init_speedo_data(void)
-{
- u32 reg;
- u32 val;
- int i;
-
- BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) != SPEEDO_ID_COUNT);
- BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) != SPEEDO_ID_COUNT);
-
- if (SPEEDO_ID_SELECT_0(tegra_revision))
- tegra_soc_speedo_id = SPEEDO_ID_0;
- else if (SPEEDO_ID_SELECT_1(tegra_sku_id))
- tegra_soc_speedo_id = SPEEDO_ID_1;
- else
- tegra_soc_speedo_id = SPEEDO_ID_2;
-
- val = 0;
- for (i = CPU_SPEEDO_MSBIT; i >= CPU_SPEEDO_LSBIT; i--) {
- reg = tegra_spare_fuse(i) |
- tegra_spare_fuse(i + CPU_SPEEDO_REDUND_OFFS);
- val = (val << 1) | (reg & 0x1);
- }
- val = val * SPEEDO_MULT;
- pr_debug("%s CPU speedo value %u\n", __func__, val);
-
- for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
- if (val <= cpu_process_speedos[tegra_soc_speedo_id][i])
- break;
- }
- tegra_cpu_process_id = i;
-
- val = 0;
- for (i = CORE_SPEEDO_MSBIT; i >= CORE_SPEEDO_LSBIT; i--) {
- reg = tegra_spare_fuse(i) |
- tegra_spare_fuse(i + CORE_SPEEDO_REDUND_OFFS);
- val = (val << 1) | (reg & 0x1);
- }
- val = val * SPEEDO_MULT;
- pr_debug("%s Core speedo value %u\n", __func__, val);
-
- for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
- if (val <= core_process_speedos[tegra_soc_speedo_id][i])
- break;
- }
- tegra_core_process_id = i;
-
- pr_info("Tegra20 Soc Speedo ID %d", tegra_soc_speedo_id);
-}
diff --git a/arch/arm/mach-tegra/tegra30_speedo.c b/arch/arm/mach-tegra/tegra30_speedo.c
deleted file mode 100644
index 81a958d..0000000
--- a/arch/arm/mach-tegra/tegra30_speedo.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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/kernel.h>
-#include <linux/bug.h>
-#include <linux/tegra-soc.h>
-
-#include "fuse.h"
-
-#define CORE_PROCESS_CORNERS_NUM 1
-#define CPU_PROCESS_CORNERS_NUM 6
-
-#define FUSE_SPEEDO_CALIB_0 0x114
-#define FUSE_PACKAGE_INFO 0X1FC
-#define FUSE_TEST_PROG_VER 0X128
-
-#define G_SPEEDO_BIT_MINUS1 58
-#define G_SPEEDO_BIT_MINUS1_R 59
-#define G_SPEEDO_BIT_MINUS2 60
-#define G_SPEEDO_BIT_MINUS2_R 61
-#define LP_SPEEDO_BIT_MINUS1 62
-#define LP_SPEEDO_BIT_MINUS1_R 63
-#define LP_SPEEDO_BIT_MINUS2 64
-#define LP_SPEEDO_BIT_MINUS2_R 65
-
-enum {
- THRESHOLD_INDEX_0,
- THRESHOLD_INDEX_1,
- THRESHOLD_INDEX_2,
- THRESHOLD_INDEX_3,
- THRESHOLD_INDEX_4,
- THRESHOLD_INDEX_5,
- THRESHOLD_INDEX_6,
- THRESHOLD_INDEX_7,
- THRESHOLD_INDEX_8,
- THRESHOLD_INDEX_9,
- THRESHOLD_INDEX_10,
- THRESHOLD_INDEX_11,
- THRESHOLD_INDEX_COUNT,
-};
-
-static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
- {180},
- {170},
- {195},
- {180},
- {168},
- {192},
- {180},
- {170},
- {195},
- {180},
- {180},
- {180},
-};
-
-static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
- {306, 338, 360, 376, UINT_MAX},
- {295, 336, 358, 375, UINT_MAX},
- {325, 325, 358, 375, UINT_MAX},
- {325, 325, 358, 375, UINT_MAX},
- {292, 324, 348, 364, UINT_MAX},
- {324, 324, 348, 364, UINT_MAX},
- {324, 324, 348, 364, UINT_MAX},
- {295, 336, 358, 375, UINT_MAX},
- {358, 358, 358, 358, 397, UINT_MAX},
- {364, 364, 364, 364, 397, UINT_MAX},
- {295, 336, 358, 375, 391, UINT_MAX},
- {295, 336, 358, 375, 391, UINT_MAX},
-};
-
-static int threshold_index;
-static int package_id;
-
-static void fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
-{
- u32 reg;
- int ate_ver;
- int bit_minus1;
- int bit_minus2;
-
- reg = tegra_fuse_readl(FUSE_SPEEDO_CALIB_0);
-
- *speedo_lp = (reg & 0xFFFF) * 4;
- *speedo_g = ((reg >> 16) & 0xFFFF) * 4;
-
- ate_ver = tegra_fuse_readl(FUSE_TEST_PROG_VER);
- pr_info("%s: ATE prog ver %d.%d\n", __func__, ate_ver/10, ate_ver%10);
-
- if (ate_ver >= 26) {
- bit_minus1 = tegra_spare_fuse(LP_SPEEDO_BIT_MINUS1);
- bit_minus1 |= tegra_spare_fuse(LP_SPEEDO_BIT_MINUS1_R);
- bit_minus2 = tegra_spare_fuse(LP_SPEEDO_BIT_MINUS2);
- bit_minus2 |= tegra_spare_fuse(LP_SPEEDO_BIT_MINUS2_R);
- *speedo_lp |= (bit_minus1 << 1) | bit_minus2;
-
- bit_minus1 = tegra_spare_fuse(G_SPEEDO_BIT_MINUS1);
- bit_minus1 |= tegra_spare_fuse(G_SPEEDO_BIT_MINUS1_R);
- bit_minus2 = tegra_spare_fuse(G_SPEEDO_BIT_MINUS2);
- bit_minus2 |= tegra_spare_fuse(G_SPEEDO_BIT_MINUS2_R);
- *speedo_g |= (bit_minus1 << 1) | bit_minus2;
- } else {
- *speedo_lp |= 0x3;
- *speedo_g |= 0x3;
- }
-}
-
-static void rev_sku_to_speedo_ids(int rev, int sku)
-{
- switch (rev) {
- case TEGRA_REVISION_A01:
- tegra_cpu_speedo_id = 0;
- tegra_soc_speedo_id = 0;
- threshold_index = THRESHOLD_INDEX_0;
- break;
- case TEGRA_REVISION_A02:
- case TEGRA_REVISION_A03:
- switch (sku) {
- case 0x87:
- case 0x82:
- tegra_cpu_speedo_id = 1;
- tegra_soc_speedo_id = 1;
- threshold_index = THRESHOLD_INDEX_1;
- break;
- case 0x81:
- switch (package_id) {
- case 1:
- tegra_cpu_speedo_id = 2;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_2;
- break;
- case 2:
- tegra_cpu_speedo_id = 4;
- tegra_soc_speedo_id = 1;
- threshold_index = THRESHOLD_INDEX_7;
- break;
- default:
- pr_err("Tegra30: Unknown pkg %d\n", package_id);
- BUG();
- break;
- }
- break;
- case 0x80:
- switch (package_id) {
- case 1:
- tegra_cpu_speedo_id = 5;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_8;
- break;
- case 2:
- tegra_cpu_speedo_id = 6;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_9;
- break;
- default:
- pr_err("Tegra30: Unknown pkg %d\n", package_id);
- BUG();
- break;
- }
- break;
- case 0x83:
- switch (package_id) {
- case 1:
- tegra_cpu_speedo_id = 7;
- tegra_soc_speedo_id = 1;
- threshold_index = THRESHOLD_INDEX_10;
- break;
- case 2:
- tegra_cpu_speedo_id = 3;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_3;
- break;
- default:
- pr_err("Tegra30: Unknown pkg %d\n", package_id);
- BUG();
- break;
- }
- break;
- case 0x8F:
- tegra_cpu_speedo_id = 8;
- tegra_soc_speedo_id = 1;
- threshold_index = THRESHOLD_INDEX_11;
- break;
- case 0x08:
- tegra_cpu_speedo_id = 1;
- tegra_soc_speedo_id = 1;
- threshold_index = THRESHOLD_INDEX_4;
- break;
- case 0x02:
- tegra_cpu_speedo_id = 2;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_5;
- break;
- case 0x04:
- tegra_cpu_speedo_id = 3;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_6;
- break;
- case 0:
- switch (package_id) {
- case 1:
- tegra_cpu_speedo_id = 2;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_2;
- break;
- case 2:
- tegra_cpu_speedo_id = 3;
- tegra_soc_speedo_id = 2;
- threshold_index = THRESHOLD_INDEX_3;
- break;
- default:
- pr_err("Tegra30: Unknown pkg %d\n", package_id);
- BUG();
- break;
- }
- break;
- default:
- pr_warn("Tegra30: Unknown SKU %d\n", sku);
- tegra_cpu_speedo_id = 0;
- tegra_soc_speedo_id = 0;
- threshold_index = THRESHOLD_INDEX_0;
- break;
- }
- break;
- default:
- pr_warn("Tegra30: Unknown chip rev %d\n", rev);
- tegra_cpu_speedo_id = 0;
- tegra_soc_speedo_id = 0;
- threshold_index = THRESHOLD_INDEX_0;
- break;
- }
-}
-
-void tegra30_init_speedo_data(void)
-{
- u32 cpu_speedo_val;
- u32 core_speedo_val;
- int i;
-
- BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
- THRESHOLD_INDEX_COUNT);
- BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
- THRESHOLD_INDEX_COUNT);
-
- package_id = tegra_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F;
-
- rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id);
- fuse_speedo_calib(&cpu_speedo_val, &core_speedo_val);
- pr_debug("%s CPU speedo value %u\n", __func__, cpu_speedo_val);
- pr_debug("%s Core speedo value %u\n", __func__, core_speedo_val);
-
- for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) {
- if (cpu_speedo_val < cpu_process_speedos[threshold_index][i])
- break;
- }
- tegra_cpu_process_id = i - 1;
-
- if (tegra_cpu_process_id == -1) {
- pr_warn("Tegra30: CPU speedo value %3d out of range",
- cpu_speedo_val);
- tegra_cpu_process_id = 0;
- tegra_cpu_speedo_id = 1;
- }
-
- for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++) {
- if (core_speedo_val < core_process_speedos[threshold_index][i])
- break;
- }
- tegra_core_process_id = i - 1;
-
- if (tegra_core_process_id == -1) {
- pr_warn("Tegra30: CORE speedo value %3d out of range",
- core_speedo_val);
- tegra_core_process_id = 0;
- tegra_soc_speedo_id = 1;
- }
-
- pr_info("Tegra30: CPU Speedo ID %d, Soc Speedo ID %d",
- tegra_cpu_speedo_id, tegra_soc_speedo_id);
-}
--
1.7.7.rc0.72.g4b5ea.dirty
^ permalink raw reply related
* [PATCH v3 5/6] misc: enable fuse drivers
From: Peter De Schrijver @ 2014-01-28 23:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390952176-30402-1-git-send-email-pdeschrijver@nvidia.com>
Enable building the fuse drivers.
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
arch/arm/mach-tegra/Makefile | 4 ----
drivers/misc/Makefile | 1 +
2 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 019bb17..92f8ab2 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -2,7 +2,6 @@ asflags-y += -march=armv7-a
obj-y += io.o
obj-y += irq.o
-obj-y += fuse.o
obj-y += pmc.o
obj-y += flowctrl.o
obj-y += powergate.o
@@ -13,14 +12,12 @@ obj-y += reset-handler.o
obj-y += sleep.o
obj-y += tegra.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
-obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o
ifeq ($(CONFIG_CPU_IDLE),y)
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o
endif
-obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pm-tegra30.o
ifeq ($(CONFIG_CPU_IDLE),y)
@@ -29,7 +26,6 @@ endif
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
-obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o
ifeq ($(CONFIG_CPU_IDLE),y)
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 99b9424..e243a8b 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -54,3 +54,4 @@ obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
obj-$(CONFIG_SRAM) += sram.o
obj-y += mic/
obj-$(CONFIG_GENWQE) += genwqe/
+obj-y += fuse/
--
1.7.7.rc0.72.g4b5ea.dirty
^ permalink raw reply related
* [PATCH v3 4/6] ARM: tegra: Add efuse bindings
From: Peter De Schrijver @ 2014-01-28 23:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390952176-30402-1-git-send-email-pdeschrijver@nvidia.com>
Add efuse bindings for Tegra20, Tegra30, Tegra114 and Tegra124.
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
.../devicetree/bindings/fuse/fuse-tegra.txt | 32 ++++++++++++++++++++
arch/arm/boot/dts/tegra114.dtsi | 7 ++++
arch/arm/boot/dts/tegra124.dtsi | 7 ++++
arch/arm/boot/dts/tegra20.dtsi | 7 ++++
arch/arm/boot/dts/tegra30.dtsi | 7 ++++
5 files changed, 60 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/fuse/fuse-tegra.txt
diff --git a/Documentation/devicetree/bindings/fuse/fuse-tegra.txt b/Documentation/devicetree/bindings/fuse/fuse-tegra.txt
new file mode 100644
index 0000000..8a566a1
--- /dev/null
+++ b/Documentation/devicetree/bindings/fuse/fuse-tegra.txt
@@ -0,0 +1,32 @@
+NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 fuse driver.
+
+Required properties:
+- compatible : should be:
+ "nvidia,tegra20-efuse"
+ "nvidia,tegra30-efuse"
+ "nvidia,tegra114-efuse"
+ "nvidia,tegra124-efuse"
+ Details:
+ nvidia,tegra20-efuse: Tegra20 requires using APB DMA to read the fuse data
+ due to a hardware bug. Tegra20 also lacks certain information which is
+ available in later generations such as fab code, lot code, wafer id,..
+ nvidia,tegra30-efuse, nvidia,tegra114-efuse and nvidia,tegra124-efuse:
+ The differences between these SoCs are the size of the efuse array,
+ the location of the spare (OEM programmable) bits and the location of
+ the speedo data.
+- reg: Should contain 2 entries: the first entry gives the physical address
+ and length of the fuse registers, the second entry gives the physical
+ address and length of the apbmisc registers. These are used to provide
+ the chipid, chip revision and strapping options.
+- clocks: Should contain a pointer to the fuse clock.
+
+Example:
+
+ fuse at 7000f800 {
+ compatible = "nvidia,tegra20-efuse";
+ reg = <0x7000F800 0x400>,
+ <0x70000000 0x400>;
+ clocks = <&tegra_car TEGRA20_CLK_FUSE>;
+ };
+
+
diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi
index 389e987..05ca90b 100644
--- a/arch/arm/boot/dts/tegra114.dtsi
+++ b/arch/arm/boot/dts/tegra114.dtsi
@@ -481,6 +481,13 @@
clock-names = "pclk", "clk32k_in";
};
+ fuse at 7000f800 {
+ compatible = "nvidia,tegra114-efuse";
+ reg = <0x7000f800 0x400>,
+ <0x70000000 0x400>;
+ clocks = <&tegra_car TEGRA114_CLK_FUSE>;
+ };
+
iommu at 70019010 {
compatible = "nvidia,tegra114-smmu", "nvidia,tegra30-smmu";
reg = <0x70019010 0x02c
diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
index ec0698a..30faa73 100644
--- a/arch/arm/boot/dts/tegra124.dtsi
+++ b/arch/arm/boot/dts/tegra124.dtsi
@@ -381,6 +381,13 @@
clock-names = "pclk", "clk32k_in";
};
+ fuse@7000f800 {
+ compatible = "nvidia,tegra124-efuse";
+ reg = <0x7000f800 0x400>,
+ <0x70000000 0x400>;
+ clocks = <&tegra_car TEGRA124_CLK_FUSE>;
+ };
+
sdhci at 700b0000 {
compatible = "nvidia,tegra124-sdhci";
reg = <0x700b0000 0x200>;
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 480ecda..a1a15d7 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -541,6 +541,13 @@
#size-cells = <0>;
};
+ fuse at 7000f800 {
+ compatible = "nvidia,tegra20-efuse";
+ reg = <0x7000F800 0x400>,
+ <0x70000000 0x400>;
+ clocks = <&tegra_car TEGRA20_CLK_FUSE>;
+ };
+
pcie-controller at 80003000 {
compatible = "nvidia,tegra20-pcie";
device_type = "pci";
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index ed8e770..1ec80fa 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -623,6 +623,13 @@
nvidia,ahb = <&ahb>;
};
+ fuse at 7000f800 {
+ compatible = "nvidia,tegra30-efuse";
+ reg = <0x7000f800 0x400>,
+ <0x70000000 0x400>;
+ clocks = <&tegra_car TEGRA30_CLK_FUSE>;
+ };
+
ahub at 70080000 {
compatible = "nvidia,tegra30-ahub";
reg = <0x70080000 0x200
--
1.7.7.rc0.72.g4b5ea.dirty
^ permalink raw reply related
* [PATCH v3 3/6] misc: fuse: Add efuse driver for Tegra
From: Peter De Schrijver @ 2014-01-28 23:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390952176-30402-1-git-send-email-pdeschrijver@nvidia.com>
Implement fuse driver for Tegra20, Tegra30, Tegra114 and Tegra124.
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
Documentation/ABI/testing/sysfs-driver-tegra-fuse | 8 +
drivers/misc/fuse/Makefile | 1 +
drivers/misc/fuse/tegra/Makefile | 7 +
drivers/misc/fuse/tegra/fuse-tegra.c | 228 ++++++++++++++++
drivers/misc/fuse/tegra/fuse-tegra20.c | 136 ++++++++++
drivers/misc/fuse/tegra/fuse-tegra30.c | 178 +++++++++++++
drivers/misc/fuse/tegra/fuse.h | 82 ++++++
drivers/misc/fuse/tegra/tegra114_speedo.c | 110 ++++++++
drivers/misc/fuse/tegra/tegra124_speedo.c | 164 ++++++++++++
drivers/misc/fuse/tegra/tegra20_speedo.c | 110 ++++++++
drivers/misc/fuse/tegra/tegra30_speedo.c | 294 +++++++++++++++++++++
11 files changed, 1318 insertions(+), 0 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-driver-tegra-fuse
create mode 100644 drivers/misc/fuse/Makefile
create mode 100644 drivers/misc/fuse/tegra/Makefile
create mode 100644 drivers/misc/fuse/tegra/fuse-tegra.c
create mode 100644 drivers/misc/fuse/tegra/fuse-tegra20.c
create mode 100644 drivers/misc/fuse/tegra/fuse-tegra30.c
create mode 100644 drivers/misc/fuse/tegra/fuse.h
create mode 100644 drivers/misc/fuse/tegra/tegra114_speedo.c
create mode 100644 drivers/misc/fuse/tegra/tegra124_speedo.c
create mode 100644 drivers/misc/fuse/tegra/tegra20_speedo.c
create mode 100644 drivers/misc/fuse/tegra/tegra30_speedo.c
diff --git a/Documentation/ABI/testing/sysfs-driver-tegra-fuse b/Documentation/ABI/testing/sysfs-driver-tegra-fuse
new file mode 100644
index 0000000..3b5e1ea
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-tegra-fuse
@@ -0,0 +1,8 @@
+What: /sys/devices/*/<our-device>/fuse
+Date: December 2013
+Contact: Peter De Schrijver <pdeschrijver@nvidia.com>
+Description: read-only access to the efuses on Tegra20, Tegra30, Tegra114
+ and Tegra124 SoC's from NVIDIA. The efuses contain write once
+ data programmed at the factory.
+Users: any user space application which wants to read the efuses on
+ Tegra SoC's
diff --git a/drivers/misc/fuse/Makefile b/drivers/misc/fuse/Makefile
new file mode 100644
index 0000000..0679c4f
--- /dev/null
+++ b/drivers/misc/fuse/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_TEGRA) += tegra/
diff --git a/drivers/misc/fuse/tegra/Makefile b/drivers/misc/fuse/tegra/Makefile
new file mode 100644
index 0000000..42829b3
--- /dev/null
+++ b/drivers/misc/fuse/tegra/Makefile
@@ -0,0 +1,7 @@
+obj-y += fuse-tegra.o
+obj-y += fuse-tegra30.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += fuse-tegra20.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o
+obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o
+obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o
+obj-$(CONFIG_ARCH_TEGRA_124_SOC) += tegra124_speedo.o
diff --git a/drivers/misc/fuse/tegra/fuse-tegra.c b/drivers/misc/fuse/tegra/fuse-tegra.c
new file mode 100644
index 0000000..aeecbcd
--- /dev/null
+++ b/drivers/misc/fuse/tegra/fuse-tegra.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/device.h>
+#include <linux/kobject.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/tegra-soc.h>
+
+#include "fuse.h"
+
+int tegra_chip_id;
+enum tegra_revision tegra_revision;
+
+/*
+ * The BCT to use at boot is specified by board straps that can be read
+ * through a APB misc register and decoded. 2 bits, i.e. 4 possible BCTs.
+ */
+int tegra_bct_strapping;
+
+#define TEGRA_STRAP_OPT 0x8
+#define TEGRA_RAM_ID_SHIFT 4
+#define TEGRA_RAM_ID_MASK 3
+
+static u32 (*fuse_readl)(const unsigned int offset);
+static int fuse_size;
+static void __iomem *fuse_base;
+static void __iomem *apbmisc_base;
+static void __iomem *car_base;
+
+static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
+ [TEGRA_REVISION_UNKNOWN] = "unknown",
+ [TEGRA_REVISION_A01] = "A01",
+ [TEGRA_REVISION_A02] = "A02",
+ [TEGRA_REVISION_A03] = "A03",
+ [TEGRA_REVISION_A03p] = "A03 prime",
+ [TEGRA_REVISION_A04] = "A04",
+};
+
+static u8 fuse_readb(const unsigned int offset)
+{
+ u32 val;
+
+ val = fuse_readl(round_down(offset, 4));
+ val >>= (offset % 4) * 8;
+ val &= 0xff;
+
+ return val;
+}
+
+static ssize_t fuse_read(struct file *fd, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t pos, size_t size)
+{
+ int i;
+
+ if (pos < 0 || pos >= fuse_size)
+ return 0;
+
+ if (size > fuse_size - pos)
+ size = fuse_size - pos;
+
+ for (i = 0; i < size; i++)
+ buf[i] = fuse_readb(pos + i);
+
+ return i;
+}
+
+static struct bin_attribute fuse_bin_attr = {
+ .attr = { .name = "fuse", .mode = S_IRUGO, },
+ .read = fuse_read,
+};
+
+static const struct of_device_id tegra_fuse_match[] __initconst = {
+ { .compatible = "nvidia,tegra20-efuse", },
+ { .compatible = "nvidia,tegra30-efuse", },
+ { .compatible = "nvidia,tegra114-efuse", },
+ { .compatible = "nvidia,tegra124-efuse", },
+ {},
+};
+
+static const struct of_device_id car_match[] __initconst = {
+ { .compatible = "nvidia,tegra20-car", },
+ { .compatible = "nvidia,tegra30-car", },
+ { .compatible = "nvidia,tegra114-car", },
+ { .compatible = "nvidia,tegra124-car", },
+ {},
+};
+
+static void tegra_read_bct_strapping(void)
+{
+ tegra_bct_strapping = readl_relaxed(apbmisc_base +
+ TEGRA_STRAP_OPT);
+ tegra_bct_strapping >>= TEGRA_RAM_ID_SHIFT;
+ tegra_bct_strapping &= TEGRA_RAM_ID_MASK;
+}
+
+static void tegra_get_revision(u32 id)
+{
+ u32 minor_rev = (id >> 16) & 0xf;
+
+ switch (minor_rev) {
+ case 1:
+ tegra_revision = TEGRA_REVISION_A01;
+ break;
+ case 2:
+ tegra_revision = TEGRA_REVISION_A02;
+ break;
+ case 3:
+ if (tegra_chip_id == TEGRA20 &&
+ (tegra20_spare_fuse_early(18, fuse_base) ||
+ tegra20_spare_fuse_early(19, fuse_base)))
+ tegra_revision = TEGRA_REVISION_A03p;
+ else
+ tegra_revision = TEGRA_REVISION_A03;
+ break;
+ case 4:
+ tegra_revision = TEGRA_REVISION_A04;
+ break;
+ default:
+ tegra_revision = TEGRA_REVISION_UNKNOWN;
+ }
+}
+
+u32 tegra_read_straps(void)
+{
+ return readl(apbmisc_base + TEGRA_STRAP_OPT);
+}
+
+u32 tegra_read_chipid(void)
+{
+ return readl_relaxed(apbmisc_base + 0x804);
+}
+
+int tegra_fuse_create_sysfs(struct device *dev, int size,
+ u32 (*readl)(const unsigned int offset),
+ struct tegra_sku_info *sku_info)
+{
+ int err;
+
+ if (fuse_size)
+ return -ENODEV;
+
+ fuse_bin_attr.size = size;
+ fuse_bin_attr.read = fuse_read;
+
+ fuse_size = size;
+ fuse_readl = readl;
+
+ err = device_create_bin_file(dev, &fuse_bin_attr);
+ if (err)
+ return err;
+
+ dev_info(dev,
+ "Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
+ tegra_revision_name[sku_info->revision],
+ sku_info->sku_id, sku_info->cpu_process_id,
+ sku_info->core_process_id);
+
+ return 0;
+}
+
+void __init tegra_init_fuse(void)
+{
+ struct device_node *np;
+ u32 id, reg;
+
+ np = of_find_matching_node(NULL, tegra_fuse_match);
+ fuse_base = of_iomap(np, 0);
+ if (!fuse_base) {
+ pr_err("ioremap tegra fuse failed\n");
+ return;
+ }
+
+ apbmisc_base = of_iomap(np, 1);
+ if (!apbmisc_base) {
+ pr_err("ioremap tegra apbmisc failed\n");
+ iounmap(fuse_base);
+ return;
+ }
+
+ np = of_find_matching_node(NULL, car_match);
+ car_base = of_iomap(np, 0);
+ if (!car_base) {
+ pr_err("ioremap tegra car failed\n");
+ iounmap(fuse_base);
+ iounmap(apbmisc_base);
+ return;
+ }
+
+ reg = readl_relaxed(car_base + 0x48);
+ reg |= 1 << 28;
+ writel(reg, car_base + 0x48);
+
+ /*
+ * Enable FUSE clock. This needs to be hardcoded because the clock
+ * subsystem is not active during early boot.
+ */
+ reg = readl(car_base + 0x14);
+ reg |= 1 << 7;
+ writel(reg, car_base + 0x14);
+
+ iounmap(car_base);
+
+ id = tegra_read_chipid();
+ tegra_chip_id = (id >> 8) & 0xff;
+
+ tegra_read_bct_strapping();
+
+ tegra_get_revision(id);
+}
diff --git a/drivers/misc/fuse/tegra/fuse-tegra20.c b/drivers/misc/fuse/tegra/fuse-tegra20.c
new file mode 100644
index 0000000..45bdfb8
--- /dev/null
+++ b/drivers/misc/fuse/tegra/fuse-tegra20.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/>.
+ *
+ * Based on drivers/misc/eeprom/sunxi_sid.c
+ */
+
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/kobject.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/random.h>
+#include <linux/tegra-soc.h>
+
+#include "fuse.h"
+
+#define FUSE_BEGIN 0x100
+#define FUSE_SIZE 0x1f8
+#define FUSE_SKU_INFO 0x10
+#define FUSE_UID_LOW 0x08
+#define FUSE_UID_HIGH 0x0c
+
+static phys_addr_t fuse_phys;
+static struct clk *fuse_clk;
+static struct tegra_sku_info sku_info;
+
+static u32 tegra20_fuse_readl(const unsigned int offset)
+{
+ int ret;
+ u32 val;
+
+ clk_prepare_enable(fuse_clk);
+
+ ret = tegra_apb_readl_using_dma(fuse_phys + FUSE_BEGIN + offset, &val);
+
+ clk_disable_unprepare(fuse_clk);
+
+ return (ret < 0) ? 0 : val;
+}
+
+static void tegra20_fuse_add_randomness(void)
+{
+ u32 randomness[7];
+
+ randomness[0] = tegra20_fuse_readl(FUSE_SKU_INFO);
+ randomness[1] = tegra_read_straps();
+ randomness[2] = tegra_read_chipid();
+ randomness[3] = sku_info.cpu_process_id << 16;
+ randomness[3] |= sku_info.core_process_id;
+ randomness[4] = sku_info.cpu_speedo_id << 16 | sku_info.soc_speedo_id;
+ randomness[5] = tegra20_fuse_readl(FUSE_UID_LOW);
+ randomness[6] = tegra20_fuse_readl(FUSE_UID_HIGH);
+
+ add_device_randomness(randomness, sizeof(randomness));
+}
+
+bool tegra20_spare_fuse(int spare_bit)
+{
+ u32 offset = spare_bit * 4 + 0x100;
+
+ return tegra20_fuse_readl(offset) & 1;
+}
+
+bool tegra20_spare_fuse_early(int spare_bit, void *fuse_base)
+{
+ u32 offset = spare_bit * 4 + 0x100;
+
+ return readl_relaxed(fuse_base + FUSE_BEGIN + offset);
+}
+
+static const struct of_device_id tegra20_fuse_of_match[] = {
+ { .compatible = "nvidia,tegra20-efuse" },
+ {},
+}
+MODULE_DEVICE_TABLE(of, tegra20_fuse_of_match);
+
+static int tegra20_fuse_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+
+ fuse_clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(fuse_clk)) {
+ dev_err(&pdev->dev, "missing clock");
+ return PTR_ERR(fuse_clk);
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -EINVAL;
+ fuse_phys = res->start;
+
+ sku_info.revision = tegra_revision;
+ tegra20_init_speedo_data(&sku_info, &pdev->dev);
+ dev_dbg(&pdev->dev, "Soc Speedo ID %d", sku_info.soc_speedo_id);
+
+ tegra20_fuse_add_randomness();
+
+ if (tegra_fuse_create_sysfs(&pdev->dev, FUSE_SIZE, tegra20_fuse_readl,
+ &sku_info))
+ return -ENODEV;
+
+ dev_dbg(&pdev->dev, "loaded\n");
+
+ return 0;
+}
+
+static struct platform_driver tegra20_fuse_driver = {
+ .probe = tegra20_fuse_probe,
+ .driver = {
+ .name = "tegra20_fuse",
+ .owner = THIS_MODULE,
+ .of_match_table = tegra20_fuse_of_match,
+ }
+};
+
+static int __init tegra20_fuse_init(void)
+{
+ return platform_driver_register(&tegra20_fuse_driver);
+}
+postcore_initcall(tegra20_fuse_init);
diff --git a/drivers/misc/fuse/tegra/fuse-tegra30.c b/drivers/misc/fuse/tegra/fuse-tegra30.c
new file mode 100644
index 0000000..6133b77
--- /dev/null
+++ b/drivers/misc/fuse/tegra/fuse-tegra30.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/random.h>
+#include <linux/tegra-soc.h>
+
+#include "fuse.h"
+
+#define FUSE_BEGIN 0x100
+
+#define FUSE_SKU_INFO 0x10
+
+/* Tegra30 and later */
+#define FUSE_VENDOR_CODE 0x100
+#define FUSE_FAB_CODE 0x104
+#define FUSE_LOT_CODE_0 0x108
+#define FUSE_LOT_CODE_1 0x10c
+#define FUSE_WAFER_ID 0x110
+#define FUSE_X_COORDINATE 0x114
+#define FUSE_Y_COORDINATE 0x118
+
+#define FUSE_HAS_REVISION_INFO BIT(0)
+
+struct tegra_fuse_info {
+ int size;
+ int spare_bit;
+ void (*init_speedo_data)(struct tegra_sku_info *sku_info,
+ struct device *dev);
+};
+
+static void __iomem *fuse_base;
+static struct clk *fuse_clk;
+static struct tegra_fuse_info *fuse_info;
+static struct tegra_sku_info sku_info;
+
+u32 tegra30_fuse_readl(const unsigned int offset)
+{
+ u32 val;
+
+ clk_prepare_enable(fuse_clk);
+
+ val = readl_relaxed(fuse_base + FUSE_BEGIN + offset);
+
+ clk_disable_unprepare(fuse_clk);
+
+ return val;
+}
+
+bool tegra30_spare_fuse(int spare_bit)
+{
+ u32 offset = fuse_info->spare_bit + spare_bit * 4;
+
+ return tegra30_fuse_readl(offset) & 1;
+}
+
+static void tegra30_fuse_add_randomness(void)
+{
+ u32 randomness[12];
+
+ randomness[0] = tegra30_fuse_readl(FUSE_SKU_INFO);
+ randomness[1] = tegra_read_straps();
+ randomness[2] = tegra_read_chipid();
+ randomness[3] = sku_info.cpu_process_id << 16;
+ randomness[3] |= sku_info.core_process_id;
+ randomness[4] = sku_info.cpu_speedo_id << 16;
+ randomness[4] |= sku_info.soc_speedo_id;
+ randomness[5] = tegra30_fuse_readl(FUSE_VENDOR_CODE);
+ randomness[6] = tegra30_fuse_readl(FUSE_FAB_CODE);
+ randomness[7] = tegra30_fuse_readl(FUSE_LOT_CODE_0);
+ randomness[8] = tegra30_fuse_readl(FUSE_LOT_CODE_1);
+ randomness[9] = tegra30_fuse_readl(FUSE_WAFER_ID);
+ randomness[10] = tegra30_fuse_readl(FUSE_X_COORDINATE);
+ randomness[11] = tegra30_fuse_readl(FUSE_Y_COORDINATE);
+
+ add_device_randomness(randomness, sizeof(randomness));
+}
+
+static struct tegra_fuse_info tegra30_info = {
+ .size = 0x2a4,
+ .spare_bit = 0x144,
+ .init_speedo_data = tegra30_init_speedo_data,
+};
+
+static struct tegra_fuse_info tegra114_info = {
+ .size = 0x2a0,
+ .init_speedo_data = tegra114_init_speedo_data,
+};
+
+static struct tegra_fuse_info tegra124_info = {
+ .size = 0x300,
+ .init_speedo_data = tegra124_init_speedo_data,
+};
+
+static const struct of_device_id tegra30_fuse_of_match[] = {
+ { .compatible = "nvidia,tegra30-efuse", .data = &tegra30_info },
+ { .compatible = "nvidia,tegra114-efuse", .data = &tegra114_info },
+ { .compatible = "nvidia,tegra124-efuse", .data = &tegra124_info },
+ {},
+};
+
+static int tegra30_fuse_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *of_dev_id;
+ struct resource *res;
+
+ of_dev_id = of_match_device(tegra30_fuse_of_match, &pdev->dev);
+ if (!of_dev_id)
+ return -ENODEV;
+ fuse_info = (struct tegra_fuse_info *)of_dev_id->data;
+
+ fuse_clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(fuse_clk)) {
+ dev_err(&pdev->dev, "missing clock");
+ return PTR_ERR(fuse_clk);
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ fuse_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(fuse_base)) {
+ dev_err(&pdev->dev, "unable to map base address");
+ return PTR_ERR(fuse_base);
+ }
+
+ sku_info.revision = tegra_revision;
+ fuse_info->init_speedo_data(&sku_info, &pdev->dev);
+ dev_dbg(&pdev->dev, "CPU Speedo ID %d, Soc Speedo ID %d",
+ sku_info.cpu_speedo_id, sku_info.soc_speedo_id);
+
+ tegra30_fuse_add_randomness();
+
+ platform_set_drvdata(pdev, NULL);
+
+ if (tegra_fuse_create_sysfs(&pdev->dev, fuse_info->size,
+ tegra30_fuse_readl, &sku_info))
+ return -ENODEV;
+
+ dev_dbg(&pdev->dev, "loaded\n");
+
+ return 0;
+}
+
+static struct platform_driver tegra30_fuse_driver = {
+ .probe = tegra30_fuse_probe,
+ .driver = {
+ .name = "tegra_fuse",
+ .owner = THIS_MODULE,
+ .of_match_table = tegra30_fuse_of_match,
+ }
+};
+
+static int __init tegra30_fuse_init(void)
+{
+ return platform_driver_register(&tegra30_fuse_driver);
+}
+postcore_initcall(tegra30_fuse_init);
+
diff --git a/drivers/misc/fuse/tegra/fuse.h b/drivers/misc/fuse/tegra/fuse.h
new file mode 100644
index 0000000..0baf82b
--- /dev/null
+++ b/drivers/misc/fuse/tegra/fuse.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Author:
+ * Colin Cross <ccross@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __DRIVERS_MISC_TEGRA_FUSE_H
+#define __DRIVERS_MISC_TEGRA_FUSE_H
+
+struct tegra_sku_info {
+ int sku_id;
+ int cpu_process_id;
+ int cpu_speedo_id;
+ int cpu_speedo_value;
+ int cpu_iddq_value;
+ int core_process_id;
+ int soc_speedo_id;
+ int gpu_speedo_id;
+ int gpu_process_id;
+ int gpu_speedo_value;
+ enum tegra_revision revision;
+};
+
+int tegra_fuse_create_sysfs(struct device *dev, int size,
+ u32 (*readl)(const unsigned int offset),
+ struct tegra_sku_info *sku_info);
+
+bool tegra30_spare_fuse(int bit);
+u32 tegra30_fuse_readl(const unsigned int offset);
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+void tegra20_init_speedo_data(struct tegra_sku_info *sku_info,
+ struct device *dev);
+bool tegra20_spare_fuse(int bit);
+bool tegra20_spare_fuse_early(int spare_bit, void *fuse_base);
+#else
+static inline void tegra20_init_speedo_data(struct tegra_sku_info *sku_info,
+ struct device *dev) {}
+static inline bool tegra20_spare_fuse(int bit) { return false; }
+static inline bool tegra20_spare_fuse_early(int spare_bit, void *fuse_base)
+{
+ return false;
+}
+#endif
+
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+void tegra30_init_speedo_data(struct tegra_sku_info *sku_info,
+ struct device *dev);
+#else
+static inline void tegra30_init_speedo_data(struct tegra_sku_info *sku_info,
+ struct device *dev) {}
+#endif
+
+#ifdef CONFIG_ARCH_TEGRA_114_SOC
+void tegra114_init_speedo_data(struct tegra_sku_info *sku_info,
+ struct device *dev);
+#else
+static inline void tegra114_init_speedo_data(struct tegra_sku_info *sku_info,
+ struct device *dev) {}
+#endif
+
+#ifdef CONFIG_ARCH_TEGRA_124_SOC
+void tegra124_init_speedo_data(struct tegra_sku_info *sku_info,
+ struct device *dev);
+#else
+static inline void tegra124_init_speedo_data(struct tegra_sku_info *sku_info,
+ struct device *dev) {}
+#endif
+
+#endif
diff --git a/drivers/misc/fuse/tegra/tegra114_speedo.c b/drivers/misc/fuse/tegra/tegra114_speedo.c
new file mode 100644
index 0000000..7be8ba5
--- /dev/null
+++ b/drivers/misc/fuse/tegra/tegra114_speedo.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/device.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/tegra-soc.h>
+
+#include "fuse.h"
+
+#define CORE_PROCESS_CORNERS_NUM 2
+#define CPU_PROCESS_CORNERS_NUM 2
+
+enum {
+ THRESHOLD_INDEX_0,
+ THRESHOLD_INDEX_1,
+ THRESHOLD_INDEX_COUNT,
+};
+
+static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
+ {1123, UINT_MAX},
+ {0, UINT_MAX},
+};
+
+static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
+ {1695, UINT_MAX},
+ {0, UINT_MAX},
+};
+
+static void rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
+ int *threshold, struct device *dev)
+{
+ u32 tmp;
+ u32 sku = sku_info->sku_id;
+ enum tegra_revision rev = sku_info->revision;
+
+ switch (sku) {
+ case 0x00:
+ case 0x10:
+ case 0x05:
+ case 0x06:
+ sku_info->cpu_speedo_id = 1;
+ sku_info->soc_speedo_id = 0;
+ *threshold = THRESHOLD_INDEX_0;
+ break;
+
+ case 0x03:
+ case 0x04:
+ sku_info->cpu_speedo_id = 2;
+ sku_info->soc_speedo_id = 1;
+ *threshold = THRESHOLD_INDEX_1;
+ break;
+
+ default:
+ dev_err(dev, "Unknown SKU %d\n", sku);
+ sku_info->cpu_speedo_id = 0;
+ sku_info->soc_speedo_id = 0;
+ *threshold = THRESHOLD_INDEX_0;
+ break;
+ }
+
+ if (rev == TEGRA_REVISION_A01) {
+ tmp = tegra30_fuse_readl(0x270) << 1;
+ tmp |= tegra30_fuse_readl(0x26c);
+ if (!tmp)
+ sku_info->cpu_speedo_id = 0;
+ }
+}
+
+void tegra114_init_speedo_data(struct tegra_sku_info *sku_info,
+ struct device *dev)
+{
+ u32 cpu_speedo_val;
+ u32 core_speedo_val;
+ int threshold;
+ int i;
+
+ BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+ BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+
+ rev_sku_to_speedo_ids(sku_info, &threshold, dev);
+
+ cpu_speedo_val = tegra30_fuse_readl(0x12c) + 1024;
+ core_speedo_val = tegra30_fuse_readl(0x134);
+
+ for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++)
+ if (cpu_speedo_val < cpu_process_speedos[threshold][i])
+ break;
+ sku_info->cpu_process_id = i;
+
+ for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++)
+ if (core_speedo_val < core_process_speedos[threshold][i])
+ break;
+ sku_info->core_process_id = i;
+}
diff --git a/drivers/misc/fuse/tegra/tegra124_speedo.c b/drivers/misc/fuse/tegra/tegra124_speedo.c
new file mode 100644
index 0000000..70edb2d
--- /dev/null
+++ b/drivers/misc/fuse/tegra/tegra124_speedo.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/device.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/tegra-soc.h>
+
+#include "fuse.h"
+
+#define CPU_PROCESS_CORNERS_NUM 2
+#define GPU_PROCESS_CORNERS_NUM 2
+#define CORE_PROCESS_CORNERS_NUM 2
+
+#define FUSE_CPU_SPEEDO_0 0x14
+#define FUSE_CPU_SPEEDO_1 0x2c
+#define FUSE_CPU_SPEEDO_2 0x30
+#define FUSE_SOC_SPEEDO_0 0x34
+#define FUSE_SOC_SPEEDO_1 0x38
+#define FUSE_SOC_SPEEDO_2 0x3c
+#define FUSE_CPU_IDDQ 0x18
+#define FUSE_SOC_IDDQ 0x40
+#define FUSE_GPU_IDDQ 0x128
+#define FUSE_FT_REV 0x28
+
+enum {
+ THRESHOLD_INDEX_0,
+ THRESHOLD_INDEX_1,
+ THRESHOLD_INDEX_COUNT,
+};
+
+static int cpu_speedo_0_value;
+static int cpu_speedo_1_value;
+static int soc_speedo_0_value;
+static int soc_speedo_1_value;
+static int soc_speedo_2_value;
+static int cpu_iddq_value;
+static int gpu_iddq_value;
+static int soc_iddq_value;
+
+static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
+ {2190, UINT_MAX},
+ {0, UINT_MAX},
+};
+
+static const u32 gpu_process_speedos[][GPU_PROCESS_CORNERS_NUM] = {
+ {1965, UINT_MAX},
+ {0, UINT_MAX},
+};
+
+static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
+ {2101, UINT_MAX},
+ {0, UINT_MAX},
+};
+
+static void rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
+ int *threshold, struct device *dev)
+{
+ int sku = sku_info->sku_id;
+
+ /* Assign to default */
+ sku_info->cpu_speedo_id = 0;
+ sku_info->soc_speedo_id = 0;
+ sku_info->gpu_speedo_id = 0;
+ *threshold = THRESHOLD_INDEX_0;
+
+ switch (sku) {
+ case 0x00: /* Eng sku */
+ case 0x0F:
+ /* Using the default */
+ break;
+
+ case 0x81:
+ case 0x83:
+ sku_info->cpu_speedo_id = 2;
+ break;
+
+ case 0x07:
+ sku_info->cpu_speedo_id = 1;
+ sku_info->soc_speedo_id = 1;
+ sku_info->gpu_speedo_id = 1;
+ *threshold = THRESHOLD_INDEX_1;
+ break;
+
+ default:
+ dev_err(dev, "Unknown SKU %d\n", sku);
+ /* Using the default for the error case */
+ break;
+ }
+}
+
+void tegra124_init_speedo_data(struct tegra_sku_info *sku_info,
+ struct device *dev)
+{
+ int i;
+ int threshold;
+
+ BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+ BUILD_BUG_ON(ARRAY_SIZE(gpu_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+ BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+
+ cpu_speedo_0_value = tegra30_fuse_readl(FUSE_CPU_SPEEDO_0);
+ cpu_speedo_1_value = tegra30_fuse_readl(FUSE_CPU_SPEEDO_1);
+
+ /* GPU Speedo is stored in CPU_SPEEDO_2 */
+ sku_info->gpu_speedo_value = tegra30_fuse_readl(FUSE_CPU_SPEEDO_2);
+
+ soc_speedo_0_value = tegra30_fuse_readl(FUSE_SOC_SPEEDO_0);
+ soc_speedo_1_value = tegra30_fuse_readl(FUSE_SOC_SPEEDO_1);
+ soc_speedo_2_value = tegra30_fuse_readl(FUSE_SOC_SPEEDO_2);
+
+ cpu_iddq_value = tegra30_fuse_readl(FUSE_CPU_IDDQ);
+ soc_iddq_value = tegra30_fuse_readl(FUSE_SOC_IDDQ);
+ gpu_iddq_value = tegra30_fuse_readl(FUSE_GPU_IDDQ);
+
+ sku_info->cpu_speedo_value = cpu_speedo_0_value;
+
+ if (sku_info->cpu_speedo_value == 0) {
+ dev_warn(dev, "Warning: Speedo value not fused.\n");
+ WARN_ON(1);
+ return;
+ }
+
+ rev_sku_to_speedo_ids(sku_info, &threshold, dev);
+
+ sku_info->cpu_iddq_value = tegra30_fuse_readl(FUSE_CPU_IDDQ);
+
+ for (i = 0; i < GPU_PROCESS_CORNERS_NUM; i++)
+ if (sku_info->gpu_speedo_value <
+ gpu_process_speedos[threshold][i])
+ break;
+ sku_info->gpu_process_id = i;
+
+ for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++)
+ if (sku_info->cpu_speedo_value <
+ cpu_process_speedos[threshold][i])
+ break;
+ sku_info->cpu_process_id = i;
+
+ for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++)
+ if (soc_speedo_0_value <
+ core_process_speedos[threshold][i])
+ break;
+ sku_info->core_process_id = i;
+
+ dev_dbg(dev, "GPU Speedo ID=%d, Speedo Value=%d\n",
+ sku_info->gpu_speedo_id, sku_info->gpu_speedo_value);
+}
diff --git a/drivers/misc/fuse/tegra/tegra20_speedo.c b/drivers/misc/fuse/tegra/tegra20_speedo.c
new file mode 100644
index 0000000..af8e86a
--- /dev/null
+++ b/drivers/misc/fuse/tegra/tegra20_speedo.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/kernel.h>
+#include <linux/device.h>
+#include <linux/bug.h>
+#include <linux/tegra-soc.h>
+
+#include "fuse.h"
+
+#define CPU_SPEEDO_LSBIT 20
+#define CPU_SPEEDO_MSBIT 29
+#define CPU_SPEEDO_REDUND_LSBIT 30
+#define CPU_SPEEDO_REDUND_MSBIT 39
+#define CPU_SPEEDO_REDUND_OFFS (CPU_SPEEDO_REDUND_MSBIT - CPU_SPEEDO_MSBIT)
+
+#define CORE_SPEEDO_LSBIT 40
+#define CORE_SPEEDO_MSBIT 47
+#define CORE_SPEEDO_REDUND_LSBIT 48
+#define CORE_SPEEDO_REDUND_MSBIT 55
+#define CORE_SPEEDO_REDUND_OFFS (CORE_SPEEDO_REDUND_MSBIT - CORE_SPEEDO_MSBIT)
+
+#define SPEEDO_MULT 4
+
+#define PROCESS_CORNERS_NUM 4
+
+#define SPEEDO_ID_SELECT_0(rev) ((rev) <= 2)
+#define SPEEDO_ID_SELECT_1(sku) \
+ (((sku) != 20) && ((sku) != 23) && ((sku) != 24) && \
+ ((sku) != 27) && ((sku) != 28))
+
+enum {
+ SPEEDO_ID_0,
+ SPEEDO_ID_1,
+ SPEEDO_ID_2,
+ SPEEDO_ID_COUNT,
+};
+
+static const u32 cpu_process_speedos[][PROCESS_CORNERS_NUM] = {
+ {315, 366, 420, UINT_MAX},
+ {303, 368, 419, UINT_MAX},
+ {316, 331, 383, UINT_MAX},
+};
+
+static const u32 core_process_speedos[][PROCESS_CORNERS_NUM] = {
+ {165, 195, 224, UINT_MAX},
+ {165, 195, 224, UINT_MAX},
+ {165, 195, 224, UINT_MAX},
+};
+
+void tegra20_init_speedo_data(struct tegra_sku_info *sku_info,
+ struct device *dev)
+{
+ u32 reg;
+ u32 val;
+ int i;
+
+ BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) != SPEEDO_ID_COUNT);
+ BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) != SPEEDO_ID_COUNT);
+
+ if (SPEEDO_ID_SELECT_0(sku_info->revision))
+ sku_info->soc_speedo_id = SPEEDO_ID_0;
+ else if (SPEEDO_ID_SELECT_1(sku_info->sku_id))
+ sku_info->soc_speedo_id = SPEEDO_ID_1;
+ else
+ sku_info->soc_speedo_id = SPEEDO_ID_2;
+
+ val = 0;
+ for (i = CPU_SPEEDO_MSBIT; i >= CPU_SPEEDO_LSBIT; i--) {
+ reg = tegra20_spare_fuse(i) |
+ tegra20_spare_fuse(i + CPU_SPEEDO_REDUND_OFFS);
+ val = (val << 1) | (reg & 0x1);
+ }
+ val = val * SPEEDO_MULT;
+ dev_dbg(dev, "CPU speedo value %u\n", val);
+
+ for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
+ if (val <= cpu_process_speedos[sku_info->soc_speedo_id][i])
+ break;
+ }
+ sku_info->cpu_process_id = i;
+
+ val = 0;
+ for (i = CORE_SPEEDO_MSBIT; i >= CORE_SPEEDO_LSBIT; i--) {
+ reg = tegra20_spare_fuse(i) |
+ tegra20_spare_fuse(i + CORE_SPEEDO_REDUND_OFFS);
+ val = (val << 1) | (reg & 0x1);
+ }
+ val = val * SPEEDO_MULT;
+ dev_dbg(dev, "Core speedo value %u\n", val);
+
+ for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
+ if (val <= core_process_speedos[sku_info->soc_speedo_id][i])
+ break;
+ }
+ sku_info->core_process_id = i;
+}
diff --git a/drivers/misc/fuse/tegra/tegra30_speedo.c b/drivers/misc/fuse/tegra/tegra30_speedo.c
new file mode 100644
index 0000000..11cf0cd
--- /dev/null
+++ b/drivers/misc/fuse/tegra/tegra30_speedo.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/device.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/tegra-soc.h>
+
+#include "fuse.h"
+
+#define CORE_PROCESS_CORNERS_NUM 1
+#define CPU_PROCESS_CORNERS_NUM 6
+
+#define FUSE_SPEEDO_CALIB_0 0x14
+#define FUSE_PACKAGE_INFO 0XFC
+#define FUSE_TEST_PROG_VER 0X28
+
+#define G_SPEEDO_BIT_MINUS1 58
+#define G_SPEEDO_BIT_MINUS1_R 59
+#define G_SPEEDO_BIT_MINUS2 60
+#define G_SPEEDO_BIT_MINUS2_R 61
+#define LP_SPEEDO_BIT_MINUS1 62
+#define LP_SPEEDO_BIT_MINUS1_R 63
+#define LP_SPEEDO_BIT_MINUS2 64
+#define LP_SPEEDO_BIT_MINUS2_R 65
+
+enum {
+ THRESHOLD_INDEX_0,
+ THRESHOLD_INDEX_1,
+ THRESHOLD_INDEX_2,
+ THRESHOLD_INDEX_3,
+ THRESHOLD_INDEX_4,
+ THRESHOLD_INDEX_5,
+ THRESHOLD_INDEX_6,
+ THRESHOLD_INDEX_7,
+ THRESHOLD_INDEX_8,
+ THRESHOLD_INDEX_9,
+ THRESHOLD_INDEX_10,
+ THRESHOLD_INDEX_11,
+ THRESHOLD_INDEX_COUNT,
+};
+
+static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
+ {180},
+ {170},
+ {195},
+ {180},
+ {168},
+ {192},
+ {180},
+ {170},
+ {195},
+ {180},
+ {180},
+ {180},
+};
+
+static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
+ {306, 338, 360, 376, UINT_MAX},
+ {295, 336, 358, 375, UINT_MAX},
+ {325, 325, 358, 375, UINT_MAX},
+ {325, 325, 358, 375, UINT_MAX},
+ {292, 324, 348, 364, UINT_MAX},
+ {324, 324, 348, 364, UINT_MAX},
+ {324, 324, 348, 364, UINT_MAX},
+ {295, 336, 358, 375, UINT_MAX},
+ {358, 358, 358, 358, 397, UINT_MAX},
+ {364, 364, 364, 364, 397, UINT_MAX},
+ {295, 336, 358, 375, 391, UINT_MAX},
+ {295, 336, 358, 375, 391, UINT_MAX},
+};
+
+static int threshold_index;
+static int package_id;
+
+static void fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp,
+ struct device *dev)
+{
+ u32 reg;
+ int ate_ver;
+ int bit_minus1;
+ int bit_minus2;
+
+ reg = tegra30_fuse_readl(FUSE_SPEEDO_CALIB_0);
+
+ *speedo_lp = (reg & 0xFFFF) * 4;
+ *speedo_g = ((reg >> 16) & 0xFFFF) * 4;
+
+ ate_ver = tegra30_fuse_readl(FUSE_TEST_PROG_VER);
+ dev_dbg(dev, "ATE prog ver %d.%d\n", ate_ver/10, ate_ver%10);
+
+ if (ate_ver >= 26) {
+ bit_minus1 = tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS1);
+ bit_minus1 |= tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS1_R);
+ bit_minus2 = tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS2);
+ bit_minus2 |= tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS2_R);
+ *speedo_lp |= (bit_minus1 << 1) | bit_minus2;
+
+ bit_minus1 = tegra30_spare_fuse(G_SPEEDO_BIT_MINUS1);
+ bit_minus1 |= tegra30_spare_fuse(G_SPEEDO_BIT_MINUS1_R);
+ bit_minus2 = tegra30_spare_fuse(G_SPEEDO_BIT_MINUS2);
+ bit_minus2 |= tegra30_spare_fuse(G_SPEEDO_BIT_MINUS2_R);
+ *speedo_g |= (bit_minus1 << 1) | bit_minus2;
+ } else {
+ *speedo_lp |= 0x3;
+ *speedo_g |= 0x3;
+ }
+}
+
+static void rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
+ struct device *dev)
+{
+ switch (sku_info->revision) {
+ case TEGRA_REVISION_A01:
+ sku_info->cpu_speedo_id = 0;
+ sku_info->soc_speedo_id = 0;
+ threshold_index = THRESHOLD_INDEX_0;
+ break;
+ case TEGRA_REVISION_A02:
+ case TEGRA_REVISION_A03:
+ switch (sku_info->sku_id) {
+ case 0x87:
+ case 0x82:
+ sku_info->cpu_speedo_id = 1;
+ sku_info->soc_speedo_id = 1;
+ threshold_index = THRESHOLD_INDEX_1;
+ break;
+ case 0x81:
+ switch (package_id) {
+ case 1:
+ sku_info->cpu_speedo_id = 2;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_2;
+ break;
+ case 2:
+ sku_info->cpu_speedo_id = 4;
+ sku_info->soc_speedo_id = 1;
+ threshold_index = THRESHOLD_INDEX_7;
+ break;
+ default:
+ dev_err(dev, "Unknown pkg %d\n", package_id);
+ BUG();
+ break;
+ }
+ break;
+ case 0x80:
+ switch (package_id) {
+ case 1:
+ sku_info->cpu_speedo_id = 5;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_8;
+ break;
+ case 2:
+ sku_info->cpu_speedo_id = 6;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_9;
+ break;
+ default:
+ dev_err(dev, "Unknown pkg %d\n", package_id);
+ BUG();
+ break;
+ }
+ break;
+ case 0x83:
+ switch (package_id) {
+ case 1:
+ sku_info->cpu_speedo_id = 7;
+ sku_info->soc_speedo_id = 1;
+ threshold_index = THRESHOLD_INDEX_10;
+ break;
+ case 2:
+ sku_info->cpu_speedo_id = 3;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_3;
+ break;
+ default:
+ dev_err(dev, "Unknown pkg %d\n", package_id);
+ BUG();
+ break;
+ }
+ break;
+ case 0x8F:
+ sku_info->cpu_speedo_id = 8;
+ sku_info->soc_speedo_id = 1;
+ threshold_index = THRESHOLD_INDEX_11;
+ break;
+ case 0x08:
+ sku_info->cpu_speedo_id = 1;
+ sku_info->soc_speedo_id = 1;
+ threshold_index = THRESHOLD_INDEX_4;
+ break;
+ case 0x02:
+ sku_info->cpu_speedo_id = 2;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_5;
+ break;
+ case 0x04:
+ sku_info->cpu_speedo_id = 3;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_6;
+ break;
+ case 0:
+ switch (package_id) {
+ case 1:
+ sku_info->cpu_speedo_id = 2;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_2;
+ break;
+ case 2:
+ sku_info->cpu_speedo_id = 3;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_3;
+ break;
+ default:
+ dev_err(dev, "Unknown pkg %d\n", package_id);
+ BUG();
+ break;
+ }
+ break;
+ default:
+ dev_warn(dev, "Unknown SKU %d\n", sku_info->sku_id);
+ sku_info->cpu_speedo_id = 0;
+ sku_info->soc_speedo_id = 0;
+ threshold_index = THRESHOLD_INDEX_0;
+ break;
+ }
+ break;
+ default:
+ dev_warn(dev, "Unknown chip rev %d\n", sku_info->revision);
+ sku_info->cpu_speedo_id = 0;
+ sku_info->soc_speedo_id = 0;
+ threshold_index = THRESHOLD_INDEX_0;
+ break;
+ }
+}
+
+void tegra30_init_speedo_data(struct tegra_sku_info *sku_info,
+ struct device *dev)
+{
+ u32 cpu_speedo_val;
+ u32 core_speedo_val;
+ int i;
+
+ BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+ BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+
+ package_id = tegra30_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F;
+
+ rev_sku_to_speedo_ids(sku_info, dev);
+ fuse_speedo_calib(&cpu_speedo_val, &core_speedo_val, dev);
+ dev_dbg(dev, "CPU speedo value %u\n", cpu_speedo_val);
+ dev_dbg(dev, "Core speedo value %u\n", core_speedo_val);
+
+ for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) {
+ if (cpu_speedo_val < cpu_process_speedos[threshold_index][i])
+ break;
+ }
+ sku_info->cpu_process_id = i - 1;
+
+ if (sku_info->cpu_process_id == -1) {
+ dev_warn(dev, "CPU speedo value %3d out of range",
+ cpu_speedo_val);
+ sku_info->cpu_process_id = 0;
+ sku_info->cpu_speedo_id = 1;
+ }
+
+ for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++) {
+ if (core_speedo_val < core_process_speedos[threshold_index][i])
+ break;
+ }
+ sku_info->core_process_id = i - 1;
+
+ if (sku_info->core_process_id == -1) {
+ dev_warn(dev, "CORE speedo value %3d out of range",
+ core_speedo_val);
+ sku_info->core_process_id = 0;
+ sku_info->soc_speedo_id = 1;
+ }
+}
--
1.7.7.rc0.72.g4b5ea.dirty
^ permalink raw reply related
* [PATCH v3 2/6] ARM: tegra: Add chipid, revision and fuse init
From: Peter De Schrijver @ 2014-01-28 23:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390952176-30402-1-git-send-email-pdeschrijver@nvidia.com>
All fuse related functionality will move to a driver in the following patches.
To prepare for this, export all the required functionality in a global header
file and move all users of fuse.h to tegra-soc.h
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
arch/arm/mach-tegra/cpuidle.c | 2 +-
arch/arm/mach-tegra/flowctrl.c | 2 +-
arch/arm/mach-tegra/fuse.h | 18 ------------------
arch/arm/mach-tegra/hotplug.c | 2 +-
arch/arm/mach-tegra/platsmp.c | 2 +-
arch/arm/mach-tegra/pm.c | 2 +-
arch/arm/mach-tegra/pmc.c | 2 +-
arch/arm/mach-tegra/powergate.c | 2 +-
arch/arm/mach-tegra/reset-handler.S | 2 +-
arch/arm/mach-tegra/reset.c | 2 +-
arch/arm/mach-tegra/sleep-tegra30.S | 2 +-
arch/arm/mach-tegra/tegra.c | 2 +-
arch/arm/mach-tegra/tegra114_speedo.c | 1 +
arch/arm/mach-tegra/tegra20_speedo.c | 1 +
arch/arm/mach-tegra/tegra2_emc.c | 2 +-
arch/arm/mach-tegra/tegra30_speedo.c | 1 +
include/linux/tegra-soc.h | 25 +++++++++++++++++++++++++
17 files changed, 40 insertions(+), 30 deletions(-)
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
index 7bc5d8d..ff0a10b 100644
--- a/arch/arm/mach-tegra/cpuidle.c
+++ b/arch/arm/mach-tegra/cpuidle.c
@@ -23,8 +23,8 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/tegra-soc.h>
-#include "fuse.h"
#include "cpuidle.h"
void __init tegra_cpuidle_init(void)
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c
index 43ae750..d2e0197 100644
--- a/arch/arm/mach-tegra/flowctrl.c
+++ b/arch/arm/mach-tegra/flowctrl.c
@@ -21,10 +21,10 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/cpumask.h>
+#include <linux/tegra-soc.h>
#include "flowctrl.h"
#include "iomap.h"
-#include "fuse.h"
static u8 flowctrl_offset_halt_cpu[] = {
FLOW_CTRL_HALT_CPU0_EVENTS,
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
index c01d047..b17c4ba 100644
--- a/arch/arm/mach-tegra/fuse.h
+++ b/arch/arm/mach-tegra/fuse.h
@@ -26,21 +26,7 @@
#define SKU_ID_AP25E 27
#define SKU_ID_T25E 28
-#define TEGRA20 0x20
-#define TEGRA30 0x30
-#define TEGRA114 0x35
-#define TEGRA124 0x40
-
#ifndef __ASSEMBLY__
-enum tegra_revision {
- TEGRA_REVISION_UNKNOWN = 0,
- TEGRA_REVISION_A01,
- TEGRA_REVISION_A02,
- TEGRA_REVISION_A03,
- TEGRA_REVISION_A03p,
- TEGRA_REVISION_A04,
- TEGRA_REVISION_MAX,
-};
extern int tegra_sku_id;
extern int tegra_cpu_process_id;
@@ -48,12 +34,8 @@ extern int tegra_core_process_id;
extern int tegra_chip_id;
extern int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */
extern int tegra_soc_speedo_id;
-extern enum tegra_revision tegra_revision;
-
-extern int tegra_bct_strapping;
unsigned long long tegra_chip_uid(void);
-void tegra_init_fuse(void);
bool tegra_spare_fuse(int bit);
u32 tegra_fuse_readl(unsigned long offset);
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index ff26af2..38c5170 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -10,10 +10,10 @@
#include <linux/kernel.h>
#include <linux/smp.h>
#include <linux/clk/tegra.h>
+#include <linux/tegra-soc.h>
#include <asm/smp_plat.h>
-#include "fuse.h"
#include "sleep.h"
static void (*tegra_hotplug_shutdown)(void);
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index eb72ae7..44409fd 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -19,13 +19,13 @@
#include <linux/smp.h>
#include <linux/io.h>
#include <linux/clk/tegra.h>
+#include <linux/tegra-soc.h>
#include <asm/cacheflush.h>
#include <asm/mach-types.h>
#include <asm/smp_scu.h>
#include <asm/smp_plat.h>
-#include "fuse.h"
#include "flowctrl.h"
#include "reset.h"
#include "pmc.h"
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 4ae0286..b444ce7 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -25,6 +25,7 @@
#include <linux/suspend.h>
#include <linux/err.h>
#include <linux/clk/tegra.h>
+#include <linux/tegra-soc.h>
#include <asm/smp_plat.h>
#include <asm/cacheflush.h>
@@ -36,7 +37,6 @@
#include "iomap.h"
#include "reset.h"
#include "flowctrl.h"
-#include "fuse.h"
#include "pm.h"
#include "pmc.h"
#include "sleep.h"
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index fb79202..d8fe587 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -21,9 +21,9 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/tegra-powergate.h>
+#include <linux/tegra-soc.h>
#include "flowctrl.h"
-#include "fuse.h"
#include "pm.h"
#include "pmc.h"
#include "sleep.h"
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c
index 3d0c537..e5c6d0f 100644
--- a/arch/arm/mach-tegra/powergate.c
+++ b/arch/arm/mach-tegra/powergate.c
@@ -30,8 +30,8 @@
#include <linux/spinlock.h>
#include <linux/clk/tegra.h>
#include <linux/tegra-powergate.h>
+#include <linux/tegra-soc.h>
-#include "fuse.h"
#include "iomap.h"
#define DPD_SAMPLE 0x020
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index 9aa6cd3..f427466 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -19,9 +19,9 @@
#include <asm/cache.h>
#include <asm/asm-offsets.h>
#include <asm/hardware/cache-l2x0.h>
+#include <linux/tegra-soc.h>
#include "flowctrl.h"
-#include "fuse.h"
#include "iomap.h"
#include "reset.h"
#include "sleep.h"
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index 146fe8e..203bac5 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -22,12 +22,12 @@
#include <asm/cacheflush.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/firmware.h>
+#include <linux/tegra-soc.h>
#include "iomap.h"
#include "irammap.h"
#include "reset.h"
#include "sleep.h"
-#include "fuse.h"
#define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \
TEGRA_IRAM_RESET_HANDLER_OFFSET)
diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S
index b16d4a57..f808c2c 100644
--- a/arch/arm/mach-tegra/sleep-tegra30.S
+++ b/arch/arm/mach-tegra/sleep-tegra30.S
@@ -15,13 +15,13 @@
*/
#include <linux/linkage.h>
+#include <linux/tegra-soc.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/cache.h>
#include "irammap.h"
-#include "fuse.h"
#include "sleep.h"
#include "flowctrl.h"
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index 303a285..3cfca20 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -34,6 +34,7 @@
#include <linux/usb/tegra_usb_phy.h>
#include <linux/clk/tegra.h>
#include <linux/irqchip.h>
+#include <linux/tegra-soc.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/mach-types.h>
@@ -46,7 +47,6 @@
#include "board.h"
#include "common.h"
#include "cpuidle.h"
-#include "fuse.h"
#include "iomap.h"
#include "irq.h"
#include "pmc.h"
diff --git a/arch/arm/mach-tegra/tegra114_speedo.c b/arch/arm/mach-tegra/tegra114_speedo.c
index 5218d48..7c73716 100644
--- a/arch/arm/mach-tegra/tegra114_speedo.c
+++ b/arch/arm/mach-tegra/tegra114_speedo.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/bug.h>
+#include <linux/tegra-soc.h>
#include "fuse.h"
diff --git a/arch/arm/mach-tegra/tegra20_speedo.c b/arch/arm/mach-tegra/tegra20_speedo.c
index fa6eb57..3b1bb53 100644
--- a/arch/arm/mach-tegra/tegra20_speedo.c
+++ b/arch/arm/mach-tegra/tegra20_speedo.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/bug.h>
+#include <linux/tegra-soc.h>
#include "fuse.h"
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
index 3ae4a7f..26e4edb 100644
--- a/arch/arm/mach-tegra/tegra2_emc.c
+++ b/arch/arm/mach-tegra/tegra2_emc.c
@@ -24,9 +24,9 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/platform_data/tegra_emc.h>
+#include <linux/tegra-soc.h>
#include "tegra2_emc.h"
-#include "fuse.h"
#ifdef CONFIG_TEGRA_EMC_SCALING_ENABLE
static bool emc_enable = true;
diff --git a/arch/arm/mach-tegra/tegra30_speedo.c b/arch/arm/mach-tegra/tegra30_speedo.c
index 125cb16..81a958d 100644
--- a/arch/arm/mach-tegra/tegra30_speedo.c
+++ b/arch/arm/mach-tegra/tegra30_speedo.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/bug.h>
+#include <linux/tegra-soc.h>
#include "fuse.h"
diff --git a/include/linux/tegra-soc.h b/include/linux/tegra-soc.h
index b02d73b..ccf42ee 100644
--- a/include/linux/tegra-soc.h
+++ b/include/linux/tegra-soc.h
@@ -17,8 +17,30 @@
#ifndef __LINUX_TEGRA_SOC_H_
#define __LINUX_TEGRA_SOC_H_
+#define TEGRA20 0x20
+#define TEGRA30 0x30
+#define TEGRA114 0x35
+#define TEGRA124 0x40
+
+#ifndef __ASSEMBLY__
+
+enum tegra_revision {
+ TEGRA_REVISION_UNKNOWN = 0,
+ TEGRA_REVISION_A01,
+ TEGRA_REVISION_A02,
+ TEGRA_REVISION_A03,
+ TEGRA_REVISION_A03p,
+ TEGRA_REVISION_A04,
+ TEGRA_REVISION_MAX,
+};
+
+u32 tegra_read_straps(void);
u32 tegra_read_chipid(void);
+void tegra_init_fuse(void);
+extern int tegra_chip_id;
+extern enum tegra_revision tegra_revision;
+extern int tegra_bct_strapping;
#if defined(CONFIG_TEGRA20_APB_DMA)
int tegra_apb_readl_using_dma(unsigned long offset, u32 *value);
@@ -33,4 +55,7 @@ static inline int tegra_apb_writel_using_dma(u32 value, unsigned long offset)
return -EINVAL;
}
#endif
+
+#endif /* __ASSEMBLY__ */
+
#endif /* __LINUX_TEGRA_SOC_H_ */
--
1.7.7.rc0.72.g4b5ea.dirty
^ permalink raw reply related
* [PATCH v3 1/6] ARM: tegra: export apb dma readl/writel
From: Peter De Schrijver @ 2014-01-28 23:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390952176-30402-1-git-send-email-pdeschrijver@nvidia.com>
Export APB DMA readl and writel. These are needed because we can't access
the fuses directly on Tegra20 without potentially causing a system hang.
Also have the APB DMA readl and writel return an error in case of a read
failure instead of just returning zero or ignore write failures.
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
arch/arm/mach-tegra/apbio.c | 51 ++++++++++++++++++++++++++----------------
include/linux/tegra-soc.h | 14 +++++++++++
2 files changed, 45 insertions(+), 20 deletions(-)
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
index bc47197..e0bf49d 100644
--- a/arch/arm/mach-tegra/apbio.c
+++ b/arch/arm/mach-tegra/apbio.c
@@ -32,8 +32,8 @@ static u32 *tegra_apb_bb;
static dma_addr_t tegra_apb_bb_phys;
static DECLARE_COMPLETION(tegra_apb_wait);
-static u32 tegra_apb_readl_direct(unsigned long offset);
-static void tegra_apb_writel_direct(u32 value, unsigned long offset);
+static int tegra_apb_readl_direct(unsigned long offset, u32 *value);
+static int tegra_apb_writel_direct(u32 value, unsigned long offset);
static struct dma_chan *tegra_apb_dma_chan;
static struct dma_slave_config dma_sconfig;
@@ -128,58 +128,64 @@ static int do_dma_transfer(unsigned long apb_add,
return 0;
}
-static u32 tegra_apb_readl_using_dma(unsigned long offset)
+int tegra_apb_readl_using_dma(unsigned long offset, u32 *value)
{
int ret;
if (!tegra_apb_dma_chan && !tegra_apb_dma_init())
- return tegra_apb_readl_direct(offset);
+ return tegra_apb_readl_direct(offset, value);
mutex_lock(&tegra_apb_dma_lock);
ret = do_dma_transfer(offset, DMA_DEV_TO_MEM);
- if (ret < 0) {
+ if (ret < 0)
pr_err("error in reading offset 0x%08lx using dma\n", offset);
- *(u32 *)tegra_apb_bb = 0;
- }
+ else
+ *value = *tegra_apb_bb;
+
mutex_unlock(&tegra_apb_dma_lock);
- return *((u32 *)tegra_apb_bb);
+
+ return ret;
}
-static void tegra_apb_writel_using_dma(u32 value, unsigned long offset)
+int tegra_apb_writel_using_dma(u32 value, unsigned long offset)
{
int ret;
- if (!tegra_apb_dma_chan && !tegra_apb_dma_init()) {
- tegra_apb_writel_direct(value, offset);
- return;
- }
+ if (!tegra_apb_dma_chan && !tegra_apb_dma_init())
+ return tegra_apb_writel_direct(value, offset);
mutex_lock(&tegra_apb_dma_lock);
*((u32 *)tegra_apb_bb) = value;
ret = do_dma_transfer(offset, DMA_MEM_TO_DEV);
+ mutex_unlock(&tegra_apb_dma_lock);
if (ret < 0)
pr_err("error in writing offset 0x%08lx using dma\n", offset);
- mutex_unlock(&tegra_apb_dma_lock);
+
+ return ret;
}
#else
#define tegra_apb_readl_using_dma tegra_apb_readl_direct
#define tegra_apb_writel_using_dma tegra_apb_writel_direct
#endif
-typedef u32 (*apbio_read_fptr)(unsigned long offset);
-typedef void (*apbio_write_fptr)(u32 value, unsigned long offset);
+typedef int (*apbio_read_fptr)(unsigned long offset, u32 *value);
+typedef int (*apbio_write_fptr)(u32 value, unsigned long offset);
static apbio_read_fptr apbio_read;
static apbio_write_fptr apbio_write;
-static u32 tegra_apb_readl_direct(unsigned long offset)
+static int tegra_apb_readl_direct(unsigned long offset, u32 *value)
{
- return readl(IO_ADDRESS(offset));
+ *value = readl(IO_ADDRESS(offset));
+
+ return 0;
}
-static void tegra_apb_writel_direct(u32 value, unsigned long offset)
+static int tegra_apb_writel_direct(u32 value, unsigned long offset)
{
writel(value, IO_ADDRESS(offset));
+
+ return 0;
}
void tegra_apb_io_init(void)
@@ -197,7 +203,12 @@ void tegra_apb_io_init(void)
u32 tegra_apb_readl(unsigned long offset)
{
- return apbio_read(offset);
+ u32 val;
+
+ if (apbio_read(offset, &val) < 0)
+ return 0;
+ else
+ return val;
}
void tegra_apb_writel(u32 value, unsigned long offset)
diff --git a/include/linux/tegra-soc.h b/include/linux/tegra-soc.h
index 95f611d..b02d73b 100644
--- a/include/linux/tegra-soc.h
+++ b/include/linux/tegra-soc.h
@@ -19,4 +19,18 @@
u32 tegra_read_chipid(void);
+
+#if defined(CONFIG_TEGRA20_APB_DMA)
+int tegra_apb_readl_using_dma(unsigned long offset, u32 *value);
+int tegra_apb_writel_using_dma(u32 value, unsigned long offset);
+#else
+static inline int tegra_apb_readl_using_dma(unsigned long offset, u32 *value)
+{
+ return -EINVAL;
+}
+static inline int tegra_apb_writel_using_dma(u32 value, unsigned long offset)
+{
+ return -EINVAL;
+}
+#endif
#endif /* __LINUX_TEGRA_SOC_H_ */
--
1.7.7.rc0.72.g4b5ea.dirty
^ permalink raw reply related
* [PATCH v3 0/6] efuse driver for Tegra
From: Peter De Schrijver @ 2014-01-28 23:36 UTC (permalink / raw)
To: linux-arm-kernel
This driver allows userspace to read the raw efuse data. Its userspace
interface is modelled after the sunxi_sid driver which provides similar
functionality for some Allwinner SoCs. It has been tested on
Tegra20 (ventana), Tegra30 (beaverboard) and Tegra114 (dalmore).
Changes since v1:
* Add documentation for sysfs interface
* Cleanup messages
Changes since v2:
* Incorporate early fuse code
* Remove module support
* Make driver always build when Tegra platform is selected
* Add DT binding document
* Address comments on v2
TODO:
* test on Tegra124 (venice2)
Peter De Schrijver (6):
ARM: tegra: export apb dma readl/writel
ARM: tegra: Add chipid, revision and fuse init
misc: fuse: Add efuse driver for Tegra
ARM: tegra: Add efuse bindings
misc: enable fuse drivers
ARM: tegra: remove fuse files from mach-tegra
Documentation/ABI/testing/sysfs-driver-tegra-fuse | 8 +
.../devicetree/bindings/fuse/fuse-tegra.txt | 32 +++
arch/arm/boot/dts/tegra114.dtsi | 7 +
arch/arm/boot/dts/tegra124.dtsi | 7 +
arch/arm/boot/dts/tegra20.dtsi | 7 +
arch/arm/boot/dts/tegra30.dtsi | 7 +
arch/arm/mach-tegra/Makefile | 4 -
arch/arm/mach-tegra/apbio.c | 51 ++--
arch/arm/mach-tegra/cpuidle.c | 2 +-
arch/arm/mach-tegra/flowctrl.c | 2 +-
arch/arm/mach-tegra/fuse.c | 252 -----------------
arch/arm/mach-tegra/fuse.h | 79 ------
arch/arm/mach-tegra/hotplug.c | 2 +-
arch/arm/mach-tegra/platsmp.c | 2 +-
arch/arm/mach-tegra/pm.c | 2 +-
arch/arm/mach-tegra/pmc.c | 2 +-
arch/arm/mach-tegra/powergate.c | 2 +-
arch/arm/mach-tegra/reset-handler.S | 2 +-
arch/arm/mach-tegra/reset.c | 2 +-
arch/arm/mach-tegra/sleep-tegra30.S | 2 +-
arch/arm/mach-tegra/tegra.c | 2 +-
arch/arm/mach-tegra/tegra114_speedo.c | 104 -------
arch/arm/mach-tegra/tegra20_speedo.c | 109 --------
arch/arm/mach-tegra/tegra2_emc.c | 2 +-
arch/arm/mach-tegra/tegra30_speedo.c | 292 -------------------
drivers/misc/Makefile | 1 +
drivers/misc/fuse/Makefile | 1 +
drivers/misc/fuse/tegra/Makefile | 7 +
drivers/misc/fuse/tegra/fuse-tegra.c | 228 +++++++++++++++
drivers/misc/fuse/tegra/fuse-tegra20.c | 136 +++++++++
drivers/misc/fuse/tegra/fuse-tegra30.c | 178 ++++++++++++
drivers/misc/fuse/tegra/fuse.h | 82 ++++++
drivers/misc/fuse/tegra/tegra114_speedo.c | 110 ++++++++
drivers/misc/fuse/tegra/tegra124_speedo.c | 164 +++++++++++
drivers/misc/fuse/tegra/tegra20_speedo.c | 110 ++++++++
drivers/misc/fuse/tegra/tegra30_speedo.c | 294 ++++++++++++++++++++
include/linux/tegra-soc.h | 39 +++
37 files changed, 1461 insertions(+), 872 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-driver-tegra-fuse
create mode 100644 Documentation/devicetree/bindings/fuse/fuse-tegra.txt
delete mode 100644 arch/arm/mach-tegra/fuse.c
delete mode 100644 arch/arm/mach-tegra/fuse.h
delete mode 100644 arch/arm/mach-tegra/tegra114_speedo.c
delete mode 100644 arch/arm/mach-tegra/tegra20_speedo.c
delete mode 100644 arch/arm/mach-tegra/tegra30_speedo.c
create mode 100644 drivers/misc/fuse/Makefile
create mode 100644 drivers/misc/fuse/tegra/Makefile
create mode 100644 drivers/misc/fuse/tegra/fuse-tegra.c
create mode 100644 drivers/misc/fuse/tegra/fuse-tegra20.c
create mode 100644 drivers/misc/fuse/tegra/fuse-tegra30.c
create mode 100644 drivers/misc/fuse/tegra/fuse.h
create mode 100644 drivers/misc/fuse/tegra/tegra114_speedo.c
create mode 100644 drivers/misc/fuse/tegra/tegra124_speedo.c
create mode 100644 drivers/misc/fuse/tegra/tegra20_speedo.c
create mode 100644 drivers/misc/fuse/tegra/tegra30_speedo.c
--
1.7.7.rc0.72.g4b5ea.dirty
^ permalink raw reply
* [RFC/PATCH] ARM: vDSO gettimeofday using generic timer architecture
From: Nathan Lynch @ 2014-01-28 21:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140128212245.GQ15937@n2100.arm.linux.org.uk>
On 01/28/2014 03:22 PM, Russell King - ARM Linux wrote:
> On Tue, Jan 28, 2014 at 03:06:53PM -0600, Nathan Lynch wrote:
>> +static union {
>> + struct vdso_data data;
>> + u8 page[PAGE_SIZE];
>> +} vdso_data_store __page_aligned_data;
>> +struct vdso_data *vdso_data = &vdso_data_store.data;
>
> So this is in the kernel data segment.
>
>> +void update_vsyscall(struct timekeeper *tk)
>> +{
>> + struct timespec xtime_coarse;
>> + struct timespec wall_time = tk_xtime(tk);
>> + struct timespec *wtm = &tk->wall_to_monotonic;
>> + u32 use_syscall = strcmp(tk->clock->name, "arch_sys_counter");
>> +
>> + ++vdso_data->tb_seq_count;
>> + smp_wmb();
>> +
>> + xtime_coarse = __current_kernel_time();
>> + vdso_data->use_syscall = use_syscall;
>> + vdso_data->xtime_coarse_sec = xtime_coarse.tv_sec;
>> + vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec;
>> +
>> + if (!use_syscall) {
>> + vdso_data->cs_cycle_last = tk->clock->cycle_last;
>> + vdso_data->xtime_clock_sec = wall_time.tv_sec;
>> + vdso_data->xtime_clock_nsec = wall_time.tv_nsec;
>> + vdso_data->cs_mult = tk->mult;
>> + vdso_data->cs_shift = tk->shift;
>> + vdso_data->wtm_clock_sec = wtm->tv_sec;
>> + vdso_data->wtm_clock_nsec = wtm->tv_nsec;
>> + }
>> +
>> + smp_wmb();
>> + ++vdso_data->tb_seq_count;
>> +}
>> +
>> +void update_vsyscall_tz(void)
>> +{
>> + vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
>> + vdso_data->tz_dsttime = sys_tz.tz_dsttime;
>> +}
>
> which gets written to directly, and read from userspace. This won't work
> with aliasing caches, of which we have VIVT caches on all ARMv4 and ARMv5
> CPUs, and VIPT caches on some ARMv6.
>
> Either this needs to be limited to just VIPT nonaliasing caches, or it
> needs cache handling.
Thanks, I will address this.
>
> The above also looks rather unsafe from the SMP perspective - how does
> vdso_data->tb_seq_count protect this data between CPUs?
It doesn't -- it merely provides a mechanism for signaling the
consistency of the data userspace reads from the page. It's basically a
seqlock.
Looks like timekeeper_lock in kernel/time/timekeeping.c prevents
concurrent calls to update_vsyscall. I could document that dependency...
^ permalink raw reply
* Marvell Driver for SD8797
From: John Tobias @ 2014-01-28 21:33 UTC (permalink / raw)
To: linux-arm-kernel
Hello all,
Does anyone using the Marvell SD8797 here?. I tested both the
opensource and the proprietary driver of Marvell for suspend mode (S3)
on iMX6SL board running 3.13 kernel.
In opensource, the driver were able to suspend/resume and able to keep
the IP address and SSID as well, which is good.
In proprietary driver, the driver were able to suspend/resume and able
to keep the IP address but, not the SSID.
Any idea?.
Regards,
john
^ permalink raw reply
* [PATCH v2] ARM: mm: Fix stage-2 device memory attributes
From: Christoffer Dall @ 2014-01-28 21:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140127172116.GD8358@arm.com>
On Mon, Jan 27, 2014 at 05:21:16PM +0000, Catalin Marinas wrote:
> On Mon, Jan 27, 2014 at 05:02:25PM +0000, Marc Zyngier wrote:
> > On 27/01/14 16:57, Catalin Marinas wrote:
> > > On Mon, Jan 27, 2014 at 11:16:57AM +0000, Marc Zyngier wrote:
> > >> On 24/01/14 23:37, Christoffer Dall wrote:
> > >>> On Sat, Jan 04, 2014 at 08:27:23AM -0800, Christoffer Dall wrote:
> > >>>> --- a/arch/arm/include/asm/pgtable-3level.h
> > >>>> +++ b/arch/arm/include/asm/pgtable-3level.h
> > >>>> @@ -120,13 +120,19 @@
> > >>>> /*
> > >>>> * 2nd stage PTE definitions for LPAE.
> > >>>> */
> > >>>> -#define L_PTE_S2_MT_UNCACHED (_AT(pteval_t, 0x5) << 2) /* MemAttr[3:0] */
> > >>>> -#define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) << 2) /* MemAttr[3:0] */
> > >>>> -#define L_PTE_S2_MT_WRITEBACK (_AT(pteval_t, 0xf) << 2) /* MemAttr[3:0] */
> > >>>> -#define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */
> > >>>> -#define L_PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */
> > >>>> -
> > >>>> -#define L_PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */
> > >>>> +#define L_PTE_S2_MT_UNCACHED (_AT(pteval_t, 0x0) << 2) /* strongly ordered */
> > >>>> +#define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) << 2) /* normal inner write-through */
> > >>>> +#define L_PTE_S2_MT_WRITEBACK (_AT(pteval_t, 0xf) << 2) /* normal inner write-back */
> > >>>> +#define L_PTE_S2_MT_DEV_SHARED (_AT(pteval_t, 0x1) << 2) /* device */
> > >>>> +#define L_PTE_S2_MT_DEV_NONSHARED (_AT(pteval_t, 0x1) << 2) /* device */
> > >>>> +#define L_PTE_S2_MT_DEV_WC (_AT(pteval_t, 0x5) << 2) /* normal non-cacheable */
> > >>>> +#define L_PTE_S2_MT_DEV_CACHED (_AT(pteval_t, 0xf) << 2) /* normal inner write-back */
> > >>>> +#define L_PTE_S2_MT_MASK (_AT(pteval_t, 0xf) << 2)
> > >>>> +
> > >>>> +#define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */
> > >>>> +#define L_PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */
> > >>>> +
> > >>>> +#define L_PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */
> > >>>>
> > >>>> /*
> > >>>> * Hyp-mode PL2 PTE definitions for LPAE.
> > >>
> > >> The change makes sense to me. arm64 uses a slightly different approach,
> > >> by using a PTE_S2_MEMATTR macro, but I'm not sure that would work for ARM.
> > >>
> > >> Russell, Catalin: could you please have a look at this?
> > >
> > > Do we actually need more than Normal Cacheable and Device for stage 2?
> >
> > Not so far. As long as these two memory types are enforced as a minimum,
> > we're quite happy to let the guest use whatever it decides.
> >
> > I suppose Christoffer introduces them all here as a matter of
> > completeness, but I don't see them as being useful anytime soon.
>
> That would be useful on arm if you want cachepolicy= argument to force
> the cacheability of guest Normal memory type.
>
> On arm64, the stage 1 memory type is decided via MAIR and that's how we
> handle cachepolicy for Normal memory. But for stage 2 this won't work,
> the type is explicitly set in the MemAttr encoding. But I don't think we
> need host cachepolicy enforced onto guest.
>
ok, sent out a V2. Thanks for the comments.
-Christoffer
^ permalink raw reply
* [PATCH v2] ARM: mm: Fix stage-2 device memory attributes
From: Christoffer Dall @ 2014-01-28 21:24 UTC (permalink / raw)
To: linux-arm-kernel
The stage-2 memory attributes are distinct from the Hyp memory
attributes and the Stage-1 memory attributes. We were using the stage-1
memory attributes for stage-2 mappings causing device mappings to be
mapped as normal memory. Add the S2 equivalent defines for memory
attributes and fix the comments explaining the defines while at it.
Add a prot_pte_s2 field to the mem_type struct and fill out the field
for device mappings accordingly.
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
Changes [v1 -> v2]:
- Only define stage 2 protection flag for MT_DEVICE memory type.
arch/arm/include/asm/pgtable-3level.h | 15 +++++++++------
arch/arm/mm/mm.h | 1 +
arch/arm/mm/mmu.c | 7 ++++++-
3 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index 4f95039..1d15673 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -120,13 +120,16 @@
/*
* 2nd stage PTE definitions for LPAE.
*/
-#define L_PTE_S2_MT_UNCACHED (_AT(pteval_t, 0x5) << 2) /* MemAttr[3:0] */
-#define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) << 2) /* MemAttr[3:0] */
-#define L_PTE_S2_MT_WRITEBACK (_AT(pteval_t, 0xf) << 2) /* MemAttr[3:0] */
-#define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */
-#define L_PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */
+#define L_PTE_S2_MT_UNCACHED (_AT(pteval_t, 0x0) << 2) /* strongly ordered */
+#define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) << 2) /* normal inner write-through */
+#define L_PTE_S2_MT_WRITEBACK (_AT(pteval_t, 0xf) << 2) /* normal inner write-back */
+#define L_PTE_S2_MT_DEV_SHARED (_AT(pteval_t, 0x1) << 2) /* device */
+#define L_PTE_S2_MT_MASK (_AT(pteval_t, 0xf) << 2)
-#define L_PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */
+#define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */
+#define L_PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */
+
+#define L_PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */
/*
* Hyp-mode PL2 PTE definitions for LPAE.
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index d5a982d..7ea641b 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -38,6 +38,7 @@ static inline pmd_t *pmd_off_k(unsigned long virt)
struct mem_type {
pteval_t prot_pte;
+ pteval_t prot_pte_s2;
pmdval_t prot_l1;
pmdval_t prot_sect;
unsigned int domain;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 580ef2d..911d433 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -231,12 +231,16 @@ __setup("noalign", noalign_setup);
#endif /* ifdef CONFIG_CPU_CP15 / else */
#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN
+#define PROT_PTE_S2_DEVICE PROT_PTE_DEVICE
#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE
static struct mem_type mem_types[] = {
[MT_DEVICE] = { /* Strongly ordered / ARMv6 shared device */
.prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_SHARED |
L_PTE_SHARED,
+ .prot_pte_s2 = s2_policy(PROT_PTE_S2_DEVICE) |
+ s2_policy(L_PTE_S2_MT_DEV_SHARED) |
+ L_PTE_SHARED,
.prot_l1 = PMD_TYPE_TABLE,
.prot_sect = PROT_SECT_DEVICE | PMD_SECT_S,
.domain = DOMAIN_IO,
@@ -458,7 +462,8 @@ static void __init build_mem_type_table(void)
cp = &cache_policies[cachepolicy];
vecs_pgprot = kern_pgprot = user_pgprot = cp->pte;
s2_pgprot = cp->pte_s2;
- hyp_device_pgprot = s2_device_pgprot = mem_types[MT_DEVICE].prot_pte;
+ hyp_device_pgprot = mem_types[MT_DEVICE].prot_pte;
+ s2_device_pgprot = mem_types[MT_DEVICE].prot_pte_s2;
/*
* ARMv6 and above have extended page tables.
--
1.8.5.2
^ permalink raw reply related
* [RFC/PATCH] ARM: vDSO gettimeofday using generic timer architecture
From: Russell King - ARM Linux @ 2014-01-28 21:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390943213-5698-1-git-send-email-nathan_lynch@mentor.com>
On Tue, Jan 28, 2014 at 03:06:53PM -0600, Nathan Lynch wrote:
> +static union {
> + struct vdso_data data;
> + u8 page[PAGE_SIZE];
> +} vdso_data_store __page_aligned_data;
> +struct vdso_data *vdso_data = &vdso_data_store.data;
So this is in the kernel data segment.
> +void update_vsyscall(struct timekeeper *tk)
> +{
> + struct timespec xtime_coarse;
> + struct timespec wall_time = tk_xtime(tk);
> + struct timespec *wtm = &tk->wall_to_monotonic;
> + u32 use_syscall = strcmp(tk->clock->name, "arch_sys_counter");
> +
> + ++vdso_data->tb_seq_count;
> + smp_wmb();
> +
> + xtime_coarse = __current_kernel_time();
> + vdso_data->use_syscall = use_syscall;
> + vdso_data->xtime_coarse_sec = xtime_coarse.tv_sec;
> + vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec;
> +
> + if (!use_syscall) {
> + vdso_data->cs_cycle_last = tk->clock->cycle_last;
> + vdso_data->xtime_clock_sec = wall_time.tv_sec;
> + vdso_data->xtime_clock_nsec = wall_time.tv_nsec;
> + vdso_data->cs_mult = tk->mult;
> + vdso_data->cs_shift = tk->shift;
> + vdso_data->wtm_clock_sec = wtm->tv_sec;
> + vdso_data->wtm_clock_nsec = wtm->tv_nsec;
> + }
> +
> + smp_wmb();
> + ++vdso_data->tb_seq_count;
> +}
> +
> +void update_vsyscall_tz(void)
> +{
> + vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
> + vdso_data->tz_dsttime = sys_tz.tz_dsttime;
> +}
which gets written to directly, and read from userspace. This won't work
with aliasing caches, of which we have VIVT caches on all ARMv4 and ARMv5
CPUs, and VIPT caches on some ARMv6.
Either this needs to be limited to just VIPT nonaliasing caches, or it
needs cache handling.
The above also looks rather unsafe from the SMP perspective - how does
vdso_data->tb_seq_count protect this data between CPUs?
--
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
* [RFC/PATCH] ARM: vDSO gettimeofday using generic timer architecture
From: Nathan Lynch @ 2014-01-28 21:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390926308-15581-1-git-send-email-steve.capper@linaro.org>
Provide fast userspace implementations of gettimeofday and
clock_gettime on systems that implement the generic timers extension
defined in ARMv7. This follows the example of arm64 in conception but
significantly differs in some aspects of the implementation (C vs
assembly, mainly).
Clocks supported:
- CLOCK_REALTIME
- CLOCK_MONOTONIC
- CLOCK_REALTIME_COARSE
- CLOCK_MONOTONIC_COARSE
This also provides clock_getres (as arm64 does).
Tested on OMAP5 UEVM (Cortex A15) using a LD_PRELOAD shim to redirect
system calls to the vDSO. I plan to undertake adding proper support
to glibc if the overall approach is acceptable.
Note that while the high-precision realtime and monotonic clock
support depends on the generic timers extension, support for
clock_getres and (I think) the coarse clocks is pretty much
independent of the timer implementation in use and could be provided
unconditionally.
I also hope to add getcpu to the vDSO, using something like
TPIDRURO/TPIDRURW (although I believe these registers are claimed for
other uses already -- suggestions welcome).
This is RFC-quality code at the moment -- I haven't tested this on a
system lacking generic timers, nor have I done much build testing.
I'm sure there is plenty of room for improvement.
Based on linux-next 20140124.
---
arch/arm/Kconfig | 1 +
arch/arm/include/asm/arch_timer.h | 7 +-
arch/arm/include/asm/auxvec.h | 7 +
arch/arm/include/asm/elf.h | 6 +
arch/arm/include/asm/mmu.h | 1 +
arch/arm/include/asm/vdso.h | 26 +++
arch/arm/include/asm/vdso_datapage.h | 45 ++++++
arch/arm/kernel/Makefile | 3 +-
arch/arm/kernel/process.c | 16 +-
arch/arm/kernel/vdso.c | 157 ++++++++++++++++++
arch/arm/kernel/vdso/.gitignore | 2 +
arch/arm/kernel/vdso/Makefile | 46 ++++++
arch/arm/kernel/vdso/vdso.S | 35 ++++
arch/arm/kernel/vdso/vdso.lds.S | 93 +++++++++++
arch/arm/kernel/vdso/vgettimeofday.c | 303 +++++++++++++++++++++++++++++++++++
15 files changed, 742 insertions(+), 6 deletions(-)
create mode 100644 arch/arm/include/asm/auxvec.h
create mode 100644 arch/arm/include/asm/vdso.h
create mode 100644 arch/arm/include/asm/vdso_datapage.h
create mode 100644 arch/arm/kernel/vdso.c
create mode 100644 arch/arm/kernel/vdso/.gitignore
create mode 100644 arch/arm/kernel/vdso/Makefile
create mode 100644 arch/arm/kernel/vdso/vdso.S
create mode 100644 arch/arm/kernel/vdso/vdso.lds.S
create mode 100644 arch/arm/kernel/vdso/vgettimeofday.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index dc6ef9a2c649..c9f69d059c76 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -23,6 +23,7 @@ config ARM
select GENERIC_SMP_IDLE_THREAD
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
+ select GENERIC_TIME_VSYSCALL
select HARDIRQS_SW_RESEND
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
select HAVE_ARCH_KGDB
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index 30cc2fb09416..80f24827af94 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -102,13 +102,16 @@ static inline void arch_counter_set_user_access(void)
{
u32 cntkctl = arch_timer_get_cntkctl();
- /* Disable user access to both physical/virtual counters/timers */
+ /* Disable user access to the timers and the physical counter */
/* Also disable virtual event stream */
cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
| ARCH_TIMER_USR_VT_ACCESS_EN
| ARCH_TIMER_VIRT_EVT_EN
- | ARCH_TIMER_USR_VCT_ACCESS_EN
| ARCH_TIMER_USR_PCT_ACCESS_EN);
+
+ /* Enable user access to the virtual counter */
+ cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
+
arch_timer_set_cntkctl(cntkctl);
}
diff --git a/arch/arm/include/asm/auxvec.h b/arch/arm/include/asm/auxvec.h
new file mode 100644
index 000000000000..f56936b97ec2
--- /dev/null
+++ b/arch/arm/include/asm/auxvec.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_AUXVEC_H
+#define __ASM_AUXVEC_H
+
+/* vDSO location */
+#define AT_SYSINFO_EHDR 33
+
+#endif
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index f4b46d39b9cf..b8d099264000 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -1,6 +1,7 @@
#ifndef __ASMARM_ELF_H
#define __ASMARM_ELF_H
+#include <asm/auxvec.h>
#include <asm/hwcap.h>
/*
@@ -129,6 +130,11 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
#define arch_randomize_brk arch_randomize_brk
#ifdef CONFIG_MMU
+#define ARCH_DLINFO \
+do { \
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, \
+ (elf_addr_t)current->mm->context.vdso); \
+} while (0)
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
struct linux_binprm;
int arch_setup_additional_pages(struct linux_binprm *, int);
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index 64fd15159b7d..1ee0f42a3b26 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -11,6 +11,7 @@ typedef struct {
#endif
unsigned int vmalloc_seq;
unsigned long sigpage;
+ unsigned long vdso;
} mm_context_t;
#ifdef CONFIG_CPU_HAS_ASID
diff --git a/arch/arm/include/asm/vdso.h b/arch/arm/include/asm/vdso.h
new file mode 100644
index 000000000000..ab080bbc4acf
--- /dev/null
+++ b/arch/arm/include/asm/vdso.h
@@ -0,0 +1,26 @@
+#ifndef __ASM_VDSO_H
+#define __ASM_VDSO_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#include <linux/mm_types.h>
+#include <asm/mmu.h>
+
+static inline bool vma_is_vdso(struct vm_area_struct *vma)
+{
+ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
+ return true;
+ return false;
+}
+
+void arm_install_vdso(void);
+
+#endif /* __ASSEMBLY__ */
+
+#define VDSO_LBASE 0x0
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_VDSO_H */
diff --git a/arch/arm/include/asm/vdso_datapage.h b/arch/arm/include/asm/vdso_datapage.h
new file mode 100644
index 000000000000..e55358c1d565
--- /dev/null
+++ b/arch/arm/include/asm/vdso_datapage.h
@@ -0,0 +1,45 @@
+/*
+ * Adapted from arm64 version.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * 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 __ASM_VDSO_DATAPAGE_H
+#define __ASM_VDSO_DATAPAGE_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+struct vdso_data {
+ __u64 cs_cycle_last; /* Timebase at clocksource init */
+ __u32 xtime_clock_sec; /* Kernel time */
+ __u32 xtime_clock_nsec;
+ __u32 xtime_coarse_sec; /* Coarse time */
+ __u32 xtime_coarse_nsec;
+ __u32 wtm_clock_sec; /* Wall to monotonic time */
+ __u32 wtm_clock_nsec;
+ __u32 tb_seq_count; /* Timebase sequence counter */
+ __u32 cs_mult; /* Clocksource multiplier */
+ __u32 cs_shift; /* Clocksource shift */
+ __u32 tz_minuteswest; /* Whacky timezone stuff */
+ __u32 tz_dsttime;
+ __u32 use_syscall;
+};
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_VDSO_DATAPAGE_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index a30fc9be9e9e..9e785550b307 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -18,7 +18,8 @@ CFLAGS_REMOVE_return_address.o = -pg
obj-y := elf.o entry-common.o irq.o opcodes.o \
process.o ptrace.o return_address.o \
setup.o signal.o sigreturn_codes.o \
- stacktrace.o sys_arm.o time.o traps.o
+ stacktrace.o sys_arm.o time.o traps.o \
+ vdso.o vdso/
obj-$(CONFIG_ATAGS) += atags_parse.o
obj-$(CONFIG_ATAGS_PROC) += atags_proc.o
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 92f7b15dd221..9907227adf92 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -41,6 +41,7 @@
#include <asm/stacktrace.h>
#include <asm/mach/time.h>
#include <asm/tls.h>
+#include <asm/vdso.h>
#ifdef CONFIG_CC_STACKPROTECTOR
#include <linux/stackprotector.h>
@@ -472,9 +473,16 @@ int in_gate_area_no_mm(unsigned long addr)
const char *arch_vma_name(struct vm_area_struct *vma)
{
- return is_gate_vma(vma) ? "[vectors]" :
- (vma->vm_mm && vma->vm_start == vma->vm_mm->context.sigpage) ?
- "[sigpage]" : NULL;
+ if (is_gate_vma(vma))
+ return "[vectors]";
+
+ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.sigpage)
+ return "[sigpage]";
+
+ if (vma_is_vdso(vma))
+ return "[vdso]";
+
+ return NULL;
}
static struct page *signal_page;
@@ -505,6 +513,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
if (ret == 0)
mm->context.sigpage = addr;
+ arm_install_vdso();
+
up_fail:
up_write(&mm->mmap_sem);
return ret;
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
new file mode 100644
index 000000000000..82ffb77df861
--- /dev/null
+++ b/arch/arm/kernel/vdso.c
@@ -0,0 +1,157 @@
+/*
+ * Adapted from arm64 version.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * 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/err.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/timekeeper_internal.h>
+#include <linux/vmalloc.h>
+
+#include <asm/page.h>
+#include <asm/vdso.h>
+#include <asm/vdso_datapage.h>
+
+extern char vdso_start, vdso_end;
+
+static unsigned long vdso_pages;
+static struct page **vdso_pagelist;
+
+static union {
+ struct vdso_data data;
+ u8 page[PAGE_SIZE];
+} vdso_data_store __page_aligned_data;
+struct vdso_data *vdso_data = &vdso_data_store.data;
+
+/*
+ * The vDSO data page.
+ */
+
+static int __init vdso_init(void)
+{
+ struct page *pg;
+ char *vbase;
+ int i, ret = 0;
+
+ vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
+ pr_info("vdso: %ld pages (%ld code, %ld data) at base %p\n",
+ vdso_pages + 1, vdso_pages, 1L, &vdso_start);
+
+ /* Allocate the vDSO pagelist, plus a page for the data. */
+ vdso_pagelist = kzalloc(sizeof(struct page *) * (vdso_pages + 1),
+ GFP_KERNEL);
+ if (vdso_pagelist == NULL) {
+ pr_err("Failed to allocate vDSO pagelist!\n");
+ return -ENOMEM;
+ }
+
+ /* Grab the vDSO code pages. */
+ for (i = 0; i < vdso_pages; i++) {
+ pg = virt_to_page(&vdso_start + i*PAGE_SIZE);
+ ClearPageReserved(pg);
+ get_page(pg);
+ vdso_pagelist[i] = pg;
+ }
+
+ /* Sanity check the shared object header. */
+ vbase = vmap(vdso_pagelist, 1, 0, PAGE_KERNEL);
+ if (vbase == NULL) {
+ pr_err("Failed to map vDSO pagelist!\n");
+ return -ENOMEM;
+ } else if (memcmp(vbase, "\177ELF", 4)) {
+ pr_err("vDSO is not a valid ELF object!\n");
+ ret = -EINVAL;
+ goto unmap;
+ }
+
+ /* Grab the vDSO data page. */
+ pg = virt_to_page(vdso_data);
+ get_page(pg);
+ vdso_pagelist[i] = pg;
+
+unmap:
+ vunmap(vbase);
+ return ret;
+}
+arch_initcall(vdso_init);
+
+/* assumes mmap_sem is write-locked */
+void arm_install_vdso(void)
+{
+ struct mm_struct *mm = current->mm;
+ unsigned long vdso_base, vdso_mapping_len;
+ int ret;
+
+ /* Be sure to map the data page */
+ vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
+
+ vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
+ if (IS_ERR_VALUE(vdso_base)) {
+ pr_notice_once("%s: get_unapped_area failed (%ld)\n",
+ __func__, (long)vdso_base);
+ ret = vdso_base;
+ return;
+ }
+ mm->context.vdso = vdso_base;
+
+ ret = install_special_mapping(mm, vdso_base, vdso_mapping_len,
+ VM_READ|VM_EXEC|
+ VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
+ vdso_pagelist);
+ if (ret) {
+ pr_notice_once("%s: install_special_mapping failed (%d)\n",
+ __func__, ret);
+ mm->context.vdso = 0;
+ return;
+ }
+}
+
+void update_vsyscall(struct timekeeper *tk)
+{
+ struct timespec xtime_coarse;
+ struct timespec wall_time = tk_xtime(tk);
+ struct timespec *wtm = &tk->wall_to_monotonic;
+ u32 use_syscall = strcmp(tk->clock->name, "arch_sys_counter");
+
+ ++vdso_data->tb_seq_count;
+ smp_wmb();
+
+ xtime_coarse = __current_kernel_time();
+ vdso_data->use_syscall = use_syscall;
+ vdso_data->xtime_coarse_sec = xtime_coarse.tv_sec;
+ vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec;
+
+ if (!use_syscall) {
+ vdso_data->cs_cycle_last = tk->clock->cycle_last;
+ vdso_data->xtime_clock_sec = wall_time.tv_sec;
+ vdso_data->xtime_clock_nsec = wall_time.tv_nsec;
+ vdso_data->cs_mult = tk->mult;
+ vdso_data->cs_shift = tk->shift;
+ vdso_data->wtm_clock_sec = wtm->tv_sec;
+ vdso_data->wtm_clock_nsec = wtm->tv_nsec;
+ }
+
+ smp_wmb();
+ ++vdso_data->tb_seq_count;
+}
+
+void update_vsyscall_tz(void)
+{
+ vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
+ vdso_data->tz_dsttime = sys_tz.tz_dsttime;
+}
diff --git a/arch/arm/kernel/vdso/.gitignore b/arch/arm/kernel/vdso/.gitignore
new file mode 100644
index 000000000000..a4093e0671be
--- /dev/null
+++ b/arch/arm/kernel/vdso/.gitignore
@@ -0,0 +1,2 @@
+vdso.lds
+
diff --git a/arch/arm/kernel/vdso/Makefile b/arch/arm/kernel/vdso/Makefile
new file mode 100644
index 000000000000..cc2b42db840e
--- /dev/null
+++ b/arch/arm/kernel/vdso/Makefile
@@ -0,0 +1,46 @@
+obj-vdso := vgettimeofday.o
+
+# Build rules
+targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds
+obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
+
+ccflags-y := -shared -fPIC -fno-common -fno-builtin
+ccflags-y += -nostdlib -Wl,-soname=linux-vdso.so.1 \
+ $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+
+obj-y += vdso.o
+extra-y += vdso.lds
+CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
+
+CFLAGS_REMOVE_vdso.o = -pg
+CFLAGS_REMOVE_vgettimeofday.o = -pg
+
+# Disable gcov profiling for VDSO code
+GCOV_PROFILE := n
+
+# Force dependency
+$(obj)/vdso.o : $(obj)/vdso.so
+
+# Link rule for the .so file, .lds has to be first
+SYSCFLAGS_vdso.so.dbg = $(c_flags)
+$(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso)
+ $(call if_changed,vdsold)
+
+# Strip rule for the .so file
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+ $(call if_changed,objcopy)
+
+# Actual build commands
+quiet_cmd_vdsold = VDSOL $@
+ cmd_vdsold = $(CC) $(c_flags) -Wl,-T $^ -o $@
+
+# Install commands for the unstripped file
+quiet_cmd_vdso_install = INSTALL $@
+ cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
+
+vdso.so: $(obj)/vdso.so.dbg
+ @mkdir -p $(MODLIB)/vdso
+ $(call cmd,vdso_install)
+
+vdso_install: vdso.so
diff --git a/arch/arm/kernel/vdso/vdso.S b/arch/arm/kernel/vdso/vdso.S
new file mode 100644
index 000000000000..aed16ff84c5f
--- /dev/null
+++ b/arch/arm/kernel/vdso/vdso.S
@@ -0,0 +1,35 @@
+/*
+ * Adapted from arm64 version.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * 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/>.
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/const.h>
+#include <asm/page.h>
+
+ __PAGE_ALIGNED_DATA
+
+ .globl vdso_start, vdso_end
+ .balign PAGE_SIZE
+vdso_start:
+ .incbin "arch/arm/kernel/vdso/vdso.so"
+ .balign PAGE_SIZE
+vdso_end:
+
+ .previous
diff --git a/arch/arm/kernel/vdso/vdso.lds.S b/arch/arm/kernel/vdso/vdso.lds.S
new file mode 100644
index 000000000000..e16f8f6f08e1
--- /dev/null
+++ b/arch/arm/kernel/vdso/vdso.lds.S
@@ -0,0 +1,93 @@
+/*
+ * Adapted from arm64 version.
+ *
+ * GNU linker script for the VDSO library.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * 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/>.
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ * Heavily based on the vDSO linker scripts for other archs.
+ */
+
+#include <linux/const.h>
+#include <asm/page.h>
+#include <asm/vdso.h>
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+SECTIONS
+{
+ . = VDSO_LBASE + SIZEOF_HEADERS;
+
+ .hash : { *(.hash) } :text
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
+ .note : { *(.note.*) } :text :note
+
+ . = ALIGN(16);
+
+ .text : { *(.text*) } :text =0xd503201f
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+
+ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
+ .eh_frame : { KEEP (*(.eh_frame)) } :text
+
+ .dynamic : { *(.dynamic) } :text :dynamic
+
+ .rodata : { *(.rodata*) } :text
+
+ _end = .;
+ PROVIDE(end = .);
+
+ . = ALIGN(PAGE_SIZE);
+ PROVIDE(_vdso_data = .);
+
+ /DISCARD/ : {
+ *(.note.GNU-stack)
+ *(.data .data.* .gnu.linkonce.d.* .sdata*)
+ *(.bss .sbss .dynbss .dynsbss)
+ }
+}
+
+/*
+ * We must supply the ELF program headers explicitly to get just one
+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
+ */
+PHDRS
+{
+ text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ note PT_NOTE FLAGS(4); /* PF_R */
+ eh_frame_hdr PT_GNU_EH_FRAME;
+}
+
+VERSION
+{
+ LINUX_3.15 {
+ global:
+ __kernel_clock_getres;
+ __kernel_clock_gettime;
+ __kernel_gettimeofday;
+ local: *;
+ };
+}
diff --git a/arch/arm/kernel/vdso/vgettimeofday.c b/arch/arm/kernel/vdso/vgettimeofday.c
new file mode 100644
index 000000000000..1519283dc2e5
--- /dev/null
+++ b/arch/arm/kernel/vdso/vgettimeofday.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2014 Mentor Graphics 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; version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/compiler.h>
+#include <linux/hrtimer.h>
+#include <linux/time.h>
+#include <asm/arch_timer.h>
+#include <asm/barrier.h>
+#include <asm/unistd.h>
+#include <asm/vdso_datapage.h>
+
+extern struct vdso_data _vdso_data;
+
+static struct vdso_data *get_datapage(void)
+{
+ struct vdso_data *ret;
+
+ /* Hack to perform pc-relative load of data page */
+ asm("b 1f\n"
+ ".align 2\n"
+ "2:\n"
+ ".long _vdso_data - .\n"
+ "1:\n"
+ "adr r2, 2b\n"
+ "ldr r3, [r2]\n"
+ "add %0, r2, r3\n" :
+ "=r" (ret) : : "r2", "r3");
+
+ return ret;
+}
+
+static u32 seqcnt_acquire(struct vdso_data *vdata)
+{
+ u32 seq;
+
+ do {
+ seq = ACCESS_ONCE(vdata->tb_seq_count);
+ } while (seq & 1);
+
+ dmb(ish);
+
+ return seq;
+}
+
+static u32 seqcnt_read(struct vdso_data *vdata)
+{
+ dmb(ish);
+
+ return ACCESS_ONCE(vdata->tb_seq_count);
+}
+
+static long clock_gettime_fallback(clockid_t _clkid, struct timespec *_ts)
+{
+ register struct timespec *ts asm("r1") = _ts;
+ register clockid_t clkid asm("r0") = _clkid;
+ register long ret asm ("r0");
+ register long nr asm("r7") = __NR_clock_gettime;
+
+ asm("swi #0" : "=r" (ret) : "r" (clkid), "r" (ts), "r" (nr) : "memory");
+
+ return ret;
+}
+
+static int do_realtime_coarse(struct timespec *ts, struct vdso_data *vdata)
+{
+ struct timespec copy;
+ u32 seq;
+
+ do {
+ seq = seqcnt_acquire(vdata);
+
+ if (vdata->use_syscall)
+ return -1;
+
+ copy.tv_sec = vdata->xtime_coarse_sec;
+ copy.tv_nsec = vdata->xtime_coarse_nsec;
+ } while (seq != seqcnt_read(vdata));
+
+ *ts = copy;
+
+ return 0;
+}
+
+static int do_monotonic_coarse(struct timespec *ts, struct vdso_data *vdata)
+{
+ struct timespec copy;
+ struct timespec wtm;
+ u32 seq;
+
+ do {
+ seq = seqcnt_acquire(vdata);
+
+ if (vdata->use_syscall)
+ return -1;
+
+ copy.tv_sec = vdata->xtime_coarse_sec;
+ copy.tv_nsec = vdata->xtime_coarse_nsec;
+ wtm.tv_sec = vdata->wtm_clock_sec;
+ wtm.tv_nsec = vdata->wtm_clock_nsec;
+ } while (seq != seqcnt_read(vdata));
+
+ copy.tv_sec += wtm.tv_sec;
+ copy.tv_nsec += wtm.tv_nsec;
+ if (copy.tv_nsec >= NSEC_PER_SEC) {
+ copy.tv_nsec -= NSEC_PER_SEC;
+ copy.tv_sec += 1;
+ }
+
+ *ts = copy;
+
+ return 0;
+}
+
+static int do_realtime(struct timespec *ts, struct vdso_data *vdata)
+{
+ unsigned long sec;
+ u32 seq;
+ u64 ns;
+
+ do {
+ u64 cycles;
+
+ seq = seqcnt_acquire(vdata);
+
+ if (vdata->use_syscall)
+ return -1;
+
+ cycles = arch_counter_get_cntvct() - vdata->cs_cycle_last;
+
+ /* The generic timer architecture guarantees only 56 bits */
+ cycles &= ~(0xff00ULL << 48);
+ ns = (cycles * vdata->cs_mult) >> vdata->cs_shift;
+
+ sec = vdata->xtime_clock_sec;
+ ns += vdata->xtime_clock_nsec;
+
+ while (ns >= NSEC_PER_SEC) {
+ ns -= NSEC_PER_SEC;
+ sec += 1;
+ }
+ } while (seq != seqcnt_read(vdata));
+
+ ts->tv_sec = sec;
+ ts->tv_nsec = ns;
+
+ return 0;
+}
+
+static int do_monotonic(struct timespec *ts, struct vdso_data *vdata)
+{
+ unsigned long sec;
+ u32 seq;
+ u64 ns;
+
+ do {
+ u64 cycles;
+
+ seq = seqcnt_acquire(vdata);
+
+ if (vdata->use_syscall)
+ return -1;
+
+ cycles = arch_counter_get_cntvct() - vdata->cs_cycle_last;
+
+ /* The generic timer architecture guarantees only 56 bits */
+ cycles &= ~(0xff00ULL << 48);
+ ns = (cycles * vdata->cs_mult) >> vdata->cs_shift;
+
+ sec = vdata->xtime_clock_sec;
+ ns += vdata->xtime_clock_nsec;
+
+ sec += vdata->wtm_clock_sec;
+ ns += vdata->wtm_clock_nsec;
+
+ while (ns >= NSEC_PER_SEC) {
+ ns -= NSEC_PER_SEC;
+ sec += 1;
+ }
+ } while (seq != seqcnt_read(vdata));
+
+ ts->tv_sec = sec;
+ ts->tv_nsec = ns;
+
+ return 0;
+}
+
+int __kernel_clock_gettime(clockid_t clkid, struct timespec *ts)
+{
+ struct vdso_data *vdata;
+ int ret = -1;
+
+ vdata = get_datapage();
+
+ switch (clkid) {
+ case CLOCK_REALTIME_COARSE:
+ ret = do_realtime_coarse(ts, vdata);
+ break;
+ case CLOCK_MONOTONIC_COARSE:
+ ret = do_monotonic_coarse(ts, vdata);
+ break;
+ case CLOCK_REALTIME:
+ ret = do_realtime(ts, vdata);
+ break;
+ case CLOCK_MONOTONIC:
+ ret = do_monotonic(ts, vdata);
+ break;
+ default:
+ break;
+ }
+
+ if (ret)
+ ret = clock_gettime_fallback(clkid, ts);
+
+ return ret;
+}
+
+static long clock_getres_fallback(clockid_t _clkid, struct timespec *_ts)
+{
+ register struct timespec *ts asm("r1") = _ts;
+ register clockid_t clkid asm("r0") = _clkid;
+ register long ret asm ("r0");
+ register long nr asm("r7") = __NR_clock_getres;
+
+ asm volatile(
+ "swi #0" :
+ "=r" (ret) :
+ "r" (clkid), "r" (ts), "r" (nr) :
+ "memory");
+
+ return ret;
+}
+
+int __kernel_clock_getres(clockid_t clkid, struct timespec *ts)
+{
+ int ret;
+
+ switch (clkid) {
+ case CLOCK_REALTIME:
+ case CLOCK_MONOTONIC:
+ if (ts) {
+ ts->tv_sec = 0;
+ ts->tv_nsec = MONOTONIC_RES_NSEC;
+ }
+ ret = 0;
+ break;
+ case CLOCK_REALTIME_COARSE:
+ case CLOCK_MONOTONIC_COARSE:
+ if (ts) {
+ ts->tv_sec = 0;
+ ts->tv_nsec = LOW_RES_NSEC;
+ }
+ ret = 0;
+ break;
+ default:
+ ret = clock_getres_fallback(clkid, ts);
+ break;
+ }
+
+ return ret;
+}
+
+static long gettimeofday_fallback(struct timeval *_tv, struct timezone *_tz)
+{
+ register struct timezone *tz asm("r1") = _tz;
+ register struct timeval *tv asm("r0") = _tv;
+ register long ret asm ("r0");
+ register long nr asm("r7") = __NR_gettimeofday;
+
+ asm("swi #0" : "=r" (ret) : "r" (tv), "r" (tz), "r" (nr) : "memory");
+
+ return ret;
+}
+
+int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+ struct timespec ts;
+ struct vdso_data *vdata;
+ int ret;
+
+ vdata = get_datapage();
+
+ ret = do_realtime(&ts, vdata);
+ if (ret)
+ return gettimeofday_fallback(tv, tz);
+
+ if (tv) {
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+ }
+ if (tz) {
+ tz->tz_minuteswest = vdata->tz_minuteswest;
+ tz->tz_dsttime = vdata->tz_dsttime;
+ }
+
+ return ret;
+}
--
1.8.3.1
^ permalink raw reply related
* [RFC] arm: vdso: Convert sigpage to vdso implementation
From: Nathan Lynch @ 2014-01-28 21:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390926308-15581-1-git-send-email-steve.capper@linaro.org>
Hi Steve,
On 01/28/2014 10:25 AM, Steve Capper wrote:
> ARM has a special sigpage that is used for signal return trampolines.
> Its implementation is very similar to a VDSO conceptually in that it
> occupies a special mapping in user address space.
>
> One could actually host the trampoline code in a VDSO instead with the
> added advantage that one could also host specialised routines there.
> One such routine could be gettimeofday where on ARM we have architected
> (and some vendor supplied) timers that can be queried entirely in
> userspace, obviating the need for an expensive syscall.
>
> This patch converts the sigpage implementation to a VDSO. It is mostly
> a direct port from Will Deacon's arm64 implementation with the ARM
> signal trampoline plumbed in.
>
> Signed-off-by: Steve Capper <steve.capper@linaro.org>
> ---
> As can be inferred from this RFC, I am interested ultimately in
> implementing a syscall-less gettimeofday for ARM. Whilst researching
> possible vectors page or VDSO implementations, I came across the
> sigpage mechanism which is very similar to a VDSO.
>
> The very simple function, __kernel_vdso_doubler, resolved in a test
> program automatically on my Arndale board (running Fedora 20) without
> any additional prodding.
>
> IPC stress tests from LTP were executed to test the signal trampoline.
>
> I would appreciate any comments on this approach of converting the
> sigpage to a VDSO. If this looks sane to people, I will work on the
> gettimeofday logic in a later patch.
As it happens, I've been working on a vDSO implementation of
gettimeofday/clock_gettime which does not mess with the signal page.
I'll reply with the patch separately in a moment.
^ 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