Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 4/4] arm64: documentation: document tagged pointer stack constraints
From: Dave P Martin @ 2017-04-21 17:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1492712234-4950-5-git-send-email-kristina.martsenko@arm.com>

On Thu, Apr 20, 2017 at 07:17:14PM +0100, Kristina Martsenko wrote:
> Some kernel features don't currently work if a task puts a non-zero
> address tag in its stack pointer, frame pointer, or frame record entries
> (FP, LR).
>
> For example, with a tagged stack pointer, the kernel can't deliver
> signals to the process, and the task is killed instead. As another
> example, with a tagged frame pointer or frame records, perf fails to
> generate call graphs or resolve symbols.
>
> For now, just document these limitations, instead of finding and fixing
> everything that doesn't work, as it's not known if anyone needs to use
> tags in these places anyway.
>
> In addition, as requested by Dave Martin, generalize the limitations
> into a general kernel address tag policy, and refactor
> tagged-pointers.txt to include it.
>
> Cc: Dave Martin <dave.martin@arm.com>
> Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>

Looks OK to me.  It's not feasible to describe all possible scenarios
here, but this makes the kernel's intentions clearer.

Reviewed-by: Dave Martin <Dave.Martin@arm.com>

> ---
>  Documentation/arm64/tagged-pointers.txt | 62 +++++++++++++++++++++++++--------
>  1 file changed, 47 insertions(+), 15 deletions(-)
>
> diff --git a/Documentation/arm64/tagged-pointers.txt b/Documentation/arm64/tagged-pointers.txt
> index d9995f1f51b3..a25a99e82bb1 100644
> --- a/Documentation/arm64/tagged-pointers.txt
> +++ b/Documentation/arm64/tagged-pointers.txt
> @@ -11,24 +11,56 @@ in AArch64 Linux.
>  The kernel configures the translation tables so that translations made
>  via TTBR0 (i.e. userspace mappings) have the top byte (bits 63:56) of
>  the virtual address ignored by the translation hardware. This frees up
> -this byte for application use, with the following caveats:
> +this byte for application use.
>
> -     (1) The kernel requires that all user addresses passed to EL1
> -         are tagged with tag 0x00. This means that any syscall
> -         parameters containing user virtual addresses *must* have
> -         their top byte cleared before trapping to the kernel.
>
> -     (2) Non-zero tags are not preserved when delivering signals.
> -         This means that signal handlers in applications making use
> -         of tags cannot rely on the tag information for user virtual
> -         addresses being maintained for fields inside siginfo_t.
> -         One exception to this rule is for signals raised in response
> -         to watchpoint debug exceptions, where the tag information
> -         will be preserved.
> +Passing tagged addresses to the kernel
> +--------------------------------------
>
> -     (3) Special care should be taken when using tagged pointers,
> -         since it is likely that C compilers will not hazard two
> -         virtual addresses differing only in the upper byte.
> +All interpretation of userspace memory addresses by the kernel assumes
> +an address tag of 0x00.
> +
> +This includes, but is not limited to, addresses found in:
> +
> + - pointer arguments to system calls, including pointers in structures
> +   passed to system calls,
> +
> + - the stack pointer (sp), e.g. when interpreting it to deliver a
> +   signal,
> +
> + - the frame pointer (x29) and frame records, e.g. when interpreting
> +   them to generate a backtrace or call graph.
> +
> +Using non-zero address tags in any of these locations may result in an
> +error code being returned, a (fatal) signal being raised, or other modes
> +of failure.
> +
> +For these reasons, passing non-zero address tags to the kernel via
> +system calls is forbidden, and using a non-zero address tag for sp is
> +strongly discouraged.
> +
> +Programs maintaining a frame pointer and frame records that use non-zero
> +address tags may suffer impaired or inaccurate debug and profiling
> +visibility.
> +
> +
> +Preserving tags
> +---------------
> +
> +Non-zero tags are not preserved when delivering signals. This means that
> +signal handlers in applications making use of tags cannot rely on the
> +tag information for user virtual addresses being maintained for fields
> +inside siginfo_t. One exception to this rule is for signals raised in
> +response to watchpoint debug exceptions, where the tag information will
> +be preserved.
>
>  The architecture prevents the use of a tagged PC, so the upper byte will
>  be set to a sign-extension of bit 55 on exception return.
> +
> +
> +Other considerations
> +--------------------
> +
> +Special care should be taken when using tagged pointers, since it is
> +likely that C compilers will not hazard two virtual addresses differing
> +only in the upper byte.
> --
> 2.1.4
>
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

^ permalink raw reply

* [PATCH V15 03/11] cper: add timestamp print to CPER status printing
From: Baicar, Tyler @ 2017-04-21 18:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170421172603.4574wonnm5tgvbcn@pd.tnic>

On 4/21/2017 11:26 AM, Borislav Petkov wrote:
> On Fri, Apr 21, 2017 at 10:04:35AM -0600, Baicar, Tyler wrote:
>> This is basically what I already had in v14...you asked to move it into a
>> different if-statement? https://lkml.org/lkml/2017/4/12/397
> Well, clearly I've been smoking some nasty potent sh*t. :-\
>
> /me goes and looks at the spec:
>
> "Bit 0 ? Timestamp is precise if this bit is set and correlates to the
> time of the error event."
>
> So why are we even printing the timestamp when !precise?
>
> IOW, I think we should do:
>
> 	if (!(timestamp[3] & 0x1))
> 		printk("%stimestamp imprecise\n", pfx);
> 	else {
> 		sec = ..
> 		min = ...
>
> 		...
> 	}
>
> and print the actual values only when the timestamp is precise.
> Otherwise it has *some* values which could just as well be completely
> random. And it's not like we're reporting the error tomorrow - it is
> mostly a couple of seconds from logging to the fw pushing it out...
The timestamp may still be useful when it is imprecise. In the polling 
case, you may only poll every minute or so, so the time may be useful. 
Also, I imagine there could be interrupt based errors happening much 
faster than the FW/OS handshake can happen. Maybe we can just use what I 
had before but also specify imprecise so that it is clear:

         printk("%s%ststamp: %02d%02d-%02d-%02d %02d:%02d:%02d\n", pfx,
             (timestamp[3] & 0x1 ? "precise " : "imprecise "),
              century, year, mon, day, hour, min, sec);

Thanks,
Tyler

-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

^ permalink raw reply

* [PATCH V15 03/11] cper: add timestamp print to CPER status printing
From: Borislav Petkov @ 2017-04-21 18:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <a20143dc-8daa-102b-d929-4d96f73353e3@codeaurora.org>

On Fri, Apr 21, 2017 at 12:08:43PM -0600, Baicar, Tyler wrote:
> The timestamp may still be useful when it is imprecise. In the polling case,
> you may only poll every minute or so, so the time may be useful.

Well, what is in the timestamp when !precise? Some random time or some
timestamp from a couple of seconds ago? How do you differentiate what
timestamp is bollocks and what is from a while ago?

Is the imprecise tstamp really close to the time the error happened or
pointing at 1970 - the beginning of unix time? :-)

I'm sure you've picked up by now that we don't trust the firmware one
bit.

> Also, I imagine there could be interrupt based errors happening much faster than the
> FW/OS handshake can happen. Maybe we can just use what I had before but also
> specify imprecise so that it is clear:
> 
>         printk("%s%ststamp: %02d%02d-%02d-%02d %02d:%02d:%02d\n", pfx,
>             (timestamp[3] & 0x1 ? "precise " : "imprecise "),
>              century, year, mon, day, hour, min, sec);

I guess.

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

^ permalink raw reply

* [PATCH V15 04/11] efi: parse ARM processor error
From: Baicar, Tyler @ 2017-04-21 18:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170421175527.fjwnqd22jz7br5yu@pd.tnic>

On 4/21/2017 11:55 AM, Borislav Petkov wrote:
> On Tue, Apr 18, 2017 at 05:05:16PM -0600, Tyler Baicar wrote:
>> Add support for ARM Common Platform Error Record (CPER).
>> UEFI 2.6 specification adds support for ARM specific
>> processor error information to be reported as part of the
>> CPER records. This provides more detail on for processor error logs.
>>
>> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
>> CC: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
>> Reviewed-by: James Morse <james.morse@arm.com>
>> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>>   drivers/firmware/efi/cper.c | 135 ++++++++++++++++++++++++++++++++++++++++++++
>>   include/linux/cper.h        |  54 ++++++++++++++++++
>>   2 files changed, 189 insertions(+)
>>
>> diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
>> index 46585f9..f959185 100644
>> --- a/drivers/firmware/efi/cper.c
>> +++ b/drivers/firmware/efi/cper.c
>> @@ -110,12 +110,15 @@ void cper_print_bits(const char *pfx, unsigned int bits,
>>   static const char * const proc_type_strs[] = {
>>   	"IA32/X64",
>>   	"IA64",
>> +	"ARM",
>>   };
>>   
>>   static const char * const proc_isa_strs[] = {
>>   	"IA32",
>>   	"IA64",
>>   	"X64",
>> +	"ARM A32/T32",
>> +	"ARM A64",
>>   };
>>   
>>   static const char * const proc_error_type_strs[] = {
>> @@ -184,6 +187,128 @@ static void cper_print_proc_generic(const char *pfx,
>>   		printk("%s""IP: 0x%016llx\n", pfx, proc->ip);
>>   }
>>   
>> +#if defined(CONFIG_ARM64) || defined(CONFIG_ARM)
>> +static const char * const arm_reg_ctx_strs[] = {
>> +	"AArch32 general purpose registers",
>> +	"AArch32 EL1 context registers",
>> +	"AArch32 EL2 context registers",
>> +	"AArch32 secure context registers",
>> +	"AArch64 general purpose registers",
>> +	"AArch64 EL1 context registers",
>> +	"AArch64 EL2 context registers",
>> +	"AArch64 EL3 context registers",
>> +	"Misc. system register structure",
>> +};
>> +
>> +static void cper_print_proc_arm(const char *pfx,
>> +				const struct cper_sec_proc_arm *proc)
>> +{
>> +	int i, len, max_ctx_type;
>> +	struct cper_arm_err_info *err_info;
>> +	struct cper_arm_ctx_info *ctx_info;
>> +	char newpfx[64];
>> +
>> +	printk("%ssection length: %d\n", pfx, proc->section_length);
> We need to dump section length because?
I guess it's not really needed. It just may be useful considering there 
can be numerous error info structures, numerous context info structures, 
and a variable length vendor information section. I can move this print 
to only in the length check failure cases.
>
>> +	printk("%sMIDR: 0x%016llx\n", pfx, proc->midr);
>> +
>> +	len = proc->section_length - (sizeof(*proc) +
>> +		proc->err_info_num * (sizeof(*err_info)));
>> +	if (len < 0) {
>> +		printk("%ssection length is too small\n", pfx);
> Now here we *can* dump it.
>
>> +		printk("%sfirmware-generated error record is incorrect\n", pfx);
>> +		printk("%sERR_INFO_NUM is %d\n", pfx, proc->err_info_num);
>> +		return;
>> +	}
>> +
>> +	if (proc->validation_bits & CPER_ARM_VALID_MPIDR)
>> +		printk("%sMPIDR: 0x%016llx\n", pfx, proc->mpidr);
>
> <---- newline here.
>
> Also, what is MPIDR and can it be written in a more user-friendly manner
> and not be an abbreviation?
>
>> +	if (proc->validation_bits & CPER_ARM_VALID_AFFINITY_LEVEL)
>> +		printk("%serror affinity level: %d\n", pfx,
>> +			proc->affinity_level);
>> +	if (proc->validation_bits & CPER_ARM_VALID_RUNNING_STATE) {
>> +		printk("%srunning state: 0x%x\n", pfx, proc->running_state);
>> +		printk("%sPSCI state: %d\n", pfx, proc->psci_state);
> One more abbreviation. Please consider whether having the abbreviations
> or actually writing them out is more user-friendly.
>
>> +	}
>> +
>> +	snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
> That INDENT_SP thing is just silly, someone should kill it.
>
>> +
>> +	err_info = (struct cper_arm_err_info *)(proc + 1);
>> +	for (i = 0; i < proc->err_info_num; i++) {
>> +		printk("%sError info structure %d:\n", pfx, i);
>> +		printk("%sversion:%d\n", newpfx, err_info->version);
>> +		printk("%slength:%d\n", newpfx, err_info->length);
> <---- newline here.
>
> Why do we even dump version and info for *every* err_info structure?
Because these are part of the error information structure. I wouldn't 
think FW would populate error information structures that are different 
versions in the same processor error, but it could be possible from the 
spec (at least once there are different versions of the table).
>
>> +		if (err_info->validation_bits &
>> +		    CPER_ARM_INFO_VALID_MULTI_ERR) {
>> +			if (err_info->multiple_error == 0)
>> +				printk("%ssingle error\n", newpfx);
>> +			else if (err_info->multiple_error == 1)
>> +				printk("%smultiple errors\n", newpfx);
>> +			else
>> +				printk("%smultiple errors count:%u\n",
>> +				newpfx, err_info->multiple_error);
> So this can be simply: "num errors: %d", err_info->multiple_error+1...
>
> Without checking CPER_ARM_INFO_VALID_MULTI_ERR.
>
>> +		}
> <---- newline here.
>
>> +		if (err_info->validation_bits & CPER_ARM_INFO_VALID_FLAGS) {
>> +			if (err_info->flags & CPER_ARM_INFO_FLAGS_FIRST)
>> +				printk("%sfirst error captured\n", newpfx);
>> +			if (err_info->flags & CPER_ARM_INFO_FLAGS_LAST)
>> +				printk("%slast error captured\n", newpfx);
>> +			if (err_info->flags & CPER_ARM_INFO_FLAGS_PROPAGATED)
>> +				printk("%spropagated error captured\n",
>> +				       newpfx);
>> +			if (err_info->flags & CPER_ARM_INFO_FLAGS_OVERFLOW)
>> +				printk("%soverflow occurred, error info is incomplete\n",
>> +				       newpfx);
>> +		}
> <---- newline here.
>
>> +		printk("%serror_type: %d, %s\n", newpfx, err_info->type,
>> +			err_info->type < ARRAY_SIZE(proc_error_type_strs) ?
>> +			proc_error_type_strs[err_info->type] : "unknown");
>> +		if (err_info->validation_bits & CPER_ARM_INFO_VALID_ERR_INFO)
>> +			printk("%serror_info: 0x%016llx\n", newpfx,
>> +			       err_info->error_info);
> err_info->error_info ?
>
> What is that supposed to mean? A u64 value of some sorts.
There is an error information 64 bit value in the ARM processor error 
information structure. (UEFI spec 2.6 table 261)
>
>> +		if (err_info->validation_bits & CPER_ARM_INFO_VALID_VIRT_ADDR)
>> +			printk("%svirtual fault address: 0x%016llx\n",
>> +				newpfx, err_info->virt_fault_addr);
>> +		if (err_info->validation_bits &
>> +		    CPER_ARM_INFO_VALID_PHYSICAL_ADDR)
> Just let that line stick out.
>
>> +			printk("%sphysical fault address: 0x%016llx\n",
>> +				newpfx, err_info->physical_fault_addr);
>> +		err_info += 1;
>> +	}
> <---- newline here.
>
> That function is kinda missing newlines.
>
>> +	ctx_info = (struct cper_arm_ctx_info *)err_info;
>> +	max_ctx_type = ARRAY_SIZE(arm_reg_ctx_strs) - 1;
>> +	for (i = 0; i < proc->context_info_num; i++) {
>> +		int size = sizeof(*ctx_info) + ctx_info->size;
>> +
>> +		printk("%sContext info structure %d:\n", pfx, i);
>> +		if (len < size) {
>> +			printk("%ssection length is too small\n", newpfx);
>> +			printk("%sfirmware-generated error record is incorrect\n", pfx);
>> +			return;
>> +		}
>> +		if (ctx_info->type > max_ctx_type) {
>> +			printk("%sInvalid context type: %d\n", newpfx,
>> +							ctx_info->type);
>> +			printk("%sMax context type: %d\n", newpfx,
>> +							max_ctx_type);
>> +			return;
> You can combine those into:
>
>                          printk("%sInvalid context type: %d (max: %d)\n",
> 				newpfx, ctx_info->type, max_ctx_type);
>
>
>> +		}
>> +		printk("%sregister context type %d: %s\n", newpfx,
>> +			ctx_info->type, arm_reg_ctx_strs[ctx_info->type]);
> Why dump the type as %d and as a string too? String should be enough, no?
Yes, the string should be sufficient.
>
>> +		print_hex_dump(newpfx, "", DUMP_PREFIX_OFFSET, 16, 4,
>> +				(ctx_info + 1), ctx_info->size, 0);
>> +		len -= size;
>> +		ctx_info = (struct cper_arm_ctx_info *)((long)ctx_info + size);
>> +	}
>> +
>> +	if (len > 0) {
>> +		printk("%sVendor specific error info has %u bytes:\n", pfx,
>> +		       len);
>> +		print_hex_dump(newpfx, "", DUMP_PREFIX_OFFSET, 16, 4, ctx_info,
>> +				len, true);
> That looks like it should be a debug printk...
Why's that? Dumping this vendor specific error information is similar to 
the unrecognized CPER section reporting which is also meant for vendor 
specific information https://lkml.org/lkml/2017/4/18/751

Thanks,
Tyler
>
>> +	}
>> +}
>> +#endif
>> +
>>   static const char * const mem_err_type_strs[] = {
>>   	"unknown",
>>   	"no error",
>> @@ -461,6 +586,16 @@ static void cper_estatus_timestamp(const char *pfx,
>>   			cper_print_pcie(newpfx, pcie, gdata);
>>   		else
>>   			goto err_section_too_small;
>> +	} else if ((IS_ENABLED(CONFIG_ARM64) || IS_ENABLED(CONFIG_ARM)) &&
>> +		   !uuid_le_cmp(*sec_type, CPER_SEC_PROC_ARM)) {
>> +		struct cper_sec_proc_arm *arm_err;
>> +
>> +		arm_err = acpi_hest_get_payload(gdata);
> 		struct cper_sec_proc_arm *arm_err = acpi_hest_get_payload(gdata);
>
>> +		printk("%ssection_type: ARM processor error\n", newpfx);
>> +		if (gdata->error_data_length >= sizeof(*arm_err))
>> +			cper_print_proc_arm(newpfx, arm_err);
>> +		else
>> +			goto err_section_too_small;
> You need to build-test your patches before submitting:
>
> drivers/firmware/efi/cper.c: In function ?cper_estatus_print_section?:
> drivers/firmware/efi/cper.c:596:4: error: implicit declaration of function ?cper_print_proc_arm? [-Werror=implicit-function-declaration]
>      cper_print_proc_arm(newpfx, arm_err);
>      ^~~~~~~~~~~~~~~~~~~
> cc1: some warnings being treated as errors
> make[3]: *** [drivers/firmware/efi/cper.o] Error 1
> make[2]: *** [drivers/firmware/efi] Error 2
> make[1]: *** [drivers/firmware] Error 2
> make[1]: *** Waiting for unfinished jobs....
> make: *** [drivers] Error 2
> make: *** Waiting for unfinished jobs....
>
> this is a x86 build.
>
>>   	} else
>>   		printk("%s""section type: unknown, %pUl\n", newpfx, sec_type);
>>   
>> diff --git a/include/linux/cper.h b/include/linux/cper.h
>> index dcacb1a..85450f3 100644
>> --- a/include/linux/cper.h
>> +++ b/include/linux/cper.h
>> @@ -180,6 +180,10 @@ enum {
>>   #define CPER_SEC_PROC_IPF						\
>>   	UUID_LE(0xE429FAF1, 0x3CB7, 0x11D4, 0x0B, 0xCA, 0x07, 0x00,	\
>>   		0x80, 0xC7, 0x3C, 0x88, 0x81)
>> +/* Processor Specific: ARM */
>> +#define CPER_SEC_PROC_ARM						\
>> +	UUID_LE(0xE19E3D16, 0xBC11, 0x11E4, 0x9C, 0xAA, 0xC2, 0x05,	\
>> +		0x1D, 0x5D, 0x46, 0xB0)
>>   /* Platform Memory */
>>   #define CPER_SEC_PLATFORM_MEM						\
>>   	UUID_LE(0xA5BC1114, 0x6F64, 0x4EDE, 0xB8, 0x63, 0x3E, 0x83,	\
>> @@ -255,6 +259,22 @@ enum {
>>   
>>   #define CPER_PCIE_SLOT_SHIFT			3
>>   
>> +#define CPER_ARM_VALID_MPIDR			0x00000001
>> +#define CPER_ARM_VALID_AFFINITY_LEVEL		0x00000002
>> +#define CPER_ARM_VALID_RUNNING_STATE		0x00000004
>> +#define CPER_ARM_VALID_VENDOR_INFO		0x00000008
>> +
>> +#define CPER_ARM_INFO_VALID_MULTI_ERR		0x0001
>> +#define CPER_ARM_INFO_VALID_FLAGS		0x0002
>> +#define CPER_ARM_INFO_VALID_ERR_INFO		0x0004
>> +#define CPER_ARM_INFO_VALID_VIRT_ADDR		0x0008
>> +#define CPER_ARM_INFO_VALID_PHYSICAL_ADDR	0x0010
>> +
>> +#define CPER_ARM_INFO_FLAGS_FIRST		0x0001
>> +#define CPER_ARM_INFO_FLAGS_LAST		0x0002
>> +#define CPER_ARM_INFO_FLAGS_PROPAGATED		0x0004
>> +#define CPER_ARM_INFO_FLAGS_OVERFLOW		0x0008
> For all of the above use BIT().
>
>> +
>>   /*
>>    * All tables and structs must be byte-packed to match CPER
>>    * specification, since the tables are provided by the system BIOS
>> @@ -340,6 +360,40 @@ struct cper_ia_proc_ctx {
>>   	__u64	mm_reg_addr;
>>   };
>>   
>> +/* ARM Processor Error Section */
>> +struct cper_sec_proc_arm {
>> +	__u32	validation_bits;
>> +	__u16	err_info_num; /* Number of Processor Error Info */
>> +	__u16	context_info_num; /* Number of Processor Context Info Records*/
>> +	__u32	section_length;
>> +	__u8	affinity_level;
>> +	__u8	reserved[3];	/* must be zero */
>> +	__u64	mpidr;
>> +	__u64	midr;
>> +	__u32	running_state; /* Bit 0 set - Processor running. PSCI = 0 */
>> +	__u32	psci_state;
> Align comments vertically pls.
>
>> +};
>> +
>> +/* ARM Processor Error Information Structure */
>> +struct cper_arm_err_info {
>> +	__u8	version;
>> +	__u8	length;
>> +	__u16	validation_bits;
>> +	__u8	type;
>> +	__u16	multiple_error;
>> +	__u8	flags;
>> +	__u64	error_info;
>> +	__u64	virt_fault_addr;
>> +	__u64	physical_fault_addr;
>> +};
>> +
>> +/* ARM Processor Context Information Structure */
>> +struct cper_arm_ctx_info {
>> +	__u16	version;
>> +	__u16	type;
>> +	__u32	size;
>> +};

-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

^ permalink raw reply

* [PATCH 3/4] arm64: entry: improve data abort handling of tagged pointers
From: Dave Martin @ 2017-04-21 18:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1492712234-4950-4-git-send-email-kristina.martsenko@arm.com>

On Thu, Apr 20, 2017 at 07:17:13PM +0100, Kristina Martsenko wrote:
> When handling a data abort from EL0, we currently zero the top byte of
> the faulting address, as we assume the address is a TTBR0 address, which
> may contain a non-zero address tag. However, the address may be a TTBR1
> address, in which case we should not zero the top byte. This patch fixes
> that. The effect is that the full TTBR1 address is passed to the task's
> signal handler (or printed out in the kernel log).
> 
> When handling a data abort from EL1, we leave the faulting address
> intact, as we assume it's either a TTBR1 address or a TTBR0 address with
> tag 0x00. This is true as far as I'm aware, we don't seem to access a
> tagged TTBR0 address anywhere in the kernel. Regardless, it's easy to
> forget about address tags, and code added in the future may not always
> remember to remove tags from addresses before accessing them. So add tag
> handling to the EL1 data abort handler as well. This also makes it
> consistent with the EL0 data abort handler.

Possibly it doesn't matter whether the tag bits are cleared for an EL0
fault on a TTBR1 address, since userspace can't have a valid pointer in
this range to (mis)match the fault address against ... or did I miss
something?

Factoring out the tag handling makes the intent of the code clearer
though, either way.

Cheers
---Dave

> Fixes: d50240a5f6ce ("arm64: mm: permit use of tagged pointers at EL0")
> Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>
> ---
>  arch/arm64/include/asm/asm-uaccess.h | 9 +++++++++
>  arch/arm64/kernel/entry.S            | 4 +++-
>  2 files changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/asm-uaccess.h b/arch/arm64/include/asm/asm-uaccess.h
> index df411f3e083c..790ce8e64f8d 100644
> --- a/arch/arm64/include/asm/asm-uaccess.h
> +++ b/arch/arm64/include/asm/asm-uaccess.h
> @@ -62,4 +62,13 @@ alternative_if ARM64_ALT_PAN_NOT_UAO
>  alternative_else_nop_endif
>  	.endm
>  
> +/*
> + * Remove the address tag from a virtual address, if present.
> + */
> +	.macro	clear_address_tag, addr, tmp
> +	bic	\tmp, \addr, #(0xff << 56)
> +	tst	\addr, #(1 << 55)
> +	csel	\addr, \tmp, \addr, eq
> +	.endm
> +
>  #endif
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 43512d4d7df2..2f7ec392ef50 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -434,6 +434,7 @@ el1_da:
>  	tbnz	x23, #7, 1f			// PSR_I_BIT
>  	enable_irq
>  1:
> +	clear_address_tag x0, x3
>  	mov	x2, sp				// struct pt_regs
>  	bl	do_mem_abort
>  
> @@ -594,7 +595,8 @@ el0_da:
>  	// enable interrupts before calling the main handler
>  	enable_dbg_and_irq
>  	ct_user_exit
> -	bic	x0, x26, #(0xff << 56)
> +	mov	x0, x26
> +	clear_address_tag x0, x3
>  	mov	x1, x25
>  	mov	x2, sp
>  	bl	do_mem_abort
> -- 
> 2.1.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH 2/5] mtd: nand: gpmi: add i.MX 7 SoC support
From: Han Xu @ 2017-04-21 18:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <a9cdc47795433e7b152dcdd123f9bd63@agner.ch>

On Fri, Apr 21, 2017 at 12:38 PM, Stefan Agner <stefan@agner.ch> wrote:
> On 2017-04-21 10:22, Marek Vasut wrote:
>> On 04/21/2017 06:19 PM, Stefan Agner wrote:
>>> On 2017-04-21 06:08, Marek Vasut wrote:
>>>> On 04/21/2017 05:15 AM, Stefan Agner wrote:
>>>>> On 2017-04-20 19:03, Marek Vasut wrote:
>>>>>> On 04/21/2017 03:07 AM, Stefan Agner wrote:
>>>>>>> Add support for i.MX 7 SoC. The i.MX 7 has a slightly different
>>>>>>> clock architecture requiring only two clocks to be referenced.
>>>>>>> The IP is slightly different compared to i.MX 6SoloX, but currently
>>>>>>> none of this differences are in use so there is no detection needed
>>>>>>> and the driver can reuse IS_MX6SX.
>>>>>>>
>>>>>>> Signed-off-by: Stefan Agner <stefan@agner.ch>
>>>>>>> ---
>>>>>>>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 15 +++++++++++++++
>>>>>>>  1 file changed, 15 insertions(+)
>>>>>>>
>>>>>>> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>>>>>> index c8bbf5da2ab8..4a45d37ddc80 100644
>>>>>>> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>>>>>> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>>>>>> @@ -127,6 +127,18 @@ static const struct gpmi_devdata gpmi_devdata_imx6sx = {
>>>>>>>          .clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
>>>>>>>  };
>>>>>>>
>>>>>>> +static const char * const gpmi_clks_for_mx7d[] = {
>>>>>>> +        "gpmi_io", "gpmi_bch_apb",
>>>>>>> +};
>>>>>>> +
>>>>>>> +static const struct gpmi_devdata gpmi_devdata_imx7d = {
>>>>>>> +        .type = IS_MX6SX,
>>>>>>
>>>>>> Would it make sense to use IS_MX7 here already to prevent future surprises ?
>>>>>>
>>>>>
>>>>> Yeah I was thinking we can do it once we have an actual reason to
>>>>> distinguish.
>>>>
>>>> So what are the differences anyway ?
>>>>
>>>
>>> I did not check the details, but Han's patchset (link in cover letter)
>>> mentions:
>>> "add the HW bitflip detection and correction for i.MX6QP and i.MX7D."...
>>
>> Oh, interesting.
>>
>>>>> But then, adding the type would only require 2-3 lines of change if I
>>>>> add it to the GPMI_IS_MX6 macro...
>>>>
>>>> Then at least add a comment because using type = IMX6SX right under
>>>> gpmi_data_mx7d can trigger some head-scratching. And put my R-B on V2.
>>>
>>> FWIW, I mentioned it in the commit message.
>>>
>>> I think rather then adding a comment it is cleaner to just add IS_IMX7D
>>> and add it to the GPMI_IS_MX6 macro. That does not need a comment since
>>> it implicitly says we have a i.MX 7 but treat it like i.MX 6 and it is a
>>> rather small change. Does that sound acceptable?
>>
>> Sure, that's even better, thanks.
>>
>> btw isn't there some single-core mx7 (mx7s ?) , maybe we should just go
>> with mx7 (without the d suffix). I dunno if it has GPMI NAND though, so
>> maybe mx7d is the right thing to do here ...
>>
>
> There is a Solo version yes, and it has GPMI NAND too. However, almost
> all i.MX 7 IPs have been named imx7d by NXP for some reason (including
> compatible strings, see grep -r -e imx7 Documentation/), so I thought I
> stay consistent here...

Hi Guys,

Yes, there should be a i.MX7 Solo version with one core fused out. IMO, can
we use QUIRK to distinguish them rather than SoC name. I know I also sent
some patch set with SoC Name but I prefer to use QUIRK now.

>
> --
> Stefan
>
>>> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>> @@ -132,7 +132,7 @@ static const char * const gpmi_clks_for_mx7d[] = {
>>>  };
>>>
>>>  static const struct gpmi_devdata gpmi_devdata_imx7d = {
>>> -       .type = IS_MX6SX,
>>> +       .type = IS_MX7D,
>>>         .bch_max_ecc_strength = 62,
>>>         .max_chain_delay = 12,
>>>         .clks = gpmi_clks_for_mx7d,
>>> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
>>> b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
>>> index 2e584e18d980..f2cc13abc896 100644
>>> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
>>> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
>>> @@ -123,7 +123,8 @@ enum gpmi_type {
>>>         IS_MX23,
>>>         IS_MX28,
>>>         IS_MX6Q,
>>> -       IS_MX6SX
>>> +       IS_MX6SX,
>>> +       IS_MX7D,
>>>  };
>>>
>>>  struct gpmi_devdata {
>>> @@ -307,6 +308,8 @@ void gpmi_copy_bits(u8 *dst, size_t dst_bit_off,
>>>  #define GPMI_IS_MX28(x)                ((x)->devdata->type == IS_MX28)
>>>  #define GPMI_IS_MX6Q(x)                ((x)->devdata->type == IS_MX6Q)
>>>  #define GPMI_IS_MX6SX(x)       ((x)->devdata->type == IS_MX6SX)
>>> +#define GPMI_IS_MX7D(x)                ((x)->devdata->type == IS_MX7D)
>>>
>>> -#define GPMI_IS_MX6(x)         (GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x))
>>> +#define GPMI_IS_MX6(x)         (GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x) ||
>>> \
>>> +                                GPMI_IS_MX7D(x))
>>>  #endif
>>>
>>> --
>>> Stefan
>>>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



-- 
Sincerely,

Han XU

^ permalink raw reply

* [RFC PATCH 0/2] kbuild: use relative path from $(srctree) instead of __FILE__
From: Masahiro Yamada @ 2017-04-21 19:03 UTC (permalink / raw)
  To: linux-arm-kernel


Kbuild works in objtree, not in srctree.  So, __FILE__ is prefixed
with $(srctree)/ for out-of-tree build.

It would be nice to see the same log regardless
in-tree, or out-of-tree build.

1/2 adds a new macro KBUILD_FILE.  This points the relative path
of the file we are building.  This is intended to replace __FILE__.

2/2 replaces __FILE__ in bug.h as an example.  This will improve
the output of WARN_ON() etc.



Masahiro Yamada (2):
  kbuild: add KBUILD_FILE to point relative file path from $(srctree)
  bug.h: replace __FILE__ with KBUILD_FILE for shorter names in log

 arch/alpha/include/asm/bug.h          | 2 +-
 arch/arc/include/asm/bug.h            | 2 +-
 arch/arm/include/asm/bug.h            | 4 ++--
 arch/arm64/include/asm/bug.h          | 2 +-
 arch/avr32/include/asm/bug.h          | 2 +-
 arch/blackfin/include/asm/bug.h       | 2 +-
 arch/cris/include/arch-v10/arch/bug.h | 6 +++---
 arch/cris/include/arch-v32/arch/bug.h | 2 +-
 arch/frv/include/asm/bug.h            | 2 +-
 arch/ia64/include/asm/bug.h           | 2 +-
 arch/m68k/include/asm/bug.h           | 4 ++--
 arch/mn10300/include/asm/bug.h        | 2 +-
 arch/parisc/include/asm/bug.h         | 4 ++--
 arch/powerpc/include/asm/bug.h        | 8 ++++----
 arch/s390/include/asm/bug.h           | 2 +-
 arch/score/include/asm/bug.h          | 4 ++--
 arch/sh/include/asm/bug.h             | 8 ++++----
 arch/sparc/include/asm/bug.h          | 2 +-
 arch/x86/include/asm/bug.h            | 2 +-
 include/asm-generic/bug.h             | 8 ++++----
 scripts/Kbuild.include                | 4 ++++
 scripts/Makefile.lib                  | 5 +++--
 22 files changed, 42 insertions(+), 37 deletions(-)

-- 
2.7.4

^ permalink raw reply

* [RFC PATCH 1/2] kbuild: add KBUILD_FILE to point relative file path from $(srctree)
From: Masahiro Yamada @ 2017-04-21 19:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1492801407-26823-1-git-send-email-yamada.masahiro@socionext.com>

Since Kbuild runs in the objtree, __FILE__ can be a very long path
depending of $(srctree).

Commit 9da0763bdd82 ("kbuild: Use relative path when building in a
subdir of the source tree") made the situation better for cases
where objtree is a child of srctree.  ($(srctree) is "..")

For other cases of out-of-tree build, filenames in WARN_ON() etc.
are still an absolute path.  It also means the kernel image depends
on where it was built.

Here, the idea is to define a new macro, KBUILD_FILE, to point the
relative file path from $(srctree).

If we replace __FILE__ with KBUILD_FILE, we can rip off the path
to the build directory.

I am adding stringify helper because '"..."' wrapping is the same
pattern for KBUILD_BASENAME, KBUILD_MODNAME, and KBUILD_FILE.

Please note KBUILD_FILE is still an absolute path for external
modules.  We can strip KBUILD_EXTMOD from the path if we want,
but I am not doing that.  It would make it difficult to figure out
the module in question in case of WARN_ON().

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

 scripts/Kbuild.include | 4 ++++
 scripts/Makefile.lib   | 5 +++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 61f87a9..7fc3841 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -31,6 +31,10 @@ baseprereq = $(basename $(notdir $<))
 escsq = $(subst $(squote),'\$(squote)',$1)
 
 ###
+# Quote a string to pass it to C files. foo => '"foo"'
+stringify = $(squote)$(quote)$1$(quote)$(squote)
+
+###
 # Easy method for doing a status message
        kecho := :
  quiet_kecho := echo
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 9e70196..f8dce56 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -96,10 +96,11 @@ obj-dirs	:= $(addprefix $(obj)/,$(obj-dirs))
 # Note: Files that end up in two or more modules are compiled without the
 #       KBUILD_MODNAME definition. The reason is that any made-up name would
 #       differ in different configs.
-name-fix = $(squote)$(quote)$(subst $(comma),_,$(subst -,_,$1))$(quote)$(squote)
+name-fix = $(call stringify,$(subst $(comma),_,$(subst -,_,$1)))
 basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget))
 modname_flags  = $(if $(filter 1,$(words $(modname))),\
                  -DKBUILD_MODNAME=$(call name-fix,$(modname)))
+filepath_flags = -DKBUILD_FILE=$(call stringify,$(src)/$(notdir $<))
 
 orig_c_flags   = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \
                  $(ccflags-y) $(CFLAGS_$(basetarget).o)
@@ -163,7 +164,7 @@ endif
 
 c_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
 		 $(__c_flags) $(modkern_cflags)                           \
-		 $(basename_flags) $(modname_flags)
+		 $(basename_flags) $(modname_flags) $(filepath_flags)
 
 a_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
 		 $(__a_flags) $(modkern_aflags)
-- 
2.7.4

^ permalink raw reply related

* [RFC PATCH 2/2] bug.h: replace __FILE__ with KBUILD_FILE for shorter names in log
From: Masahiro Yamada @ 2017-04-21 19:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1492801407-26823-1-git-send-email-yamada.masahiro@socionext.com>

__FILE__ can be a long absolute path for out-of-tree build.
The output of WARN_ON() and friends depends on the location of
the object tree, like this:

WARNING: CPU: 1 PID: 1 at /path/to/build/directory/arch/arm64/kernel/foo.c:...

KBUILD_FILE is a relative from srctree, so we will always see the
same path with/without O= option.

WARNING: CPU: 1 PID: 1 at arch/arm64/kernel/foo.c:...

Note:
"git grep __FILE__" has more than 1000 hits.  Perhaps, we may want
to do 's/__FILE__/KBUILD_FILE/' tree-wide.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

 arch/alpha/include/asm/bug.h          | 2 +-
 arch/arc/include/asm/bug.h            | 2 +-
 arch/arm/include/asm/bug.h            | 4 ++--
 arch/arm64/include/asm/bug.h          | 2 +-
 arch/avr32/include/asm/bug.h          | 2 +-
 arch/blackfin/include/asm/bug.h       | 2 +-
 arch/cris/include/arch-v10/arch/bug.h | 6 +++---
 arch/cris/include/arch-v32/arch/bug.h | 2 +-
 arch/frv/include/asm/bug.h            | 2 +-
 arch/ia64/include/asm/bug.h           | 2 +-
 arch/m68k/include/asm/bug.h           | 4 ++--
 arch/mn10300/include/asm/bug.h        | 2 +-
 arch/parisc/include/asm/bug.h         | 4 ++--
 arch/powerpc/include/asm/bug.h        | 8 ++++----
 arch/s390/include/asm/bug.h           | 2 +-
 arch/score/include/asm/bug.h          | 4 ++--
 arch/sh/include/asm/bug.h             | 8 ++++----
 arch/sparc/include/asm/bug.h          | 2 +-
 arch/x86/include/asm/bug.h            | 2 +-
 include/asm-generic/bug.h             | 8 ++++----
 20 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/arch/alpha/include/asm/bug.h b/arch/alpha/include/asm/bug.h
index f091682..8dd0661 100644
--- a/arch/alpha/include/asm/bug.h
+++ b/arch/alpha/include/asm/bug.h
@@ -12,7 +12,7 @@
 	__asm__ __volatile__(						\
 		"call_pal %0  # bugchk\n\t"				\
 		".long %1\n\t.8byte %2"					\
-		: : "i"(PAL_bugchk), "i"(__LINE__), "i"(__FILE__));	\
+		: : "i"(PAL_bugchk), "i"(__LINE__), "i"(KBUILD_FILE));	\
 	unreachable();							\
   } while (0)
 
diff --git a/arch/arc/include/asm/bug.h b/arch/arc/include/asm/bug.h
index ea022d4..620f03e 100644
--- a/arch/arc/include/asm/bug.h
+++ b/arch/arc/include/asm/bug.h
@@ -22,7 +22,7 @@ void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
 void die(const char *str, struct pt_regs *regs, unsigned long address);
 
 #define BUG()	do {								\
-	pr_warn("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
+	pr_warn("BUG: failure at %s:%d/%s()!\n", KBUILD_FILE, __LINE__, __func__); \
 	dump_stack();								\
 } while (0)
 
diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h
index 4e6e88a..8644f7d 100644
--- a/arch/arm/include/asm/bug.h
+++ b/arch/arm/include/asm/bug.h
@@ -19,13 +19,13 @@
 #endif
 
 
-#define BUG() _BUG(__FILE__, __LINE__, BUG_INSTR_VALUE)
+#define BUG() _BUG(KBUILD_FILE, __LINE__, BUG_INSTR_VALUE)
 #define _BUG(file, line, value) __BUG(file, line, value)
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 
 /*
- * The extra indirection is to ensure that the __FILE__ string comes through
+ * The extra indirection is to ensure that the KBUILD_FILE string comes through
  * OK. Many version of gcc do not support the asm %c parameter which would be
  * preferable to this unpleasantness. We use mergeable string sections to
  * avoid multiple copies of the string appearing in the kernel image.
diff --git a/arch/arm64/include/asm/bug.h b/arch/arm64/include/asm/bug.h
index 561190d..3d8826e 100644
--- a/arch/arm64/include/asm/bug.h
+++ b/arch/arm64/include/asm/bug.h
@@ -42,7 +42,7 @@
 		".pushsection __bug_table,\"a\"\n\t"	\
 		".align 2\n\t"				\
 	"0:	.long 1f - 0b\n\t"			\
-_BUGVERBOSE_LOCATION(__FILE__, __LINE__)		\
+_BUGVERBOSE_LOCATION(KBUILD_FILE, __LINE__)		\
 		".short " #flags "\n\t"			\
 		".popsection\n"				\
 							\
diff --git a/arch/avr32/include/asm/bug.h b/arch/avr32/include/asm/bug.h
index 85a92d0..b9b610c 100644
--- a/arch/avr32/include/asm/bug.h
+++ b/arch/avr32/include/asm/bug.h
@@ -29,7 +29,7 @@
 		"	.org	2b + %4\n"				\
 		"	.previous"					\
 		:							\
-		: "i"(AVR32_BUG_OPCODE), "i"(__FILE__),			\
+		: "i"(AVR32_BUG_OPCODE), "i"(KBUILD_FILE),			\
 		  "i"(__LINE__), "i"(flags),				\
 		  "i"(sizeof(struct bug_entry)))
 
diff --git a/arch/blackfin/include/asm/bug.h b/arch/blackfin/include/asm/bug.h
index 8d9b1eb..c64a48e 100644
--- a/arch/blackfin/include/asm/bug.h
+++ b/arch/blackfin/include/asm/bug.h
@@ -29,7 +29,7 @@
 		"	.org	2b + %4\n"				\
 		"	.previous"					\
 		:							\
-		: "i"(BFIN_BUG_OPCODE), "i"(__FILE__),			\
+		: "i"(BFIN_BUG_OPCODE), "i"(KBUILD_FILE),			\
 		  "i"(__LINE__), "i"(flags),				\
 		  "i"(sizeof(struct bug_entry)))
 
diff --git a/arch/cris/include/arch-v10/arch/bug.h b/arch/cris/include/arch-v10/arch/bug.h
index 3485d6b..f190d12 100644
--- a/arch/cris/include/arch-v10/arch/bug.h
+++ b/arch/cris/include/arch-v10/arch/bug.h
@@ -35,11 +35,11 @@ struct bug_frame {
 	__asm__ __volatile__ ("clear.d [" __stringify(BUG_MAGIC) "]\n\t"\
 				"movu.w %0,$r0\n\t"			\
 				"jump %1\n\t"				\
-				: : "i" (__LINE__), "i" (__FILE__))
+				: : "i" (__LINE__), "i" (KBUILD_FILE))
 #else
 /* This version will have to do for now, until the compiler is fixed.
  * The drawbacks of this version are that the file name will appear multiple
- * times in the .rodata section, and that __LINE__ and __FILE__ can probably
+ * times in the .rodata section, and that __LINE__ and KBUILD_FILE can probably
  * not be used like this with newer versions of gcc.
  */
 #define BUG()								\
@@ -47,7 +47,7 @@ struct bug_frame {
 			      "movu.w " __stringify(__LINE__) ",$r0\n\t"\
 			      "jump 0f\n\t"				\
 			      ".section .rodata\n"			\
-			      "0:\t.string \"" __FILE__ "\"\n\t"	\
+			      "0:\t.string \"" KBUILD_FILE "\"\n\t"	\
 			      ".previous")
 #endif
 
diff --git a/arch/cris/include/arch-v32/arch/bug.h b/arch/cris/include/arch-v32/arch/bug.h
index fb59faa..e0eeeff 100644
--- a/arch/cris/include/arch-v32/arch/bug.h
+++ b/arch/cris/include/arch-v32/arch/bug.h
@@ -22,7 +22,7 @@ do {									\
 			      ".section __ex_table,\"a\"\n\t"		\
 			      ".dword 0b, 1b\n\t"			\
 			      ".previous\n\t"				\
-			      : : "ri" (__FILE__), "i" (__LINE__));	\
+			      : : "ri" (KBUILD_FILE), "i" (__LINE__));	\
 	unreachable();				\
 } while (0)
 #else
diff --git a/arch/frv/include/asm/bug.h b/arch/frv/include/asm/bug.h
index dd01bcf..6a46dde 100644
--- a/arch/frv/include/asm/bug.h
+++ b/arch/frv/include/asm/bug.h
@@ -23,7 +23,7 @@ extern asmlinkage void __debug_bug_trap(int signr);
 #define	_debug_bug_printk()
 #else
 extern void __debug_bug_printk(const char *file, unsigned line);
-#define	_debug_bug_printk() __debug_bug_printk(__FILE__, __LINE__)
+#define	_debug_bug_printk() __debug_bug_printk(KBUILD_FILE, __LINE__)
 #endif
 
 #define _debug_bug_trap(signr)			\
diff --git a/arch/ia64/include/asm/bug.h b/arch/ia64/include/asm/bug.h
index 823616b..3cabfa3 100644
--- a/arch/ia64/include/asm/bug.h
+++ b/arch/ia64/include/asm/bug.h
@@ -3,7 +3,7 @@
 
 #ifdef CONFIG_BUG
 #define ia64_abort()	__builtin_trap()
-#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0)
+#define BUG() do { printk("kernel BUG at %s:%d!\n", KBUILD_FILE, __LINE__); ia64_abort(); } while (0)
 
 /* should this BUG be made generic? */
 #define HAVE_ARCH_BUG
diff --git a/arch/m68k/include/asm/bug.h b/arch/m68k/include/asm/bug.h
index 5bc8d91..46ad49f 100644
--- a/arch/m68k/include/asm/bug.h
+++ b/arch/m68k/include/asm/bug.h
@@ -6,12 +6,12 @@
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 #ifndef CONFIG_SUN3
 #define BUG() do { \
-	pr_crit("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	pr_crit("kernel BUG at %s:%d!\n", KBUILD_FILE, __LINE__); \
 	__builtin_trap(); \
 } while (0)
 #else
 #define BUG() do { \
-	pr_crit("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	pr_crit("kernel BUG at %s:%d!\n", KBUILD_FILE, __LINE__); \
 	panic("BUG!"); \
 } while (0)
 #endif
diff --git a/arch/mn10300/include/asm/bug.h b/arch/mn10300/include/asm/bug.h
index aa6a388..d5de3b8 100644
--- a/arch/mn10300/include/asm/bug.h
+++ b/arch/mn10300/include/asm/bug.h
@@ -25,7 +25,7 @@ do {								\
 		"	.long 0b,%0,%1			\n"	\
 		"	.previous			\n"	\
 		:						\
-		: "i"(__FILE__), "i"(__LINE__)			\
+		: "i"(KBUILD_FILE), "i"(__LINE__)			\
 		);						\
 } while (1)
 
diff --git a/arch/parisc/include/asm/bug.h b/arch/parisc/include/asm/bug.h
index 62a3333..3b8e71f 100644
--- a/arch/parisc/include/asm/bug.h
+++ b/arch/parisc/include/asm/bug.h
@@ -32,7 +32,7 @@
 			     "\t.short %c1, %c2\n"			\
 			     "\t.org 2b+%c3\n"				\
 			     "\t.popsection"				\
-			     : : "i" (__FILE__), "i" (__LINE__),	\
+			     : : "i" (KBUILD_FILE), "i" (__LINE__),	\
 			     "i" (0), "i" (sizeof(struct bug_entry)) ); \
 		unreachable();						\
 	} while(0)
@@ -55,7 +55,7 @@
 			     "\t.short %c1, %c2\n"			\
 			     "\t.org 2b+%c3\n"				\
 			     "\t.popsection"				\
-			     : : "i" (__FILE__), "i" (__LINE__),	\
+			     : : "i" (KBUILD_FILE), "i" (__LINE__),	\
 			     "i" (BUGFLAG_TAINT(taint)), 		\
 			     "i" (sizeof(struct bug_entry)) );		\
 	} while(0)
diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
index 3a39283..55b803c 100644
--- a/arch/powerpc/include/asm/bug.h
+++ b/arch/powerpc/include/asm/bug.h
@@ -66,7 +66,7 @@
 	__asm__ __volatile__(					\
 		"1:	twi 31,0,0\n"				\
 		_EMIT_BUG_ENTRY					\
-		: : "i" (__FILE__), "i" (__LINE__),		\
+		: : "i" (KBUILD_FILE), "i" (__LINE__),		\
 		    "i" (0), "i"  (sizeof(struct bug_entry)));	\
 	unreachable();						\
 } while (0)
@@ -79,7 +79,7 @@
 		__asm__ __volatile__(				\
 		"1:	"PPC_TLNEI"	%4,0\n"			\
 		_EMIT_BUG_ENTRY					\
-		: : "i" (__FILE__), "i" (__LINE__), "i" (0),	\
+		: : "i" (KBUILD_FILE), "i" (__LINE__), "i" (0),	\
 		  "i" (sizeof(struct bug_entry)),		\
 		  "r" ((__force long)(x)));			\
 	}							\
@@ -89,7 +89,7 @@
 	__asm__ __volatile__(					\
 		"1:	twi 31,0,0\n"				\
 		_EMIT_BUG_ENTRY					\
-		: : "i" (__FILE__), "i" (__LINE__),		\
+		: : "i" (KBUILD_FILE), "i" (__LINE__),		\
 		  "i" (BUGFLAG_TAINT(taint)),			\
 		  "i" (sizeof(struct bug_entry)));		\
 } while (0)
@@ -103,7 +103,7 @@
 		__asm__ __volatile__(				\
 		"1:	"PPC_TLNEI"	%4,0\n"			\
 		_EMIT_BUG_ENTRY					\
-		: : "i" (__FILE__), "i" (__LINE__),		\
+		: : "i" (KBUILD_FILE), "i" (__LINE__),		\
 		  "i" (BUGFLAG_TAINT(TAINT_WARN)),		\
 		  "i" (sizeof(struct bug_entry)),		\
 		  "r" (__ret_warn_on));				\
diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h
index bf90d1f..23638f4 100644
--- a/arch/s390/include/asm/bug.h
+++ b/arch/s390/include/asm/bug.h
@@ -12,7 +12,7 @@
 		"0:	j	0b+2\n"				\
 		"1:\n"						\
 		".section .rodata.str,\"aMS\", at progbits,1\n"	\
-		"2:	.asciz	\""__FILE__"\"\n"		\
+		"2:	.asciz	\""KBUILD_FILE"\"\n"		\
 		".previous\n"					\
 		".section __bug_table,\"a\"\n"			\
 		"3:	.long	1b-3b,2b-3b\n"			\
diff --git a/arch/score/include/asm/bug.h b/arch/score/include/asm/bug.h
index fd7164a..3b8373b 100644
--- a/arch/score/include/asm/bug.h
+++ b/arch/score/include/asm/bug.h
@@ -10,8 +10,8 @@ extern void __die_if_kernel(const char *, struct pt_regs *, const char *,
 	const char *, unsigned long);
 
 #define die(msg, regs)							\
-	__die(msg, regs, __FILE__ ":", __func__, __LINE__)
+	__die(msg, regs, KBUILD_FILE ":", __func__, __LINE__)
 #define die_if_kernel(msg, regs)					\
-	__die_if_kernel(msg, regs, __FILE__ ":", __func__, __LINE__)
+	__die_if_kernel(msg, regs, KBUILD_FILE ":", __func__, __LINE__)
 
 #endif /* _ASM_SCORE_BUG_H */
diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h
index dcf2780..ee1e59d 100644
--- a/arch/sh/include/asm/bug.h
+++ b/arch/sh/include/asm/bug.h
@@ -12,7 +12,7 @@
 
 /**
  * _EMIT_BUG_ENTRY
- * %1 - __FILE__
+ * %1 - KBUILD_FILE
  * %2 - __LINE__
  * %3 - trap type
  * %4 - sizeof(struct bug_entry)
@@ -45,7 +45,7 @@ do {							\
 		_EMIT_BUG_ENTRY				\
 		 :					\
 		 : "n" (TRAPA_BUG_OPCODE),		\
-		   "i" (__FILE__),			\
+		   "i" (KBUILD_FILE),			\
 		   "i" (__LINE__), "i" (0),		\
 		   "i" (sizeof(struct bug_entry)));	\
 } while (0)
@@ -57,7 +57,7 @@ do {							\
 		 _EMIT_BUG_ENTRY			\
 		 :					\
 		 : "n" (TRAPA_BUG_OPCODE),		\
-		   "i" (__FILE__),			\
+		   "i" (KBUILD_FILE),			\
 		   "i" (__LINE__),			\
 		   "i" (BUGFLAG_TAINT(taint)),		\
 		   "i" (sizeof(struct bug_entry)));	\
@@ -82,7 +82,7 @@ do {							\
 		_EMIT_BUG_ENTRY				\
 		 :					\
 		 : "n" (TRAPA_BUG_OPCODE),		\
-		   "i" (__FILE__),			\
+		   "i" (KBUILD_FILE),			\
 		   "i" (__LINE__),			\
 		   "i" (BUGFLAG_UNWINDER),		\
 		   "i" (sizeof(struct bug_entry)));	\
diff --git a/arch/sparc/include/asm/bug.h b/arch/sparc/include/asm/bug.h
index eaa8f8d..c619219 100644
--- a/arch/sparc/include/asm/bug.h
+++ b/arch/sparc/include/asm/bug.h
@@ -7,7 +7,7 @@
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 void do_BUG(const char *file, int line);
 #define BUG() do {					\
-	do_BUG(__FILE__, __LINE__);			\
+	do_BUG(KBUILD_FILE, __LINE__);			\
 	__builtin_trap();				\
 } while (0)
 #else
diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h
index ba38ebb..2af438d 100644
--- a/arch/x86/include/asm/bug.h
+++ b/arch/x86/include/asm/bug.h
@@ -19,7 +19,7 @@ do {								\
 		     "\t.word %c1, 0\n"				\
 		     "\t.org 2b+%c2\n"				\
 		     ".popsection"				\
-		     : : "i" (__FILE__), "i" (__LINE__),	\
+		     : : "i" (KBUILD_FILE), "i" (__LINE__),	\
 		     "i" (sizeof(struct bug_entry)));		\
 	unreachable();						\
 } while (0)
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 6f96247..04e50b3 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -46,7 +46,7 @@ struct bug_entry {
  */
 #ifndef HAVE_ARCH_BUG
 #define BUG() do { \
-	printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
+	printk("BUG: failure at %s:%d/%s()!\n", KBUILD_FILE, __LINE__, __func__); \
 	panic("BUG!"); \
 } while (0)
 #endif
@@ -70,10 +70,10 @@ void warn_slowpath_fmt_taint(const char *file, const int line, unsigned taint,
 			     const char *fmt, ...);
 extern void warn_slowpath_null(const char *file, const int line);
 #define WANT_WARN_ON_SLOWPATH
-#define __WARN()		warn_slowpath_null(__FILE__, __LINE__)
-#define __WARN_printf(arg...)	warn_slowpath_fmt(__FILE__, __LINE__, arg)
+#define __WARN()		warn_slowpath_null(KBUILD_FILE, __LINE__)
+#define __WARN_printf(arg...)	warn_slowpath_fmt(KBUILD_FILE, __LINE__, arg)
 #define __WARN_printf_taint(taint, arg...)				\
-	warn_slowpath_fmt_taint(__FILE__, __LINE__, taint, arg)
+	warn_slowpath_fmt_taint(KBUILD_FILE, __LINE__, taint, arg)
 #else
 #define __WARN()		__WARN_TAINT(TAINT_WARN)
 #define __WARN_printf(arg...)	do { printk(arg); __WARN(); } while (0)
-- 
2.7.4

^ permalink raw reply related

* [PATCH] ARM: add DTS, defconfig for ADLINK LEC-iMX6
From: Jens Rottmann @ 2017-04-21 19:27 UTC (permalink / raw)
  To: linux-arm-kernel

These are SMARC form factor modules with NXP/Freescale i.MX6 Q/D/DL/S,
1-2 GB RAM, optional eMMC, optional PCIe switch. The DTS files support
the modules on ADLINK's LEC-Base R1 and LEC-Base Mini eval carriers.

Signed-off-by: Jens Rottmann <Jens.Rottmann@ADLINKtech.com>
---

--- /dev/null
+++ b/arch/arm/boot/dts/lec-imx6.dtsi
@@ -0,0 +1,1244 @@
+/*
+ * Copyright 2014-2016 LiPPERT ADLINK Technology GmbH
+ * Copyright 2012-2015 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/* On-module multiplexer: 0 enables SMARC SPI0, !=0 enables I2S0 instead:
+ * 1=TI TLV320AIC23 on LEC-Base R1 carrier, 2=Freescale SGTL5000 on LEC-Base R2/Mini */
+#define CONFIG_I2S_AUDIO	0
+/* The LEC-Base carrier doesn't include cameras, but allows connecting some. */
+//#define CONFIG_SER_CAMERA	3c /* I2C addr of serial camera, hex without "0x" */
+//#define CONFIG_PAR_CAMERA	3c /* I2C addr of parallel camera */
+
+/* The on-module Freescale PF0100 PMIC provides VDD_ARM_IN, VDD_SOC_IN to the
+ * on-SoC Anatop LDOs, which then generate VDD_ARM (CPU cores), VDD_PU
+ * (GPU/VPU), VDD_SOC (the rest). To save power clock and voltage need to vary
+ * according to the workload.
+ * Normal: PMIC provides fixed voltage, internal LDO lowers voltage further to
+ *         required value, depending on clock frequency.
+ * LDO bypass: PMIC (switched!) provides variable voltage directly, controlled
+ *             via I2C; internal LDOs bridged (FETs permanently on).
+ * Bypassing saves power, but requires steady communication on i2c2 to work. */
+#define LDO_BYPASS	1
+
+/* Freescale defines 2 alternative DT nodes for the VPU: The one normally active
+ * loads a driver called 'mxc_vpu'. The other, disabled one, would invoke a
+ * different driver named 'coda'. I don't know what state it is in; none of
+ * Freescale's sample dts files enable it, but the code is there, appearently
+ * dormant, in imx6qdl.dtsi. 'Coda' requires a v4l-coda960-imx6*.bin firmware. */
+#define VPU_CODA	0
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#define __0x(X) 0x##X	/* prefix hex digits with "0x" */
+#define _0x(X) __0x(X)
+
+/ {
+	aliases {
+		mxcfb0 = &mxcfb1;
+		mxcfb1 = &mxcfb2;
+		mxcfb2 = &mxcfb3;
+	};
+
+	chosen {
+		/* U-Boot provides this via "console=..." in the 'params' variable. */
+		//stdout-path = &uart1;
+	};
+
+	/* The LEC-Base carriers don't have any LEDs, just show how it's done. */
+	//leds {
+	//	compatible = "gpio-leds";
+	//
+	//	example-led {
+	//		gpios = <&smarc_gpio 5 GPIO_ACTIVE_LOW>; /* SMARC GPIO5/PWM_OUT */
+	//		linux,default-trigger = "mmc1"; /* more triggers in menuconfig */
+	//	};
+	//};
+
+	memory: memory {
+		reg = <0x10000000 0x40000000>;	/* dummy size, overwritten by U-Boot */
+	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_regulators>;
+
+		reg_smarc_lcd_vdd: regulator at 130 {
+			compatible = "regulator-fixed";
+			reg = <130>;
+			regulator-name = "smarc_lcd_vdd";
+			gpio = <&gpio1 30 GPIO_ACTIVE_HIGH>; /* SMARC LCD_VDD_EN */
+			enable-active-high;
+			regulator-always-on; /* Freescale's fb/lcd/ldb drivers can't control a regulator yet :-( */
+			regulator-state-mem { regulator-off-in-suspend; }; /* no effect? */
+		};
+
+		reg_smarc_usb0: regulator at 127 {
+			compatible = "regulator-fixed";
+			reg = <127>;
+			regulator-name = "smarc_usb0";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>; /* SMARC USB0_EN_OC# */
+			enable-active-high;
+		};
+
+		reg_smarc_usb1: regulator at 329 {
+			compatible = "regulator-fixed";
+			reg = <329>;
+			regulator-name = "smarc_usb1";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio3 29 GPIO_ACTIVE_HIGH>; /* SMARC USB1_EN_OC# */
+			enable-active-high;
+			/* Before enabling Vbus on the carrier power up the host phy's Vbus. */
+			vin-supply = <&swbst_reg>;
+		};
+
+		reg_smarc_usb2: regulator at 330 {
+			compatible = "regulator-fixed";
+			reg = <330>;
+			regulator-name = "smarc_usb2";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>; /* SMARC USB2_EN_OC# */
+			enable-active-high;
+			/* An on-module hub splits the i.MX6's usbh1 port into SMARC USB1 and 2.
+			 * Devices on both are powered independently, via reg_smarc_usb1 and 2.
+			 * But I've seen no way to model the hub in the device tree and usbh1
+			 * takes only 1 "vbus-supply" line. So by declaring one as vin-supply
+			 * for the other we trick usbh1 into enabling both. If someone needed to
+			 * enable them separately they'd have to do it manually in user mode. */
+			vin-supply = <&reg_smarc_usb1>;
+		};
+
+		reg_smarc_sdio_pwr: regulator at 411 {
+			compatible = "regulator-fixed";
+			reg = <411>;
+			regulator-name = "smarc_sdio_pwr";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpio = <&gpio4 11 GPIO_ACTIVE_HIGH>; /* SMARC SDIO_PWR_EN */
+			enable-active-high;
+			regulator-boot-on;
+		};
+
+#if CONFIG_I2S_AUDIO == 2
+		/* Power supplies on the LEC-Base R2 carrier. They cannot be
+		 * controlled, but the SGTL5000 driver won't work without
+		 * regulator definitions. */
+		reg_base_1v8: regulator at 18 {
+			compatible = "regulator-fixed";
+			reg = <18>;
+			regulator-name = "base_1v8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		reg_base_3v3: regulator at 33 {
+			compatible = "regulator-fixed";
+			reg = <33>;
+			regulator-name = "base_3v3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+#endif
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_keys>;
+
+		lid {
+			label = "Lid switch";
+			gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; /* SMARC LID# */
+			gpio-key,wakeup;
+			linux,input-type = <5>; /* EV_SW */
+			linux,code = <0>; /* SW_LID */
+		};
+
+		power {
+			label = "Power button";
+			gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; /* SMARC POWER_BTN# */
+			gpio-key,wakeup;
+			linux,code = <KEY_POWER>;
+		};
+
+		sleep {
+			label = "Sleep button";
+			gpios = <&gpio2 7 GPIO_ACTIVE_LOW>; /* SMARC SLEEP# */
+			gpio-key,wakeup;
+			linux,code = <KEY_SLEEP>;
+		};
+
+		test {
+			label = "Test button"; /* LEC-Base R2 carrier provides a button */
+			gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; /* SMARC TEST# */
+			/* SMARC spec: "invoke module vendor specific test function(s)" */
+			linux,code = <KEY_PROG1>; /* adapt to your needs */
+		};
+
+		/* The PCIe driver doesn't implement a wakeup GPIO yet. For now,
+		 * this can serve as workaround. */
+		//pcie_wake {
+		//	label = "PCIe wake workaround";
+		//	gpios = <&gpio5 20 GPIO_ACTIVE_LOW>; /* PCIE_WAKE_B */
+		//	gpio-key,wakeup;
+		//	linux,code = <KEY_WAKEUP>;
+		//};
+	};
+
+#if CONFIG_I2S_AUDIO == 1
+	sound-i2s {	/* Audio codec on LEC-Base R1 carrier */
+		compatible = "fsl,imx-audio-tlv320aic23";
+		model = "imx-tlv320aic23";
+		ssi-controller = <&ssi2>;
+		mux-int-port = <2>;
+		mux-ext-port = <3>;
+		audio-codec = <&codec>;
+	};
+#elif CONFIG_I2S_AUDIO == 2
+	sound-i2s {	/* Audio codec on LEC-Base R2 carrier */
+		compatible = "fsl,imx-audio-sgtl5000";
+		model = "imx-sgtl5000";
+		ssi-controller = <&ssi2>;
+		mux-int-port = <2>;
+		mux-ext-port = <3>;
+		audio-codec = <&codec>;
+		asrc-controller = <&asrc>;
+		audio-routing =
+			"MIC_IN", "Mic Jack",
+			"Mic Jack", "Mic Bias",
+			"LINE_IN", "Line In Jack",
+		//	"Headphone Jack", "HP_OUT",
+			"Line Out Jack", "LINE_OUT";
+	};
+#endif
+
+	sound-hdmi {
+		compatible = "fsl,imx6q-audio-hdmi",
+			     "fsl,imx-audio-hdmi";
+		model = "imx-audio-hdmi";
+		hdmi-controller = <&hdmi_audio>;
+	};
+
+	sound-spdif {
+		compatible = "fsl,imx-audio-spdif";
+		model = "imx-spdif";
+		spdif-controller = <&spdif>;
+		spdif-in;
+		spdif-out;
+	};
+
+	mxcfb1: fb at 0 {	/* IPU1 DI1: /dev/fb0=HDMI, fb1=IPU1's overlay */
+		compatible = "fsl,mxc_sdc_fb";
+		disp_dev = "hdmi";
+		interface_pix_fmt = "RGB24";
+		mode_str ="1920x1080M at 60";
+		default_bpp = <24>;
+		int_clk = <0>;
+		late_init = <0>;
+		status = "okay";
+	};
+
+	mxcfb2: fb at 1 {	/* IPU1 DI0: /dev/fb2=parallel RGB */
+		compatible = "fsl,mxc_sdc_fb";
+		disp_dev = "lcd";
+		interface_pix_fmt = "RGB24";
+		mode_str ="CLAA-WVGA";
+		default_bpp = <24>;
+		int_clk = <0>;
+		late_init = <0>;
+		status = "okay";
+	};
+
+	mxcfb3: fb at 2 {	/* IPU2 DI0: /dev/fb3=LVDS, fb4=IPU2's overlay
+		         * Solo/DL: IPU1, fb2 competing with par. RGB, no overlay */
+		compatible = "fsl,mxc_sdc_fb";
+		disp_dev = "ldb";
+		interface_pix_fmt = "RGB24";
+		default_bpp = <24>;
+		int_clk = <0>;
+		late_init = <0>;
+		status = "okay";
+	};
+
+	rgb: lcd at 0 {	/* parallel RGB (see fb above) */
+		compatible = "fsl,lcd";
+		ipu_id = <0>;
+		disp_id = <0>;
+		default_ifmt = "RGB24";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ipu1>;
+		disp-power-on-supply = <&reg_smarc_lcd_vdd>; /* unsupported by driver */
+		status = "okay";
+	};
+
+	backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm1 0 5000000>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+		enable-gpios = <&gpio6 10 GPIO_ACTIVE_HIGH>; /* SMARC LCD_BKLT_EN */
+		status = "okay";
+	};
+
+#ifdef CONFIG_PAR_CAMERA
+	v4l2_cap_0 {
+		compatible = "fsl,imx6q-v4l2-capture";
+		ipu_id = <0>;
+		csi_id = <0>;
+		mclk_source = <0>;
+		status = "okay";
+	};
+#endif
+
+#ifdef CONFIG_SER_CAMERA
+	v4l2_cap_1 {
+		compatible = "fsl,imx6q-v4l2-capture";
+		ipu_id = <0>;
+		csi_id = <1>;
+		mclk_source = <0>;
+		status = "okay";
+	};
+#endif
+
+	v4l2_out {
+		compatible = "fsl,mxc_v4l2_output";
+		status = "okay";
+	};
+};
+
+#if VPU_CODA
+&vpu {
+	status = "okay";
+};
+&vpu_fsl {
+	status = "disabled";
+};
+#endif
+
+#if CONFIG_I2S_AUDIO
+&audmux {	/* SMARC I2S0 (instead of SPI0) */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_audmux>;
+	/* Freescale-specific; vanilla relies on U-Boot to set GPIO accordingly. */
+	//pinctrl-assert-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; /* AEN# */
+	status = "okay";
+};
+#endif
+
+&cpu0 {
+#if LDO_BYPASS
+	arm-supply = <&sw1a_reg>;
+	soc-supply = <&sw1c_reg>;
+#else
+	arm-supply = <&reg_arm>;
+	soc-supply = <&reg_soc>;
+#endif
+};
+
+&clks {
+	fsl,ldb-di0-parent = <&clks IMX6QDL_CLK_PLL2_PFD0_352M>; /* LVDS */
+	fsl,ldb-di1-parent = <&clks IMX6QDL_CLK_PLL2_PFD0_352M>; /* unused */
+};
+
+#if !CONFIG_I2S_AUDIO
+&ecspi1 {	/* SMARC SPI0 (instead of I2S0) */
+	fsl,spi-num-chipselects = <2>;
+	cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>, /* SMARC CS0 */
+	           <&gpio3 24 GPIO_ACTIVE_LOW>; /* SMARC CS1 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi1>;
+	/* Freescale-specific; vanilla relies on U-Boot to set GPIO accordingly. */
+	//pinctrl-assert-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; /* AEN# */
+	status = "okay";
+
+	tsc2046 at 0 {		/* Touch screen controller on LEC-Base R1 carrier */
+		compatible = "ti,tsc2046";
+		reg = <0>;
+		vcc-supply = <&reg_smarc_lcd_vdd>;
+		spi-max-frequency = <2500000>;
+		interrupt-parent = <&smarc_gpio>;
+		interrupts = <10 IRQ_TYPE_EDGE_FALLING>; /* SMARC GPIO10 */
+		pendown-gpio = <&smarc_gpio 10 GPIO_ACTIVE_LOW>;
+		ti,vref-mv = /bits/ 16 <3300>;
+	};
+};
+#endif
+
+&ecspi2 {	/* SMARC SPI1 */
+	fsl,spi-num-chipselects = <2>;
+	cs-gpios = <&gpio2 27 GPIO_ACTIVE_LOW>, /* SMARC CS0 */
+	           <&gpio2 26 GPIO_ACTIVE_LOW>; /* SMARC CS1 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi2>;
+	status = "okay";
+};
+
+&ecspi4 {	/* on-module U-Boot SPI */
+	fsl,spi-num-chipselects = <1>;
+	cs-gpios = <&gpio3 25 GPIO_ACTIVE_LOW>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi4>;
+	status = "okay";
+
+	flash: m25p80 at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "winbond,w25q64";
+		spi-max-frequency = <66000000>; /* slowest we used was SST25VF032B; i.MX6 provides 60MHz max */
+		reg = <0>;
+		m25p,fast-read;
+	};
+};
+
+&fec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet>;
+	phy-mode = "rgmii";
+	phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; /* RGMII_nRST */
+	/* Can't power off phy because sw2_reg is permanently needed. We could
+	 * turn off i.MX6's NVCC_RGMII (I/O voltage) only, but that's risky when
+	 * the phy remains powered. */
+	//phy-supply = <&vgen1_reg>;
+	fsl,magic-packet;
+	status = "okay";
+};
+
+&can1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_flexcan1>;
+	/* The next 2 options are documented, but not implemented by Freescale's
+	 * driver. Their recent DTs replace trx-stby-gpio and trx-en-gpio (also
+	 * missing) with 'xceiver-supply' regulators (is this really the same?),
+	 * however we won't bother, the GPIOs don't connect anyway. */
+	//trx-nerr-gpio = <&smarc_gpio 8 GPIO_ACTIVE_LOW>; /* SMARC GPIO8/CAN0_ERR#, unused on LEC-Base carrier */
+	//trx-stby-gpio = <&carrier_misc_control 1 GPIO_ACTIVE_HIGH>; /* CAN1_STB, solder jumper not populated */
+	status = "okay";
+};
+
+&can2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_flexcan2>;
+	//trx-nerr-gpio = <&smarc_gpio 9 GPIO_ACTIVE_LOW>; /* SMARC GPIO9/CAN1_ERR#, unused on LEC-Base carrier */
+	//trx-stby-gpio = <&carrier_misc_control 2 GPIO_ACTIVE_HIGH>; /* CAN2_STB, solder jumper not populated */
+	status = "okay";
+};
+
+&gpc {
+	fsl,ldo-bypass = <LDO_BYPASS>; /* U-Boot will check it and configure */
+};
+
+&dcic1 {
+	dcic_id = <0>;
+	dcic_mux = "dcic-hdmi";
+	status = "okay";
+};
+
+&dcic2 {
+	dcic_id = <1>;
+	dcic_mux = "dcic-lvds0";
+	status = "okay";
+};
+
+&hdmi_audio {
+	status = "okay";
+};
+
+&hdmi_cec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hdmi_cec>;
+	status = "okay";
+};
+
+&hdmi_core {		/* HDMI (see fb above) */
+	ipu_id = <0>;
+	disp_id = <1>;
+	status = "okay";
+};
+
+&hdmi_video {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hdmi_hdcp>;
+	fsl,hdcp; /* also means we use the dedicated DDC function */
+	fsl,phy_reg_vlev = <0x03f4>;
+	fsl,phy_reg_cksymtx = <0x800f>;
+	status = "okay";
+};
+
+&i2c1 {		/* RTC, optional PCIe switch, SMARC I2C_CAM */
+	clock-frequency = <100000>; /* 66 MHz / 768 = 86 kHz */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	status = "okay";
+
+	pcf8563 at 51 {				/* Real Time Clock */
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+	};
+
+	pex8605 at 58 {				/* optional PCIe switch */
+		compatible = "plx,pex8605"; /* guessing, no driver found */
+		reg = <0x58>;
+	};
+
+#if CONFIG_I2S_AUDIO == 2
+	codec: sgtl5000 at 0a {		/* Audio codec on LEC-Base R2 carrier */
+		compatible = "fsl,sgtl5000";
+		reg = <0x0a>;
+		clocks = <&clks IMX6QDL_CLK_CKO>; /* SMARC AUDIO_MCK, actually unused on carrier */
+		VDDA-supply = <&reg_base_3v3>;
+		VDDIO-supply = <&reg_base_1v8>;
+		VDDD-supply = <&reg_base_1v8>;
+		micbias-resistor-k-ohms = <4>;
+		micbias-voltage-m-volts = <1250>;
+	};
+#endif
+
+	carrier_misc_control: pcf8575 at 20 {	/* GPIO expander on LEC-Base R1 carrier */
+		compatible = "nxp,pcf8575";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		/* 0: HUB1_RESET	 8: 3G1_DISABLE#
+		 * 1: CAN1_STB (NC)	 9: 3G1_DOWN#
+		 * 2: CAN2_STB (NC)	10: 3G2_DISABLE#
+		 * 3: LCD_RESET# (NC)	11: 3G2_DOWN#
+		 * 4: SUP_RESET# (NC)	12: HDMI_RESET#
+		 * 5: LVDS_VDD_EN	13: 3G_PW_EN
+		 * 6: CAM_PW_EN (NC)	14: PCAM_LE#
+		 * 7: GPS_VDD_EN	15: HUB2_RESET */
+		lines-initial-states = <0xc001>; /* bitmask: 0=high(!)/input, 1=pulled low */
+	};
+
+#ifdef CONFIG_PAR_CAMERA
+	ov564x at CONFIG_PAR_CAMERA {		/* Parallel camera connected to carrier */
+		compatible = "ovti,ov564x";
+		reg = <_0x(CONFIG_PAR_CAMERA)>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ipu1_pcam>;
+		clocks = <&clks IMX6QDL_CLK_CKO>;
+		clock-names = "csi_mclk";
+		pwn-gpios = <&gpio6 14 GPIO_ACTIVE_HIGH>; /* SMARC GPIO1/CAM1_PWR# */
+		rst-gpios = <&gpio6 16 GPIO_ACTIVE_LOW>;  /* SMARC GPIO3/CAM1_RST# */
+		csi_id = <0>; /* but on SMARC CSI1_...! */
+		mclk = <24000000>;
+		mclk_source = <0>;
+	};
+#endif
+
+#ifdef CONFIG_SER_CAMERA
+	ov564x_mipi at CONFIG_SER_CAMERA {		/* Serial camera connected to carrier */
+		compatible = "ovti,ov564x_mipi";
+		reg = <_0x(CONFIG_SER_CAMERA)>;
+		clocks = <&clks IMX6QDL_CLK_CKO>;
+		clock-names = "csi_mclk";
+		pwn-gpios = <&gpio6 11 GPIO_ACTIVE_HIGH>; /* SMARC GPIO0/CAM0_PWR# */
+		rst-gpios = <&gpio6 15 GPIO_ACTIVE_LOW>;  /* SMARC GPIO2/CAM0_RST# */
+		csi_id = <1>; /* but on SMARC CSI0_...! */
+		mclk = <24000000>;
+		mclk_source = <0>;
+	};
+#endif
+};
+
+&i2c2 {		/* PFUZE100 PMIC, SMARC I2C_LCD, SMARC I2C_GP */
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	status = "okay";
+
+	pmic: pfuze100 at 08 {
+		compatible = "fsl,pfuze100";
+		reg = <0x08>;
+
+		regulators {
+			sw1a_reg: sw1ab { /* VDDCORE: VDDARM */
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1875000>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <6250>;
+			};
+
+			sw1c_reg: sw1c { /* VDDSOC */
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1875000>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <6250>;
+			};
+
+			sw2_reg: sw2 { /* GEN_3V3: NVCC_ENET (eth mac), eth phy, USB hub, eMMC, lots of misc stuff */
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <6250>;
+			};
+
+			sw3a_reg: sw3a { /* DDR_1V5 */
+				regulator-min-microvolt = <400000>;
+				regulator-max-microvolt = <1975000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sw3b_reg: sw3b { /* dito */
+				regulator-min-microvolt = <400000>;
+				regulator-max-microvolt = <1975000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sw4_reg: sw4 { /* PMIC_1V8: VDD_IO and lots of stuff everywhere */
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			swbst_reg: swbst { /* PMIC_5V: USB h1 Vbus (for phy, rest is provided by carrier) */
+				regulator-min-microvolt = <5000000>;
+				regulator-max-microvolt = <5150000>;
+				regulator-boot-on;
+			};
+
+			snvs_reg: vsnvs { /* PMIC_VSNVS (3V) */
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			vref_reg: vrefddr { /* DDR_VREF */
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			vgen1_reg: vgen1 { /* VGEN1_1V5: NVCC_RGMII (i.MX6's I/O to external eth phy) */
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1550000>;
+				regulator-boot-on;
+				regulator-always-on; /* we can't power off phy itself */
+			};
+
+			vgen2_reg: vgen2 { /* unused */
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1550000>;
+			};
+
+			vgen3_reg: vgen3 { /* VGEN3_2V5: NVCC_LVDS (LVDS, DRAM, RGMII), SPI/I2S mux */
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on; /* despite its name, NVCC_LVDS also supplies DRAM_IO */
+			};
+
+			vgen4_reg: vgen4 { /* VDDHIGH_IN (2.8V): SATA, PCIe, HDMI, MIPI, LVDS, USB, PLLs */
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			vgen5_reg: vgen5 { /* dito, but unused per default (since LEC-iMX6 rev A4) */
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				//regulator-always-on; /* solder jumper */
+			};
+
+			vgen6_reg: vgen6 { /* VGEN6_3V3: PCIe switch, PCIe reset */
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				/* no driver for PCIe switch, no regulator in i.MX6 driver and we couldn't
+				   power down carrier devices or host, only PCIe switch in between */
+				regulator-always-on;
+			};
+		};
+	};
+
+#if CONFIG_I2S_AUDIO == 1
+	codec: tlv320aic23 at 1a {		/* Audio codec on LEC-Base R1 carrier */
+		compatible = "ti,tlv320aic23";
+		reg = <0x1a>;
+		clocks = <&clks IMX6QDL_CLK_CKO>; /* SMARC AUDIO_MCK, actually unused on carrier */
+	};
+#endif
+
+	/* Current driver depends on MXS framebuffer not present on i.MX6Q/D/DL/S.
+	 * Also assuming LEC-Base R1 JP3=1-2, JP15=2-3. */
+	sii902x at 39 {			/* HDMI transmitter on LEC-Base R1 carrier */
+		compatible = "SiI,sii902x";
+		reg = <0x39>;
+		interrupt-parent = <&smarc_gpio>;
+		interrupts = <4 IRQ_TYPE_EDGE_FALLING>; /* SMARC GPIO4/HDA_RST# */
+		mode_str = "1280x720M at 60";
+		bits-per-pixel = <32>;
+	};
+
+	mma7660 at 4c {			/* Accelerometer on LEC-Base R1 carrier */
+		compatible = "fsl,mma7660"; /* guessing, no driver mainlined */
+		reg = <0x4c>;
+		interrupt-parent = <&smarc_gpio>;
+		interrupts = <11 IRQ_TYPE_LEVEL_LOW>; /* SMARC GPIO11 */
+	};
+
+	at24c08 at 54 {			/* 1KB EEPROM on LEC-Base R1 carrier */
+		compatible = "atmel,24c08";
+		reg = <0x54>;
+		pagesize = <16>;
+	};
+
+	/* Driver disabled in defconfig, we have an on-module RTC already. */
+	ds1337 at 68 {			/* RTC on LEC-Base R1 carrier */
+		compatible = "maxim,ds1337";
+		reg = <0x68>;
+	};
+};
+
+&i2c3 {		/* GPIO expander, SEMA BMC, SMARC I2C_PM */
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	status = "okay";
+
+	smarc_gpio: pca9535 at 20 {	/* GPIO expander */
+		/* GPIOs 4-6, 8-11 map directly to the SMARC connector's GPIOx.
+		 * GPIOs 0-3, 7 are unused unless a solder jumper is changed, per default
+		 * SMARC GPIO0-3,7 are provided by the i.MX6 (CAM0/1_PWR/RST#,PCAM_FLD). */
+		compatible = "nxp,pca9535";
+		reg = <0x20>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <29 IRQ_TYPE_LEVEL_LOW>; /* GPIO_INT_B */
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	sema_bmc at 28 {			/* SEMA Board Management Controller */
+		compatible = "adlink,sema_bmc"; /* no driver needed */
+		reg = <0x28>;
+	};
+
+	ltc1760 at 0a {			/* Battery charger on LEC-Base R1 carrier */
+		compatible = "linear,ltc1760"; /* guessing, no driver found */
+		reg = <0x0a>;
+	};
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hog>;
+
+	lec-imx6 {
+		pinctrl_hog: hoggrp {
+			fsl,pins = <
+				/* Native pad functions */
+				MX6QDL_PAD_GPIO_0__CCM_CLKO1		0x130b0
+				/* Pads used for GPIOs */
+				MX6QDL_PAD_GPIO_3__GPIO1_IO03        0x80000000 /* AEN# (mux: 0=SPI0, 1=I2S0) */
+				MX6QDL_PAD_ENET_TXD1__GPIO1_IO29     0x80000000 /* GPIO_INT_B */
+				MX6QDL_PAD_NANDF_CS0__GPIO6_IO11     0x80000000 /* SMARC GPIO0/CAM0_PWR# */
+				MX6QDL_PAD_NANDF_CS1__GPIO6_IO14     0x80000000 /* SMARC GPIO1/CAM1_PWR# */
+				MX6QDL_PAD_NANDF_CS2__GPIO6_IO15     0x80000000 /* SMARC GPIO2/CAM0_RST# */
+				MX6QDL_PAD_NANDF_CS3__GPIO6_IO16     0x80000000 /* SMARC GPIO3/CAM1_RST# */
+				MX6QDL_PAD_NANDF_CLE__GPIO6_IO07     0x80000000 /* SMARC GPIO7/PCAM_FLD */
+			>;
+		};
+
+		pinctrl_regulators: regulatorsgrp {
+			fsl,pins = <
+				MX6QDL_PAD_ENET_TXD0__GPIO1_IO30     0x80000000 /* SMARC LCD_VDD_EN */
+				MX6QDL_PAD_ENET_RXD0__GPIO1_IO27	0x1a8b0 /* SMARC USB0_EN_OC# (open-drain) */
+				MX6QDL_PAD_EIM_D29__GPIO3_IO29		0x1a8b0 /* SMARC USB1_EN_OC# (open-drain) */
+				MX6QDL_PAD_EIM_D30__GPIO3_IO30		0x1a8b0 /* SMARC USB2_EN_OC# (open-drain) */
+				MX6QDL_PAD_KEY_ROW2__GPIO4_IO11      0x80000000 /* SMARC SDIO_PWR_EN */
+				//MX6QDL_PAD_GPIO_18__GPIO7_IO13     0x80000000 /* PMIC_INT_B */
+			>;
+		};
+
+#if CONFIG_I2S_AUDIO
+		pinctrl_audmux: audmuxgrp {
+			fsl,pins = <	/* SMARC I2S0 (instead of SPI0) */
+				MX6QDL_PAD_CSI0_DAT7__AUD3_RXD		0x130b0
+				MX6QDL_PAD_CSI0_DAT4__AUD3_TXC		0x130b0
+				MX6QDL_PAD_CSI0_DAT5__AUD3_TXD		0x110b0
+				MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS		0x130b0
+			>;
+		};
+#else
+		pinctrl_ecspi1: ecspi1grp {
+			fsl,pins = <	/* SMARC SPI0 (instead of I2S0) */
+				MX6QDL_PAD_CSI0_DAT6__ECSPI1_MISO	0x100b1
+				MX6QDL_PAD_CSI0_DAT5__ECSPI1_MOSI	0x100b1
+				MX6QDL_PAD_CSI0_DAT4__ECSPI1_SCLK	0x100b1
+				MX6QDL_PAD_CSI0_DAT7__GPIO5_IO25	0x1b0b0 /* SMARC CS0 */
+				MX6QDL_PAD_EIM_D24__GPIO3_IO24		0x1b0b0 /* SMARC CS1 */
+			>;
+		};
+#endif
+
+		pinctrl_ecspi2: ecspi2grp {
+			fsl,pins = <	/* SMARC SPI1 */
+				MX6QDL_PAD_EIM_OE__ECSPI2_MISO		0x100b1
+				MX6QDL_PAD_EIM_CS1__ECSPI2_MOSI		0x100b1
+				MX6QDL_PAD_EIM_CS0__ECSPI2_SCLK		0x100b1
+				MX6QDL_PAD_EIM_RW__GPIO2_IO26		0x1b0b0 /* SMARC CS1 */
+				MX6QDL_PAD_EIM_LBA__GPIO2_IO27		0x1b0b0 /* SMARC CS0 */
+			>;
+		};
+
+		pinctrl_ecspi4: ecspi4grp {
+			fsl,pins = <	/* on-module U-Boot SPI */
+				MX6QDL_PAD_EIM_D22__ECSPI4_MISO		0x100b1
+				MX6QDL_PAD_EIM_D28__ECSPI4_MOSI		0x100b1
+				MX6QDL_PAD_EIM_D21__ECSPI4_SCLK		0x100b1
+				MX6QDL_PAD_EIM_D25__GPIO3_IO25		0x1b0b0 /* CS3 */
+			>;
+		};
+
+		pinctrl_enet: enetgrp {
+			fsl,pins = <
+				MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x1b0b0
+				MX6QDL_PAD_ENET_MDC__ENET_MDC		0x1b0b0
+				MX6QDL_PAD_RGMII_TXC__RGMII_TXC		0x1b0b8 /* serial resistor added */
+				MX6QDL_PAD_RGMII_TD0__RGMII_TD0		0x1b0b0
+				MX6QDL_PAD_RGMII_TD1__RGMII_TD1		0x1b0b0
+				MX6QDL_PAD_RGMII_TD2__RGMII_TD2		0x1b0b0
+				MX6QDL_PAD_RGMII_TD3__RGMII_TD3		0x1b0b0
+				MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	0x1b0b0
+				MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK	0x1b0b0
+				MX6QDL_PAD_RGMII_RXC__RGMII_RXC		0x1b0b0
+				MX6QDL_PAD_RGMII_RD0__RGMII_RD0		0x1b0b0
+				MX6QDL_PAD_RGMII_RD1__RGMII_RD1		0x1b0b0
+				MX6QDL_PAD_RGMII_RD2__RGMII_RD2		0x1b0b0
+				MX6QDL_PAD_RGMII_RD3__RGMII_RD3		0x1b0b0
+				MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x1b0b0
+				MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25   0x80000000 /* RGMII_nRST */
+				//MX6QDL_PAD_ENET_RXD1__GPIO1_IO26   0x80000000 /* RGMII_INT */
+				/* For the workaround improving network latency described in i.MX6
+				 * erratum 6687 disable the power button, re-mux as follows and
+				 * add "interrupts-extended" as in imx6q-sabresd-enetirq.dts. */
+				//MX6QDL_PAD_GPIO_6__ENET_IRQ		0x000b1
+			>;
+		};
+
+		pinctrl_flexcan1: flexcan1grp {
+			fsl,pins = <	/* SMARC CAN0 */
+				MX6QDL_PAD_SD3_CMD__FLEXCAN1_TX		0x17059
+				MX6QDL_PAD_SD3_CLK__FLEXCAN1_RX		0x17059
+			>;
+		};
+
+		pinctrl_flexcan2: flexcan2grp {
+			fsl,pins = <	/* SMARC CAN1 */
+				MX6QDL_PAD_SD3_DAT0__FLEXCAN2_TX	0x17059
+				MX6QDL_PAD_SD3_DAT1__FLEXCAN2_RX	0x17059
+			>;
+		};
+
+		pinctrl_gpio_keys: gpio_keysgrp {
+			fsl,pins = <
+				MX6QDL_PAD_GPIO_7__GPIO1_IO07		0x1b0b0 /* SMARC LID# */
+				MX6QDL_PAD_GPIO_6__GPIO1_IO06		0x1b0b0 /* SMARC POWER_BTN# */
+				MX6QDL_PAD_NANDF_D7__GPIO2_IO07		0x1b0b0 /* SMARC SLEEP# */
+				MX6QDL_PAD_GPIO_8__GPIO1_IO08		0x1b0b0 /* SMARC TEST# */
+			>;
+		};
+
+		pinctrl_hdmi_cec: hdmicecgrp {
+			fsl,pins = <
+				MX6QDL_PAD_EIM_A25__HDMI_TX_CEC_LINE	0x108b0
+			>;
+		};
+
+		pinctrl_hdmi_hdcp: hdmihdcpgrp {
+			fsl,pins = <
+				MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
+				MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
+			>;
+		};
+
+		pinctrl_i2c1: i2c1grp {
+			fsl,pins = <
+				MX6QDL_PAD_CSI0_DAT8__I2C1_SDA		0x4001b8b1
+				MX6QDL_PAD_CSI0_DAT9__I2C1_SCL		0x4001b8b1
+			>;
+		};
+
+		pinctrl_i2c2: i2c2grp {
+			fsl,pins = <
+				MX6QDL_PAD_EIM_EB2__I2C2_SCL		0x4001b8b1
+				MX6QDL_PAD_EIM_D16__I2C2_SDA		0x4001b8b1
+			>;
+		};
+
+		pinctrl_i2c3: i2c3grp {
+			fsl,pins = <
+				MX6QDL_PAD_EIM_D17__I2C3_SCL		0x4001b8b1
+				MX6QDL_PAD_EIM_D18__I2C3_SDA		0x4001b8b1
+			>;
+		};
+
+		pinctrl_ipu1: ipu1grp {
+			fsl,pins = <
+				MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK       0xf1
+				MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15             0xf1
+				MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02              0xf1
+				MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03              0xf1
+				MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04        0x80000000
+				MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00         0xf1
+				MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01         0xf1
+				MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02         0xf1
+				MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03         0xf1
+				MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04         0xf1
+				MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05         0xf1
+				MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06         0xf1
+				MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07         0xf1
+				MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08         0xf1
+				MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09         0xf1
+				MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10        0xf1
+				MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11        0xf1
+				MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12        0xf1
+				MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13        0xf1
+				MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14        0xf1
+				MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15        0xf1
+				MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16        0xf1
+				MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17        0xf1
+				MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18        0xf1
+				MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19        0xf1
+				MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20        0xf1
+				MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21        0xf1
+				MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22        0xf1
+				MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23        0xf1
+			>;
+		};
+
+#ifdef CONFIG_PAR_CAMERA
+		pinctrl_ipu1_pcam: ipu1_pcamgrp {
+			fsl,pins = <	/* SMARC PCAM */
+				MX6QDL_PAD_CSI0_DAT10__IPU1_CSI0_DATA10    0x80000000
+				MX6QDL_PAD_CSI0_DAT11__IPU1_CSI0_DATA11    0x80000000
+				MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12    0x80000000
+				MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13    0x80000000
+				MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14    0x80000000
+				MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15    0x80000000
+				MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16    0x80000000
+				MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17    0x80000000
+				MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18    0x80000000
+				MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19    0x80000000
+				MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK   0x80000000
+				MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC      0x80000000
+				MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC     0x80000000
+			>;
+		};
+#endif
+
+		pinctrl_pcie: pciegrp {
+			fsl,pins = <
+				MX6QDL_PAD_GPIO_17__GPIO7_IO12		0x1b0b0 /* PCIE_RST_B */
+				MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20	0x1b0b0 /* PCIE_WAKE_B */
+			>;
+		};
+
+		pinctrl_pwm1: pwm1grp {
+			fsl,pins = <
+				MX6QDL_PAD_NANDF_RB0__GPIO6_IO10     0x80000000 /* SMARC LCD_BKLT_EN */
+				MX6QDL_PAD_GPIO_9__PWM1_OUT		0x1b0b1 /* SMARC LCD_BKLT_PWM */
+			>;
+		};
+
+		pinctrl_spdif: spdifgrp {
+			fsl,pins = <	/* SMARC SPDIF_IN/OUT */
+				MX6QDL_PAD_GPIO_16__SPDIF_IN		0x1b0b0
+				MX6QDL_PAD_GPIO_19__SPDIF_OUT		0x1b0b0
+			>;
+		};
+
+		pinctrl_uart1: uart1grp {
+			fsl,pins = <	/* SMARC SER0 */
+				MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA	0x1b0b1
+				MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA	0x1b0b1
+				MX6QDL_PAD_EIM_D19__UART1_CTS_B		0x1b0b1
+				MX6QDL_PAD_EIM_D20__UART1_RTS_B		0x1b0b1
+			>;
+		};
+
+		pinctrl_uart2: uart2grp {
+			fsl,pins = <	/* SMARC SER1 */
+				MX6QDL_PAD_EIM_D26__UART2_TX_DATA	0x1b0b1
+				MX6QDL_PAD_EIM_D27__UART2_RX_DATA	0x1b0b1
+			>;
+		};
+
+		pinctrl_uart4: uart4grp {
+			fsl,pins = <	/* SMARC SER3 */
+				MX6QDL_PAD_KEY_COL0__UART4_TX_DATA	0x1b0b1
+				MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA	0x1b0b1
+			>;
+		};
+
+		pinctrl_uart5: uart5grp {
+			fsl,pins = <	/* SMARC SER2 */
+				MX6QDL_PAD_KEY_COL1__UART5_TX_DATA	0x1b0b1
+				MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA	0x1b0b1
+				MX6QDL_PAD_KEY_COL4__UART5_RTS_B	0x1b0b1
+				MX6QDL_PAD_KEY_ROW4__UART5_CTS_B	0x1b0b1
+			>;
+		};
+
+		pinctrl_usbotg: usbotggrp {
+			fsl,pins = <	/* SMARC USB0 */
+				MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID	0x17059
+			>;
+		};
+
+		pinctrl_usdhc1: usdhc1grp {
+			fsl,pins = <	/* on-module eMMC */
+				MX6QDL_PAD_SD1_CMD__SD1_CMD		0x17059
+				MX6QDL_PAD_SD1_CLK__SD1_CLK		0x10059
+				MX6QDL_PAD_SD1_DAT0__SD1_DATA0		0x17059
+				MX6QDL_PAD_SD1_DAT1__SD1_DATA1		0x17059
+				MX6QDL_PAD_SD1_DAT2__SD1_DATA2		0x17059
+				MX6QDL_PAD_SD1_DAT3__SD1_DATA3		0x17059
+				MX6QDL_PAD_NANDF_D0__SD1_DATA4		0x17059
+				MX6QDL_PAD_NANDF_D1__SD1_DATA5		0x17059
+				MX6QDL_PAD_NANDF_D2__SD1_DATA6		0x17059
+				MX6QDL_PAD_NANDF_D3__SD1_DATA7		0x17059
+			>;
+		};
+
+		pinctrl_usdhc2: usdhc2grp {
+			fsl,pins = <	/* SMARC SDIO */
+				MX6QDL_PAD_SD2_CMD__SD2_CMD		0x17059
+				MX6QDL_PAD_SD2_CLK__SD2_CLK		0x10059
+				MX6QDL_PAD_SD2_DAT0__SD2_DATA0		0x17059
+				MX6QDL_PAD_SD2_DAT1__SD2_DATA1		0x17059
+				MX6QDL_PAD_SD2_DAT2__SD2_DATA2		0x17059
+				MX6QDL_PAD_SD2_DAT3__SD2_DATA3		0x17059
+				//MX6QDL_PAD_GPIO_4__SD2_CD_B	     0x80000000 /* controller internal CD doesn't work */
+				MX6QDL_PAD_GPIO_4__GPIO1_IO04	     0x80000000 /* SD2_CD_B: mux as GPIO instead */
+				MX6QDL_PAD_GPIO_2__SD2_WP	     0x80000000
+			>;
+		};
+
+		pinctrl_usdhc4: usdhc4grp {
+			fsl,pins = <	/* SMARC SDMMC */
+				MX6QDL_PAD_SD4_CMD__SD4_CMD		0x17059
+				MX6QDL_PAD_SD4_CLK__SD4_CLK		0x10059
+				MX6QDL_PAD_SD4_DAT0__SD4_DATA0		0x17059
+				MX6QDL_PAD_SD4_DAT1__SD4_DATA1		0x17059
+				MX6QDL_PAD_SD4_DAT2__SD4_DATA2		0x17059
+				MX6QDL_PAD_SD4_DAT3__SD4_DATA3		0x17059
+				MX6QDL_PAD_SD4_DAT4__SD4_DATA4		0x17059
+				MX6QDL_PAD_SD4_DAT5__SD4_DATA5		0x17059
+				MX6QDL_PAD_SD4_DAT6__SD4_DATA6		0x17059
+				MX6QDL_PAD_SD4_DAT7__SD4_DATA7		0x17059
+				MX6QDL_PAD_NANDF_ALE__SD4_RESET	     0x80000000
+			>;
+		};
+
+		pinctrl_wdog: wdoggrp {
+			fsl,pins = <
+				MX6QDL_PAD_GPIO_1__WDOG2_B 0x80000000
+			>;
+		};
+	};
+};
+
+&ldb {		/* LVDS (see fb above) */
+	disp-power-on-supply = <&reg_smarc_lcd_vdd>; /* unsupported by driver */
+	status = "okay";
+
+	lvds-channel at 0 {
+		fsl,data-mapping = "spwg"; /* spwg or jeida (see chapter "Bit Mapping" in i.MX6 Reference Manual) */
+		fsl,data-width = <24>;
+		primary;
+		status = "okay";
+
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: hsd100pxn1 {
+				clock-frequency = <65000000>;
+				hactive = <1024>;
+				vactive = <768>;
+				hback-porch = <220>;
+				hfront-porch = <40>;
+				vback-porch = <21>;
+				vfront-porch = <7>;
+				hsync-len = <60>;
+				vsync-len = <10>;
+			};
+		};
+	};
+};
+
+#ifdef CONFIG_SER_CAMERA
+&mipi_csi {
+	ipu_id = <0>;
+	csi_id = <1>;
+	v_channel = <0>;
+	lanes = <2>;
+	status = "okay";
+};
+#endif
+
+&mlb {		/* SMARC AFB_DIFF1-3 */
+	/* Driver doesn't seem to support differential (6-pin) mode. */
+	//status = "okay";
+};
+
+&pcie {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pcie>;
+	reset-gpio = <&gpio7 12 GPIO_ACTIVE_LOW>; /* PCIE_RST_B */
+	/* Next line has no effect: half-implemented in older kernels, Freescale
+	 * now removed code completely; gpio-key can serve as workaround. */
+	wake-up-gpio = <&gpio5 20 GPIO_ACTIVE_LOW>; /* PCIE_WAKE_B */
+	status = "okay";
+};
+
+&pwm1 {		/* SMARC LCD_BKLT_PWM */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm1>;
+	status = "okay";
+};
+
+&snvs_poweroff {
+	status = "okay";
+};
+
+&spdif {	/* SMARC SPDIF_IN/OUT */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spdif>;
+	assigned-clocks = <&clks IMX6QDL_CLK_SPDIF_SEL>, <&clks IMX6QDL_CLK_SPDIF_PODF>;
+	assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_PFD3_454M>;
+	assigned-clock-rates = <0>, <227368421>;
+	status = "okay";
+};
+
+#if CONFIG_I2S_AUDIO
+&ssi2 {		/* SMARC I2S0 (instead of SPI0) */
+	status = "okay";
+};
+#endif
+
+&uart1 {	/* SMARC SER0 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+	fsl,uart-has-rtscts;
+	status = "okay";
+};
+
+&uart2 {	/* SMARC SER1 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	status = "okay";
+};
+
+&uart4 {	/* SMARC SER3 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart4>;
+	status = "okay";
+};
+
+&uart5 {	/* SMARC SER2 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart5>;
+	fsl,uart-has-rtscts;
+	status = "okay";
+};
+
+&usbh1 {	/* SMARC USB1,2 */
+	vbus-supply = <&reg_smarc_usb2>; /* chained with usb1, see above */
+	disable-over-current; /* connects to SMARC USB2_EN_OC# but not USB1_ */
+	status = "okay";
+};
+
+&usbotg {	/* SMARC USB0 */
+	vbus-supply = <&reg_smarc_usb0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbotg>;
+	//dr_mode = "peripheral"; /* default is "otg", override with "host" or "peripheral" to set fixed role */
+	disable-over-current;
+	srp-disable;
+	hnp-disable;
+	adp-disable;
+	status = "okay";
+};
+
+&usbphy1 {
+	tx-d-cal = <0x5>;
+};
+
+&usbphy2 {
+	tx-d-cal = <0x5>;
+};
+
+&usdhc1 {	/* on-module eMMC */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	bus-width = <8>;
+	non-removable;
+	status = "okay";
+};
+
+&usdhc2 {	/* SMARC SDIO */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc2>;
+	bus-width = <4>;
+	//fsl,cd-controller; /* using controller internal CD doesn't work properly */
+	cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; /* need to treat it as GPIO instead */
+	fsl,wp-controller;
+	vmmc-supply = <&reg_smarc_sdio_pwr>;
+	vqmmc-supply = <&reg_smarc_sdio_pwr>;
+	no-1-8-v; /* LEC-Base carriers have pull-ups (3.3V) on data lines */
+	//keep-power-in-suspend;
+	//enable-sdio-wakeup;
+	status = "okay";
+};
+
+&usdhc4 {	/* SMARC SDMMC */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc4>;
+	bus-width = <8>;
+	//non-removable; /* eMMC: no polling saves power */
+	broken-cd; /* uSD slot on carrier: polling allows switching cards */
+	no-1-8-v; /* LEC-Base carriers have pull-ups (3.3V) on data lines */
+	status = "okay";
+};
+
+&wdog1 {
+	/* Contrary to other nodes Freescale's dtsi doesn't default to "disabled" here. */
+	status = "disabled";
+};
+
+&wdog2 {
+	/* This is the TrustZone watchdog, however pin mux leaves no other choice.
+	 * We don't need an SoC reset (wdog_rst_b), but WDOG2_B --> system wide POR. */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wdog>;
+	fsl,wdog_b;
+	status = "okay";
+};
--- /dev/null
+++ b/arch/arm/boot/dts/lec-imx6q.dts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014-2016 LiPPERT ADLINK Technology GmbH
+ * Copyright 2012-2015 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "lec-imx6.dtsi"
+
+/ {
+	model = "ADLINK LEC-iMX6 (Quad/Dual) SMARC module";
+	compatible = "adlink,lec-imx6", "fsl,imx6q";
+};
+
+&ldb {		/* LVDS (see fb in lec-imx6.dtsi) */
+	lvds-channel at 0 {
+		crtc = "ipu2-di0";
+	};
+};
+
+&sata {
+	/* Freescale's defaults */
+	fsl,transmit-level-mV = <1025>;
+	fsl,transmit-boost-mdB = <3330>;
+	fsl,transmit-atten-16ths = <9>;
+	fsl,receive-eq-mdB = <3000>;
+	status = "okay";
+};
--- /dev/null
+++ b/arch/arm/boot/dts/lec-imx6s.dts
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014-2016 LiPPERT ADLINK Technology GmbH
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ */
+
+/* The i.MX6 Solo/DualLite only has 1 IPU i.e. can only operate 2 of the 3
+ * display options at the same time. lec-imx6.dtsi assigns the IPU's 2 DIs such
+ * that HDMI always works, whereas parallel RGB and LVDS compete for the same
+ * DI. The following option leaves only one of them enabled. (The Quad/Dual DTS
+ * maps LVDS to the 2nd IPU, enabling all displays simultaneously.) */
+#define CONFIG_SOLO_LVDS	0
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "lec-imx6.dtsi"
+
+/ {
+	model = "ADLINK LEC-iMX6 (Solo/DualLite) SMARC module";
+	compatible = "adlink,lec-imx6", "fsl,imx6dl";
+};
+
+&ldb {		/* LVDS (see fb in lec-imx6.dtsi) */
+	lvds-channel at 0 {
+		crtc = "ipu1-di0";
+	};
+};
+
+#if CONFIG_SOLO_LVDS
+&mxcfb2 {	/* parallel RGB */
+#else
+&mxcfb3 {	/* LVDS */
+#endif
+	status = "disabled";
+};
+
+#if CONFIG_SOLO_LVDS
+&rgb {		/* parallel RGB */
+#else
+&ldb {		/* LVDS */
+#endif
+	status = "disabled";
+};
+
+&pxp {
+	status = "okay";
+};
--- /dev/null
+++ b/arch/arm/configs/lec-imx6_defconfig
@@ -0,0 +1,309 @@
+CONFIG_CROSS_COMPILE="arm-linux-gnueabihf-"
+CONFIG_LOCALVERSION="-imx6"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_KERNEL_XZ=y
+CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
+# CONFIG_USELIB is not set
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_CGROUPS=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EXPERT=y
+# CONFIG_SYSFS_SYSCALL is not set
+CONFIG_PERF_EVENTS=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_JUMP_LABEL=y
+CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMX6Q=y
+# CONFIG_SWP_EMULATE is not set
+# CONFIG_ARM_ERRATA_643719 is not set
+CONFIG_PCI=y
+CONFIG_PCI_IMX6=y
+# CONFIG_PCIEAER is not set
+CONFIG_PCIEASPM_POWERSAVE=y
+CONFIG_SMP=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_CMA=y
+CONFIG_CMDLINE="console=ttymxc0,115200 rootwait"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_ARM_IMX6Q_CPUFREQ=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+CONFIG_CAN=y
+# CONFIG_CAN_GW is not set
+CONFIG_CAN_FLEXCAN=y
+# CONFIG_WIRELESS is not set
+# CONFIG_UEVENT_HELPER is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=0
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_EEPROM_AT24=m
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+# CONFIG_ATA_VERBOSE_ERROR is not set
+# CONFIG_SATA_PMP is not set
+CONFIG_AHCI_IMX=y
+# CONFIG_ATA_SFF is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_AGERE is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_HP is not set
+CONFIG_IGB=m
+# CONFIG_IGB_HWMON is not set
+# CONFIG_NET_VENDOR_I825XX is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_AT803X_PHY=y
+# CONFIG_USB_NET_DRIVERS is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=m
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_FSL_OTP=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_SPI_IMX=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_PCF857X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+# CONFIG_MXC_MMA8451 is not set
+CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
+CONFIG_IMX_THERMAL=y
+CONFIG_DEVICE_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_ANATOP=y
+CONFIG_REGULATOR_PFUZE100=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_CAPTURE=m
+CONFIG_MXC_CAMERA_OV5640=m
+CONFIG_MXC_CAMERA_OV5642=m
+CONFIG_MXC_CAMERA_OV5640_MIPI=m
+CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_CODA=m
+# CONFIG_VGA_ARB is not set
+CONFIG_DRM=y
+CONFIG_DRM_VGEM=m
+CONFIG_DRM_VIVANTE=y
+CONFIG_FB=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+CONFIG_FB_MXC_LDB=y
+CONFIG_FB_MXC_HDMI=y
+CONFIG_FB_MXC_DCIC=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_PCI is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_FSL_ASRC=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_SOC_EUKREA_TLV320=m
+CONFIG_SND_SOC_IMX_SGTL5000=m
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_HDMI=y
+CONFIG_HID_MULTITOUCH=m
+CONFIG_USB=y
+CONFIG_USB_OTG=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_ACM=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_MMC=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_MXC_IPU=y
+CONFIG_MXC_GPU_VIV=y
+CONFIG_MXC_MIPI_CSI2=y
+CONFIG_MXC_HDMI_CEC=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_SYSTOHC is not set
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_SNVS=m
+CONFIG_DMADEVICES=y
+CONFIG_MXC_PXP_V2=y
+# CONFIG_MX3_IPU is not set
+CONFIG_IMX_SDMA=y
+CONFIG_MXS_DMA=y
+CONFIG_STAGING=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PWM=y
+CONFIG_PWM_IMX=y
+# CONFIG_RESET_GPIO is not set
+CONFIG_EXT4_FS=y
+CONFIG_FANOTIFY=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_VFAT_FS=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+# CONFIG_JFFS2_FS_WRITEBUFFER is not set
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V2 is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_RCU_CPU_STALL_INFO is not set
+# CONFIG_FTRACE is not set
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+# CONFIG_XZ_DEC_SPARC is not set
_

^ permalink raw reply

* [RFC-b PATCH] kbuild: redefine __FILE__ as relative path from $(srctree) if possible
From: Masahiro Yamada @ 2017-04-21 19:36 UTC (permalink / raw)
  To: linux-arm-kernel

Since Kbuild runs in the objtree, __FILE__ can be a very long path
depending of $(srctree).

Commit 9da0763bdd82 ("kbuild: Use relative path when building in a
subdir of the source tree") made the situation better for cases
where objtree is a child of srctree.  ($(srctree) is "..")

For other cases of out-of-tree build, filenames in WARN_ON() etc.
are still an absolute path.  It also means the kernel image depends
on where it was built.

Here, the idea is to redefine __FILE__ as the relative path from
$(srctree), but doing so causes a compiler warning:
  warning: "__FILE__" redefined [-Wbuiltin-macro-redefined]

We can suppress it with -Wno-builtin-macro-redefined.  However,
this option is not recognized by old compilers.  So, __FILE__
is re-defined only when the option is supported.

I am adding stringify helper because '"..."' wrapping is the same
pattern as in KBUILD_BASENAME, KBUILD_MODNAME.

Please note __FILE__ is always an absolute path for external
modules.  We can strip KBUILD_EXTMOD from the path if we want,
but I am not doing that.  It would make it difficult to figure out
the module in question in case of WARN_ON().

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

This is another possible approach.

Please see these as well:
https://patchwork.kernel.org/patch/9693559/
https://patchwork.kernel.org/patch/9693563/

Pro:
this is only touching 3 makefiles.

Con:
this does not work for old compilers.


 Makefile               | 3 +++
 scripts/Kbuild.include | 4 ++++
 scripts/Makefile.lib   | 6 ++++--
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 8804aae..293ef6d 100644
--- a/Makefile
+++ b/Makefile
@@ -798,6 +798,9 @@ KBUILD_CFLAGS   += $(call cc-option,-Werror=strict-prototypes)
 # Prohibit date/time macros, which would make the build non-deterministic
 KBUILD_CFLAGS   += $(call cc-option,-Werror=date-time)
 
+# Is is possible to redefine __FILE__?
+KBUILD_CFLAGS	+= $(call cc-disable-warning, builtin-macro-redefined)
+
 # enforce correct pointer usage
 KBUILD_CFLAGS   += $(call cc-option,-Werror=incompatible-pointer-types)
 
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 61f87a9..7fc3841 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -31,6 +31,10 @@ baseprereq = $(basename $(notdir $<))
 escsq = $(subst $(squote),'\$(squote)',$1)
 
 ###
+# Quote a string to pass it to C files. foo => '"foo"'
+stringify = $(squote)$(quote)$1$(quote)$(squote)
+
+###
 # Easy method for doing a status message
        kecho := :
  quiet_kecho := echo
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 9e70196..1d789df 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -96,10 +96,12 @@ obj-dirs	:= $(addprefix $(obj)/,$(obj-dirs))
 # Note: Files that end up in two or more modules are compiled without the
 #       KBUILD_MODNAME definition. The reason is that any made-up name would
 #       differ in different configs.
-name-fix = $(squote)$(quote)$(subst $(comma),_,$(subst -,_,$1))$(quote)$(squote)
+name-fix = $(call stringify,$(subst $(comma),_,$(subst -,_,$1)))
 basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget))
 modname_flags  = $(if $(filter 1,$(words $(modname))),\
                  -DKBUILD_MODNAME=$(call name-fix,$(modname)))
+filepath_flags = $(if $(filter -Wno-builtin-macro-redefined, $(KBUILD_CFLAGS)), \
+                 -D__FILE__=$(call stringify,$(src)/$(notdir $<)))
 
 orig_c_flags   = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \
                  $(ccflags-y) $(CFLAGS_$(basetarget).o)
@@ -163,7 +165,7 @@ endif
 
 c_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
 		 $(__c_flags) $(modkern_cflags)                           \
-		 $(basename_flags) $(modname_flags)
+		 $(basename_flags) $(modname_flags) $(filepath_flags)
 
 a_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
 		 $(__a_flags) $(modkern_aflags)
-- 
2.7.4

^ permalink raw reply related

* [RFC PATCH 0/2] kbuild: use relative path from $(srctree) instead of __FILE__
From: Geert Uytterhoeven @ 2017-04-21 19:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1492801407-26823-1-git-send-email-yamada.masahiro@socionext.com>

Hi Yamada-san,

On Fri, Apr 21, 2017 at 9:03 PM, Masahiro Yamada
<yamada.masahiro@socionext.com> wrote:
> Kbuild works in objtree, not in srctree.  So, __FILE__ is prefixed
> with $(srctree)/ for out-of-tree build.
>
> It would be nice to see the same log regardless
> in-tree, or out-of-tree build.
>
> 1/2 adds a new macro KBUILD_FILE.  This points the relative path
> of the file we are building.  This is intended to replace __FILE__.
>
> 2/2 replaces __FILE__ in bug.h as an example.  This will improve
> the output of WARN_ON() etc.

I haven't tried your series, but I love the idea behind it!
I never liked exposing full file paths in kernel images.

Thanks!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* [RFC-b PATCH] kbuild: redefine __FILE__ as relative path from $(srctree) if possible
From: Michal Marek @ 2017-04-21 19:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1492803404-17837-1-git-send-email-yamada.masahiro@socionext.com>

Dne 21.4.2017 v 21:36 Masahiro Yamada napsal(a):
> Since Kbuild runs in the objtree, __FILE__ can be a very long path
> depending of $(srctree).
> 
> Commit 9da0763bdd82 ("kbuild: Use relative path when building in a
> subdir of the source tree") made the situation better for cases
> where objtree is a child of srctree.  ($(srctree) is "..")
> 
> For other cases of out-of-tree build, filenames in WARN_ON() etc.
> are still an absolute path.  It also means the kernel image depends
> on where it was built.
> 
> Here, the idea is to redefine __FILE__ as the relative path from
> $(srctree), but doing so causes a compiler warning:
>   warning: "__FILE__" redefined [-Wbuiltin-macro-redefined]
> 
> We can suppress it with -Wno-builtin-macro-redefined.  However,
> this option is not recognized by old compilers.  So, __FILE__
> is re-defined only when the option is supported.

I actually like the KBUILD_FILE approach more, even if it means patching
various users.


> Please note __FILE__ is always an absolute path for external
> modules.  We can strip KBUILD_EXTMOD from the path if we want,
> but I am not doing that.  It would make it difficult to figure out
> the module in question in case of WARN_ON().

Agreed. OOT modules are potential source of trouble, so let them stand out.

Michal

^ permalink raw reply

* [PATCH 1/5 v3] usb: host: add DT bindings for faraday fotg2
From: Linus Walleij @ 2017-04-21 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

From: Hans Ulli Kroll <ulli.kroll@googlemail.com>

This adds device tree bindings for the Faraday FOTG2
dual-mode host controller.

Cc: devicetree at vger.kernel.org
Signed-off-by: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v3:
- Change compatible to "faraday,fotg210" as the name of the
  hardware block.
- Add an elaborate SoC-specific compatible string for the
  Cortina Systems Gemini so that SoC-specific features can
  be enabled.
- Add cortina,gemini-mini-b to indicate a Gemini PHY with
  a Mini-B adapter connected.
- Indicated that the Gemini version can handle "wakeup-source".
- Add optional IP block clock.
---
 .../devicetree/bindings/usb/faraday,fotg210.txt    | 35 ++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/faraday,fotg210.txt

diff --git a/Documentation/devicetree/bindings/usb/faraday,fotg210.txt b/Documentation/devicetree/bindings/usb/faraday,fotg210.txt
new file mode 100644
index 000000000000..cf06808303e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/faraday,fotg210.txt
@@ -0,0 +1,35 @@
+Faraday FOTG Host controller
+
+This OTG-capable USB host controller is found in Cortina Systems
+Gemini and other SoC products.
+
+Required properties:
+- compatible: should be one of:
+  "faraday,fotg210"
+  "cortina,gemini-usb", "faraday,fotg210"
+- reg: should contain one register range i.e. start and length
+- interrupts: description of the interrupt line
+
+Optional properties:
+- clocks: should contain the IP block clock
+- clock-names: should be "PCLK" for the IP block clock
+
+Required properties for "cortina,gemini-usb" compatible:
+- syscon: a phandle to the system controller to access PHY registers
+
+Optional properties for "cortina,gemini-usb" compatible:
+- cortina,gemini-mini-b: boolean property that indicates that a Mini-B
+  OTH connector is in use
+- wakeup-source: see power/wakeup-source.txt
+
+Example for Gemini:
+
+usb at 68000000 {
+	compatible = "cortina,gemini-usb", "faraday,fotg210";
+	reg = <0x68000000 0x1000>;
+	interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
+	clocks = <&cc 12>;
+	clock-names = "PCLK";
+	syscon = <&syscon>;
+	wakeup-source;
+};
-- 
2.9.3

^ permalink raw reply related

* [PATCH 2/5 v3] usb: host: fotg2: add device tree probing
From: Linus Walleij @ 2017-04-21 20:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170421204058.6206-1-linus.walleij@linaro.org>

From: Hans Ulli Kroll <ulli.kroll@googlemail.com>

Add device tree probing to the fotg2 driver.

Signed-off-by: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v2->v3:
- Change compatible to "faraday,fotg210" simply.
---
 drivers/usb/host/fotg210-hcd.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 1c5b34b74860..c226041101d1 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -23,6 +23,7 @@
  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/device.h>
 #include <linux/dmapool.h>
 #include <linux/kernel.h>
@@ -5600,6 +5601,15 @@ static int fotg210_hcd_probe(struct platform_device *pdev)
 	if (usb_disabled())
 		return -ENODEV;
 
+	/* Right now device-tree probed devices don't get dma_mask set.
+	 * Since shared usb code relies on it, set it here for now.
+	 * Once we have dma capability bindings this can go away.
+	 */
+
+	retval = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+	if (retval)
+		goto fail_create_hcd;
+
 	pdev->dev.power.power_state = PMSG_ON;
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -5676,9 +5686,18 @@ static int fotg210_hcd_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id fotg210_of_match[] = {
+	{ .compatible = "faraday,fotg210" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, fotg210_of_match);
+#endif
+
 static struct platform_driver fotg210_hcd_driver = {
 	.driver = {
 		.name   = "fotg210-hcd",
+		.of_match_table = of_match_ptr(fotg210_of_match),
 	},
 	.probe  = fotg210_hcd_probe,
 	.remove = fotg210_hcd_remove,
-- 
2.9.3

^ permalink raw reply related

* [PATCH 3/5 v3] usb: host: fotg2: add silicon clock handling
From: Linus Walleij @ 2017-04-21 20:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170421204058.6206-1-linus.walleij@linaro.org>

When used in a system with software-controller silicon clocks,
the FOTG210 needs to grab, prepare and enable the clock.
This is needed on for example the Cortina Gemini, where the
platform will by default gate off the clock unless the
peripheral (in this case the USB driver) grabs and enables
the clock.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/usb/host/fotg210-hcd.c | 26 ++++++++++++++++++++++----
 drivers/usb/host/fotg210.h     |  3 +++
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index c226041101d1..906e42458791 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -45,6 +45,7 @@
 #include <linux/uaccess.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/clk.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -5635,7 +5636,7 @@ static int fotg210_hcd_probe(struct platform_device *pdev)
 	hcd->regs = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(hcd->regs)) {
 		retval = PTR_ERR(hcd->regs);
-		goto failed;
+		goto failed_put_hcd;
 	}
 
 	hcd->rsrc_start = res->start;
@@ -5645,22 +5646,35 @@ static int fotg210_hcd_probe(struct platform_device *pdev)
 
 	fotg210->caps = hcd->regs;
 
+	/* It's OK not to supply this clock */
+	fotg210->pclk = clk_get(dev, "PCLK");
+	if (!IS_ERR(fotg210->pclk)) {
+		retval = clk_prepare_enable(fotg210->pclk);
+		if (retval) {
+			dev_err(dev, "failed to enable PCLK\n");
+			goto failed_dis_clk;
+		}
+	}
+
 	retval = fotg210_setup(hcd);
 	if (retval)
-		goto failed;
+		goto failed_dis_clk;
 
 	fotg210_init(fotg210);
 
 	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (retval) {
 		dev_err(dev, "failed to add hcd with err %d\n", retval);
-		goto failed;
+		goto failed_dis_clk;
 	}
 	device_wakeup_enable(hcd->self.controller);
 
 	return retval;
 
-failed:
+failed_dis_clk:
+	if (!IS_ERR(fotg210->pclk))
+		clk_disable_unprepare(fotg210->pclk);
+failed_put_hcd:
 	usb_put_hcd(hcd);
 fail_create_hcd:
 	dev_err(dev, "init %s fail, %d\n", dev_name(dev), retval);
@@ -5676,6 +5690,10 @@ static int fotg210_hcd_remove(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+
+	if (!IS_ERR(fotg210->pclk))
+		clk_disable_unprepare(fotg210->pclk);
 
 	if (!hcd)
 		return 0;
diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h
index b5cfa7aeb277..c429efeb2b7e 100644
--- a/drivers/usb/host/fotg210.h
+++ b/drivers/usb/host/fotg210.h
@@ -181,6 +181,9 @@ struct fotg210_hcd {			/* one per controller */
 #	define COUNT(x)
 #endif
 
+	/* silicon clock */
+	struct clk		*pclk;
+
 	/* debug files */
 	struct dentry		*debug_dir;
 };
-- 
2.9.3

^ permalink raw reply related

* [PATCH 4/5 v3] usb: host: fotg2: add Gemini-specific handling
From: Linus Walleij @ 2017-04-21 20:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170421204058.6206-1-linus.walleij@linaro.org>

The Cortina Systems Gemini has bolted on a PHY inside the
silicon that can be handled by six bits in a MISC register in
the system controller.

If we are running on Gemini, look up a syscon regmap through
a phandle and enable VBUS and optionally the Mini-B connector.

If the device is flagged as "wakeup-source" using the standard
DT bindings, we also enable this in the global controller for
respective port.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/usb/host/Kconfig       |  1 +
 drivers/usb/host/fotg210-hcd.c | 76 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 407d947b34ea..9750783e5481 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -375,6 +375,7 @@ config USB_ISP1362_HCD
 config USB_FOTG210_HCD
 	tristate "FOTG210 HCD support"
 	depends on USB && HAS_DMA && HAS_IOMEM
+	select MFD_SYSCON
 	---help---
 	  Faraday FOTG210 is an OTG controller which can be configured as
 	  an USB2.0 host. It is designed to meet USB2.0 EHCI specification
diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 906e42458791..146f1eb96b60 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -46,6 +46,10 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/bitops.h>
+/* For Cortina Gemini */
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -5583,6 +5587,72 @@ static void fotg210_init(struct fotg210_hcd *fotg210)
 	iowrite32(value, &fotg210->regs->otgcsr);
 }
 
+/*
+ * Gemini-specific initialization function, only executed on the
+ * Gemini SoC using the global misc control register.
+ */
+#define GEMINI_GLOBAL_MISC_CTRL		0x30
+#define GEMINI_MISC_USB0_WAKEUP		BIT(14)
+#define GEMINI_MISC_USB1_WAKEUP		BIT(15)
+#define GEMINI_MISC_USB0_VBUS_ON	BIT(22)
+#define GEMINI_MISC_USB1_VBUS_ON	BIT(23)
+#define GEMINI_MISC_USB0_MINI_B		BIT(29)
+#define GEMINI_MISC_USB1_MINI_B		BIT(30)
+
+static int fotg210_gemini_init(struct device *dev, struct usb_hcd *hcd)
+{
+	struct device_node *np = dev->of_node;
+	struct regmap *map;
+	bool mini_b;
+	bool wakeup;
+	u32 mask, val;
+	int ret;
+
+	map = syscon_regmap_lookup_by_phandle(np, "syscon");
+	if (IS_ERR(map)) {
+		dev_err(dev, "no syscon\n");
+		return PTR_ERR(map);
+	}
+	mini_b = of_property_read_bool(np, "cortina,gemini-mini-b");
+	wakeup = of_property_read_bool(np, "wakeup-source");
+
+	/*
+	 * Figure out if this is USB0 or USB1 by simply checking the
+	 * physical base address.
+	 */
+	mask = 0;
+	if (hcd->rsrc_start == 0x69000000) {
+		val = GEMINI_MISC_USB1_VBUS_ON;
+		if (mini_b)
+			val |= GEMINI_MISC_USB1_MINI_B;
+		else
+			mask |= GEMINI_MISC_USB1_MINI_B;
+		if (wakeup)
+			val |= GEMINI_MISC_USB1_WAKEUP;
+		else
+			mask |= GEMINI_MISC_USB1_WAKEUP;
+	} else {
+		val = GEMINI_MISC_USB0_VBUS_ON;
+		if (mini_b)
+			val |= GEMINI_MISC_USB0_MINI_B;
+		else
+			mask |= GEMINI_MISC_USB0_MINI_B;
+		if (wakeup)
+			val |= GEMINI_MISC_USB0_WAKEUP;
+		else
+			mask |= GEMINI_MISC_USB0_WAKEUP;
+	}
+
+	ret = regmap_update_bits(map, GEMINI_GLOBAL_MISC_CTRL, mask, val);
+	if (ret) {
+		dev_err(dev, "failed to initialize Gemini PHY\n");
+		return ret;
+	}
+
+	dev_info(dev, "initialized Gemini PHY\n");
+	return 0;
+}
+
 /**
  * fotg210_hcd_probe - initialize faraday FOTG210 HCDs
  *
@@ -5662,6 +5732,12 @@ static int fotg210_hcd_probe(struct platform_device *pdev)
 
 	fotg210_init(fotg210);
 
+	if (of_device_is_compatible(dev->of_node, "cortina,gemini-usb")) {
+		retval = fotg210_gemini_init(dev, hcd);
+		if (retval)
+			goto failed_dis_clk;
+	}
+
 	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (retval) {
 		dev_err(dev, "failed to add hcd with err %d\n", retval);
-- 
2.9.3

^ permalink raw reply related

* [PATCH 5/5 v3] ARM: dts: Add the FOTG210 USB host to Gemini
From: Linus Walleij @ 2017-04-21 20:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170421204058.6206-1-linus.walleij@linaro.org>

This adds the FOTG210 USB host controller to the Gemini
device trees. In the main SoC DTSI it is flagged as disabled
and then it is selectively enabled on the devices that utilize
it (these per-platform enablements are done on the out-of-tree
OpenWrt patch set). It is not enabled on the Itian SquareOne
NAS/router since this instead has a VIA host controller
soldered on the PCI port, and can gate off these USB host
controllers.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
USB maintainers: I will merge this through the ARM SoC tree,
the patch is only included in the series for context.
---
 arch/arm/boot/dts/gemini-nas4220b.dts |  8 ++++++++
 arch/arm/boot/dts/gemini-rut1xx.dts   |  8 ++++++++
 arch/arm/boot/dts/gemini-wbd111.dts   |  8 ++++++++
 arch/arm/boot/dts/gemini-wbd222.dts   |  8 ++++++++
 arch/arm/boot/dts/gemini.dtsi         | 22 ++++++++++++++++++++++
 5 files changed, 54 insertions(+)

diff --git a/arch/arm/boot/dts/gemini-nas4220b.dts b/arch/arm/boot/dts/gemini-nas4220b.dts
index 7668ba52158e..55059a72aef2 100644
--- a/arch/arm/boot/dts/gemini-nas4220b.dts
+++ b/arch/arm/boot/dts/gemini-nas4220b.dts
@@ -98,5 +98,13 @@
 				read-only;
 			};
 		};
+
+		usb at 68000000 {
+			status = "okay";
+		};
+
+		usb at 69000000 {
+			status = "okay";
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/gemini-rut1xx.dts b/arch/arm/boot/dts/gemini-rut1xx.dts
index 7b920bfbda32..1c253da9f28c 100644
--- a/arch/arm/boot/dts/gemini-rut1xx.dts
+++ b/arch/arm/boot/dts/gemini-rut1xx.dts
@@ -61,5 +61,13 @@
 			reg = <0x30000000 0x00800000>;
 			/* TODO: add flash partitions here */
 		};
+
+		usb at 68000000 {
+			status = "okay";
+		};
+
+		usb at 69000000 {
+			status = "okay";
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/gemini-wbd111.dts b/arch/arm/boot/dts/gemini-wbd111.dts
index 63b756e3bf5a..c6a5abca0935 100644
--- a/arch/arm/boot/dts/gemini-wbd111.dts
+++ b/arch/arm/boot/dts/gemini-wbd111.dts
@@ -98,5 +98,13 @@
 				read-only;
 			};
 		};
+
+		usb at 68000000 {
+			status = "okay";
+		};
+
+		usb at 69000000 {
+			status = "okay";
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/gemini-wbd222.dts b/arch/arm/boot/dts/gemini-wbd222.dts
index 9747f5a47807..415380262140 100644
--- a/arch/arm/boot/dts/gemini-wbd222.dts
+++ b/arch/arm/boot/dts/gemini-wbd222.dts
@@ -98,5 +98,13 @@
 				read-only;
 			};
 		};
+
+		usb at 68000000 {
+			status = "okay";
+		};
+
+		usb at 69000000 {
+			status = "okay";
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/gemini.dtsi b/arch/arm/boot/dts/gemini.dtsi
index 6fe678a68e31..2f8d0381d5eb 100644
--- a/arch/arm/boot/dts/gemini.dtsi
+++ b/arch/arm/boot/dts/gemini.dtsi
@@ -183,5 +183,27 @@
 				#interrupt-cells = <1>;
 			};
 		};
+
+		usb at 68000000 {
+			compatible = "cortina,gemini-usb", "faraday,fotg210";
+			reg = <0x68000000 0x1000>;
+			interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
+			resets = <&rcon 8>;
+			clocks = <&gcc GEMINI_CLK_GATE_USB0>;
+			clock-names = "PCLK";
+			syscon = <&syscon>;
+			status = "disabled";
+		};
+
+		usb at 69000000 {
+			compatible = "cortina,gemini-usb", "faraday,fotg210";
+			reg = <0x69000000 0x1000>;
+			interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
+			resets = <&rcon 9>;
+			clocks = <&gcc GEMINI_CLK_GATE_USB1>;
+			clock-names = "PCLK";
+			syscon = <&syscon>;
+			status = "disabled";
+		};
 	};
 };
-- 
2.9.3

^ permalink raw reply related

* [RFC] minimum gcc version for kernel: raise to gcc-4.3 or 4.6?
From: Arnd Bergmann @ 2017-04-21 20:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGXu5jLTR+dY_Ayyix5Tg0Yn9LBFAt=j56MQVdJVGue-R-CizA@mail.gmail.com>

On Thu, Apr 20, 2017 at 9:52 PM, Kees Cook <keescook@chromium.org> wrote:
> On Thu, Apr 20, 2017 at 3:15 AM, Arnd Bergmann <arnd@arndb.de> wrote:
>> On Sun, Apr 16, 2017 at 9:52 PM, Kees Cook <keescook@chromium.org> wrote:
>>>>> The original gcc-4.3 release was in early 2008. If we decide to still
>>>>> support that, we probably want the first 10 quirks in this series,
>>>>> while gcc-4.6 (released in 2011) requires none of them.
>>>
>>> I'd be in support of raising the minimum to gcc 4.6. (I'd actually
>>> prefer 4.7, just to avoid some 4.6 packaging issues, and for better
>>> gcc plugin support.)
>>>
>>> I'm curious what gcc 4.6 binaries are common in the wild besides
>>> old-stable Debian (unsupported in maybe a year from now?) and 12.04
>>> Ubuntu (going fully unsupported in 2 weeks). It looks like 4.6 was
>>> used only in Fedora 15 and 16 (both EOL).
>>
>> I think we are better off defining two versions: One that we know
>> a lot of people care about, and we actively try to make that work
>> well in all configurations (e.g. 4.6, 4.7 or 4.8), fixing all warnings
>> we run into, and an older version that we try not to break
>> intentionally (e.g. 3.4, 4.1 or 4.3) but that we only fix when
>> someone actually runs into a problem they can't work around
>> by upgrading to a more modern compiler.
>
> For "working well everywhere" I feel like 4.8 is the better of those
> three (I'd prefer 4.9). I think we should avoid 4.6 -- it seems not
> widely used.

I suspect that 4.9 might be the one that actually works best
across architectures, and it contained some very significant
changes. In my testing gcc-5 tends to behave very similarly
to 4.9, and gcc-6 introduced a larger number of new warnings,
so that would clearly be too new for a recommended version.

The suggestion of 4.9 or higher is appealing as a recommendation
because it matches what I would personally tell people:

- If you have gcc-4.9 or newer and you don't rely on any newer
  features, there is no need to upgrade
- Wth gcc-4.8, the -Wmaybe-uninitialized warnings are now turned
  off because they were too noisy, so upgrading is probably a good
  idea even though the compiler is otherwise ok and in widespread
  use
- gcc-4.6 and 4.7 are basically usable for building kernels, but the
  warning output is often counterproductive, and the generated
  object code may be noticeably worse.
- anything before gcc-4.6 is missing too many features to be
  useful on ARM, but may still be fine on other architectures.

On the other hand, there is a noticeable difference in compile
speed, as a 5% slowdown compared to the previous release
apparently is not considered a regression. These are the times
I see for building ARM 'vexpress_defconfig':

gcc-4.4: real 0m47.269s user 11m48.576s
gcc-4.5: real 0m44.878s user 10m58.900s
gcc-4.6: real 0m44.621s user 11m34.716s
gcc-4.7: real 0m47.476s user 12m42.924s
gcc-4.8: real 0m48.494s user 13m19.736s
gcc-4.9: real 0m50.140s user 13m44.876s
gcc-5.x: real 0m51.302s user 14m05.564s
gcc-6.x: real 0m54.615s user 15m06.304s
gcc-7.x: real 0m56.008s user 15m44.720s

That is a factor of 1.5x in CPU cycles between slowest and
fastest, so there is clearly a benefit to keeping the old versions
around, but there is also no clear cut-off other thannoticing
that gcc-4.4 is slower than 4.5 in this particular
configuration.

> For an old compiler... yikes. 3.4 sounds insane to me. :)

That was my initial thought as well. On ARM, it clearly is
insane, as even gcc-4.0 is unable to build any of the modern
defconfigs (lacking -mabi=aapcs, ICE when building vsprintf.c)
and even the patch I did to get gcc-4.1 to build is probably
too ugly to get merged, so to build any unpatched kernel after
linux-3.6 you need at least gcc-4.2, or even gcc-4.4 for the
''defconfig' (gcc-4.3 if you disable vdso).

Then again, on x86, old cmpilers were claimed to be much better
supported. I just tried it out and found that no x86 defconfig kernel
since linux-3.2 could be built with gcc-3.4, probably not on any
other architecture either (it cannot have forward declarations
for inline functions and we have one in kernel/sched_fair.c).

I think that would be a really good argument for requiring
something newer ;-)

The linux-4.2 x86 defconfig could still be built with gcc-4.0, but
later kernels have several minor problems with that, and
require at least gcc-4.3.

If we are ok with this status quo, we could simply declare gcc-4.3
the absolute minimum version for the kernel, make gcc-4.9
the recommeded minimum version, and remove all workarounds
for gcc-4.2 or older.

If anyone has a good reason for gcc-4.0 through gcc-4.2, then
we would need a small number of patches to get them back
working with x86 defconfig.

       Arnd

^ permalink raw reply

* [RFC PATCH 0/2] kbuild: use relative path from $(srctree) instead of __FILE__
From: Joe Perches @ 2017-04-21 20:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1492801407-26823-1-git-send-email-yamada.masahiro@socionext.com>

On Sat, 2017-04-22 at 04:03 +0900, Masahiro Yamada wrote:
> Kbuild works in objtree, not in srctree.  So, __FILE__ is prefixed
> with $(srctree)/ for out-of-tree build.
> 
> It would be nice to see the same log regardless
> in-tree, or out-of-tree build.
> 
> 1/2 adds a new macro KBUILD_FILE.  This points the relative path
> of the file we are building.  This is intended to replace __FILE__.
> 
> 2/2 replaces __FILE__ in bug.h as an example.  This will improve
> the output of WARN_ON() etc.

Good idea.

Perhaps a lot of the in-tree __FILE__ uses should be
KBUILD_BASENAME or another new type like KBUILD_PRETTY_FILE

^ permalink raw reply

* linux-next: manual merge of the pm tree with the arm-soc tree
From: santosh.shilimkar at oracle.com @ 2017-04-21 21:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAK8P3a0cVMt3y_oYH70V-ekPvUMeeBApSvybpRftSupzYy1FWQ@mail.gmail.com>



On 4/21/17 2:31 AM, Arnd Bergmann wrote:
> On Fri, Apr 21, 2017 at 8:39 AM, santosh.shilimkar at oracle.com
> <santosh.shilimkar@oracle.com> wrote:
>> On 4/20/17 10:53 PM, Arnd Bergmann wrote:
>>>
>>> On Fri, Apr 21, 2017 at 2:54 AM, Stephen Rothwell <sfr@canb.auug.org.au>
>>> wrote:
>>>>
>>>> Hi all,
>>>>
>>>> Today's linux-next merge of the pm tree got a conflict in:
>>>>
>>>>   include/dt-bindings/genpd/k2g.h
>>>>
>>>> between commit:
>>>>
>>>>   7cc119f29b19 ("dt-bindings: Add TI SCI PM Domains")
>>>>
>>>> from the arm-soc tree and commit:
>>>>
>>>>   45da8edd1741 ("dt-bindings: Add TI SCI PM Domains")
>>>>
>>>> from the pm tree.
>>>>
>>>> I fixed it up (I just used the pm tree version) and can carry the fix as
>>>> necessary. This is now fixed as far as linux-next is concerned, but any
>>>> non trivial conflicts should be mentioned to your upstream maintainer
>>>> when your tree is submitted for merging.  You may also want to consider
>>>> cooperating with the maintainer of the conflicting tree to minimise any
>>>> particularly complex conflicts.
>>>
>>>
>>> Dave, Santosh,
>>>
>>> any idea what happened here? It seems that we picked up the wrong
>>> version of the tree, do we need to drop this from arm-soc?
>>>
>> Nope. Its because this series was in my 'next' branch for a week or
>> so and now it made it via arm-soc tree next as well.
>>
>> I just cleaned up my next head so it linux-next next tag should have
>> only arm-soc copy.
>
> I still see two conflicting trees in linux-next as of today, neither of
> them is your keystone tree:
>
In the list it was agreed that the patchset goes via arm-soc tree.

ae3874c ARM: keystone: Drop PM domain support for k2g
52835d5 soc: ti: Add ti_sci_pm_domains driver
7cc119f dt-bindings: Add TI SCI PM Domains
213ec7f PM / Domains: Do not check if simple providers have phandle cells
a5ea7a0 PM / Domains: Add generic data pointer to genpd data struct

> arm-soc/next/drivers:
> ae3874cc931b ARM: keystone: Drop PM domain support for k2g
> 52835d59fc6c soc: ti: Add ti_sci_pm_domains driver
> 7cc119f29b19 dt-bindings: Add TI SCI PM Domains
> 213ec7fed302 PM / Domains: Do not check if simple providers have phandle cells
> a5ea7a0fcbd7 PM / Domains: Add generic data pointer to genpd data struct
>
Above are the correct git object for which I sent pull request for.

> pm/pm-domains:
> 9da73c55f95f ARM: keystone: Drop PM domain support for k2g
> 112572283742 soc: ti: Add ti_sci_pm_domains driver
> 45da8edd1741 dt-bindings: Add TI SCI PM Domains
> b1013fa55589 PM / Domains: Do not check if simple providers have phandle cells
> 7030fc004df9 PM / Domains: Add generic data pointer to genpd data struct
The above git object don't exist in my tree so am not sure about these
objects. I Just checked Rafael's pm-domains head and that also don't
have these objects.

https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git/log/?h=pm-domains


> b539cc82d493 PM / Domains: Ignore domain-idle-states that are not compatible
> 075c37d59ecd PM / Domains: Don't warn about IRQ safe device for an
> always on PM domain
> 1c14967c6ea0 PM / Domains: Respect errors from genpd's ->power_off() callback
> ffaa42e8a40b PM / Domains: Enable users of genpd to specify always on PM domains
> 41e2c8e0060d PM / Domains: Clean up code validating genpd's status
> 8ce95844c853 PM / Domain: remove conditional from error case
>
> For all I can tell (and matching what Stephen found), the version in
> the 'pm' tree
> is the one you intended to send, while the version we merged into arm-soc
> has not only a different git commit ID but also some odd comments that
> are not present in the PM version:
>
See above. The one in arm-soc tree is what I sent as pull request. Am
also confused for the git objects you pointed out in pm/pm-domains.
If they are not on the source pm-domains tree then how they landed
up in linux-next ?

Regards,
Santosh

^ permalink raw reply

* [RFC] minimum gcc version for kernel: raise to gcc-4.3 or 4.6?
From: Kees Cook @ 2017-04-21 21:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAK8P3a114EVbnhbObfq-4pZp8XCT4fWzMXD+WkRi7iPXs1vFMA@mail.gmail.com>

On Fri, Apr 21, 2017 at 1:55 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thu, Apr 20, 2017 at 9:52 PM, Kees Cook <keescook@chromium.org> wrote:
>> On Thu, Apr 20, 2017 at 3:15 AM, Arnd Bergmann <arnd@arndb.de> wrote:
>>> On Sun, Apr 16, 2017 at 9:52 PM, Kees Cook <keescook@chromium.org> wrote:
>>>>>> The original gcc-4.3 release was in early 2008. If we decide to still
>>>>>> support that, we probably want the first 10 quirks in this series,
>>>>>> while gcc-4.6 (released in 2011) requires none of them.
>>>>
>>>> I'd be in support of raising the minimum to gcc 4.6. (I'd actually
>>>> prefer 4.7, just to avoid some 4.6 packaging issues, and for better
>>>> gcc plugin support.)
>>>>
>>>> I'm curious what gcc 4.6 binaries are common in the wild besides
>>>> old-stable Debian (unsupported in maybe a year from now?) and 12.04
>>>> Ubuntu (going fully unsupported in 2 weeks). It looks like 4.6 was
>>>> used only in Fedora 15 and 16 (both EOL).
>>>
>>> I think we are better off defining two versions: One that we know
>>> a lot of people care about, and we actively try to make that work
>>> well in all configurations (e.g. 4.6, 4.7 or 4.8), fixing all warnings
>>> we run into, and an older version that we try not to break
>>> intentionally (e.g. 3.4, 4.1 or 4.3) but that we only fix when
>>> someone actually runs into a problem they can't work around
>>> by upgrading to a more modern compiler.
>>
>> For "working well everywhere" I feel like 4.8 is the better of those
>> three (I'd prefer 4.9). I think we should avoid 4.6 -- it seems not
>> widely used.
>
> I suspect that 4.9 might be the one that actually works best
> across architectures, and it contained some very significant
> changes. In my testing gcc-5 tends to behave very similarly
> to 4.9, and gcc-6 introduced a larger number of new warnings,
> so that would clearly be too new for a recommended version.
>
> The suggestion of 4.9 or higher is appealing as a recommendation
> because it matches what I would personally tell people:
>
> - If you have gcc-4.9 or newer and you don't rely on any newer
>   features, there is no need to upgrade
> - Wth gcc-4.8, the -Wmaybe-uninitialized warnings are now turned
>   off because they were too noisy, so upgrading is probably a good
>   idea even though the compiler is otherwise ok and in widespread
>   use
> - gcc-4.6 and 4.7 are basically usable for building kernels, but the
>   warning output is often counterproductive, and the generated
>   object code may be noticeably worse.
> - anything before gcc-4.6 is missing too many features to be
>   useful on ARM, but may still be fine on other architectures.
>
> On the other hand, there is a noticeable difference in compile
> speed, as a 5% slowdown compared to the previous release
> apparently is not considered a regression. These are the times
> I see for building ARM 'vexpress_defconfig':
>
> gcc-4.4: real 0m47.269s user 11m48.576s
> gcc-4.5: real 0m44.878s user 10m58.900s
> gcc-4.6: real 0m44.621s user 11m34.716s
> gcc-4.7: real 0m47.476s user 12m42.924s
> gcc-4.8: real 0m48.494s user 13m19.736s
> gcc-4.9: real 0m50.140s user 13m44.876s
> gcc-5.x: real 0m51.302s user 14m05.564s
> gcc-6.x: real 0m54.615s user 15m06.304s
> gcc-7.x: real 0m56.008s user 15m44.720s
>
> That is a factor of 1.5x in CPU cycles between slowest and
> fastest, so there is clearly a benefit to keeping the old versions
> around, but there is also no clear cut-off other thannoticing
> that gcc-4.4 is slower than 4.5 in this particular
> configuration.
>
>> For an old compiler... yikes. 3.4 sounds insane to me. :)
>
> That was my initial thought as well. On ARM, it clearly is
> insane, as even gcc-4.0 is unable to build any of the modern
> defconfigs (lacking -mabi=aapcs, ICE when building vsprintf.c)
> and even the patch I did to get gcc-4.1 to build is probably
> too ugly to get merged, so to build any unpatched kernel after
> linux-3.6 you need at least gcc-4.2, or even gcc-4.4 for the
> ''defconfig' (gcc-4.3 if you disable vdso).
>
> Then again, on x86, old cmpilers were claimed to be much better
> supported. I just tried it out and found that no x86 defconfig kernel
> since linux-3.2 could be built with gcc-3.4, probably not on any
> other architecture either (it cannot have forward declarations
> for inline functions and we have one in kernel/sched_fair.c).
>
> I think that would be a really good argument for requiring
> something newer ;-)
>
> The linux-4.2 x86 defconfig could still be built with gcc-4.0, but
> later kernels have several minor problems with that, and
> require at least gcc-4.3.
>
> If we are ok with this status quo, we could simply declare gcc-4.3
> the absolute minimum version for the kernel, make gcc-4.9
> the recommeded minimum version, and remove all workarounds
> for gcc-4.2 or older.

I think starting with this would be a good first step. I'm not sure
the best way to add "recommended minimum" to
Documentation/process/changes.rst hmmm

> If anyone has a good reason for gcc-4.0 through gcc-4.2, then
> we would need a small number of patches to get them back
> working with x86 defconfig.

-Kees


-- 
Kees Cook
Pixel Security

^ permalink raw reply

* Touchscreen failure with CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
From: Rafael J. Wysocki @ 2017-04-21 21:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOMZO5BZ8Z8dfwsfuiunNQ_q39_k4QJg7jLPQfaxn+YBsmz2jw@mail.gmail.com>

On Friday, April 21, 2017 01:11:52 PM Fabio Estevam wrote:
> Hi,
> 
> Running 4.11-rc7 on a imx6q-sabresd board I notice that egalax
> touchscreen stops generating evtest events after a random period of
> time.
> 
> This problem can be avoided if I unselect CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND:
> 
> --- a/arch/arm/configs/imx_v6_v7_defconfig
> +++ b/arch/arm/configs/imx_v6_v7_defconfig
> @@ -54,7 +54,6 @@ CONFIG_CMA=y
>  CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
>  CONFIG_KEXEC=y
>  CONFIG_CPU_FREQ=y
> -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
>  CONFIG_ARM_IMX6Q_CPUFREQ=y
>  CONFIG_CPU_IDLE=y
>  CONFIG_VFP=y
> 
> With this change evtest always capture all touchscreen events. No
> single failure is seen.
> 
> I could see the same behavior with all mainline kernels I tested (4.9 and 4.10).
> 
> Any ideas as to how fix this bug when CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y?

And which governor is the default otherwise?

Thanks,
Rafael

^ permalink raw reply

* linux-next: manual merge of the pm tree with the arm-soc tree
From: Rafael J. Wysocki @ 2017-04-21 21:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <e2f9efab-291f-1436-2176-0fff3f2aae3f@oracle.com>

On Friday, April 21, 2017 02:02:35 PM santosh.shilimkar at oracle.com wrote:
> 
> On 4/21/17 2:31 AM, Arnd Bergmann wrote:
> > On Fri, Apr 21, 2017 at 8:39 AM, santosh.shilimkar at oracle.com
> > <santosh.shilimkar@oracle.com> wrote:
> >> On 4/20/17 10:53 PM, Arnd Bergmann wrote:
> >>>
> >>> On Fri, Apr 21, 2017 at 2:54 AM, Stephen Rothwell <sfr@canb.auug.org.au>
> >>> wrote:
> >>>>
> >>>> Hi all,
> >>>>
> >>>> Today's linux-next merge of the pm tree got a conflict in:
> >>>>
> >>>>   include/dt-bindings/genpd/k2g.h
> >>>>
> >>>> between commit:
> >>>>
> >>>>   7cc119f29b19 ("dt-bindings: Add TI SCI PM Domains")
> >>>>
> >>>> from the arm-soc tree and commit:
> >>>>
> >>>>   45da8edd1741 ("dt-bindings: Add TI SCI PM Domains")
> >>>>
> >>>> from the pm tree.
> >>>>
> >>>> I fixed it up (I just used the pm tree version) and can carry the fix as
> >>>> necessary. This is now fixed as far as linux-next is concerned, but any
> >>>> non trivial conflicts should be mentioned to your upstream maintainer
> >>>> when your tree is submitted for merging.  You may also want to consider
> >>>> cooperating with the maintainer of the conflicting tree to minimise any
> >>>> particularly complex conflicts.
> >>>
> >>>
> >>> Dave, Santosh,
> >>>
> >>> any idea what happened here? It seems that we picked up the wrong
> >>> version of the tree, do we need to drop this from arm-soc?
> >>>
> >> Nope. Its because this series was in my 'next' branch for a week or
> >> so and now it made it via arm-soc tree next as well.
> >>
> >> I just cleaned up my next head so it linux-next next tag should have
> >> only arm-soc copy.
> >
> > I still see two conflicting trees in linux-next as of today, neither of
> > them is your keystone tree:
> >
> In the list it was agreed that the patchset goes via arm-soc tree.

OK, I missed that when I looked at it again a couple of days ago, sorry.

I'll drop it from the pm-domains branch.

Thanks,
Rafael

^ permalink raw reply

* Touchscreen failure with CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
From: Rafael J. Wysocki @ 2017-04-21 21:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOMZO5C776E3AqnhPPJSTF=atuOHi5Mok7F7yocBhRsJ6Ror2A@mail.gmail.com>

On Friday, April 21, 2017 06:37:31 PM Fabio Estevam wrote:
> On Fri, Apr 21, 2017 at 6:28 PM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > On Friday, April 21, 2017 01:11:52 PM Fabio Estevam wrote:
> >> Hi,
> >>
> >> Running 4.11-rc7 on a imx6q-sabresd board I notice that egalax
> >> touchscreen stops generating evtest events after a random period of
> >> time.
> >>
> >> This problem can be avoided if I unselect CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND:
> >>
> >> --- a/arch/arm/configs/imx_v6_v7_defconfig
> >> +++ b/arch/arm/configs/imx_v6_v7_defconfig
> >> @@ -54,7 +54,6 @@ CONFIG_CMA=y
> >>  CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
> >>  CONFIG_KEXEC=y
> >>  CONFIG_CPU_FREQ=y
> >> -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
> >>  CONFIG_ARM_IMX6Q_CPUFREQ=y
> >>  CONFIG_CPU_IDLE=y
> >>  CONFIG_VFP=y
> >>
> >> With this change evtest always capture all touchscreen events. No
> >> single failure is seen.
> >>
> >> I could see the same behavior with all mainline kernels I tested (4.9 and 4.10).
> >>
> >> Any ideas as to how fix this bug when CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y?
> >
> > And which governor is the default otherwise?
> 
> When CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y is removed then the
> 'performance' governor is the default.

There you go.  Apparently, using frequencies below the max causes problems to
happen in the SoC.

Thanks,
Rafael

^ permalink raw reply


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