“Porting Linux on ARM” seminar road show in France

CaptronicIn December 2015, Free Electrons engineer Alexandre Belloni gave a half-day seminar “Porting Linux on ARM” in Toulouse (France) in partnership with french organization Captronic. We published the materials used for the seminar shortly after the event.

We are happy to announce that this seminar will be given in four different cities in France over the next few months:

  • In Montpellier, on April 14th from 2 PM to 6 PM. See this page for details.
  • In Clermont-Ferrand, on April 27th from 2 PM to 6 PM. See this page for details.
  • In Brive, on April 28th from 9 AM to 1 PM. See this page for details.
  • Near Chambéry, on May 25th from 9:30 AM to 5/30 PM. See this page for details.
  • Near Bordeaux, on June 2nd from 2 PM to 6 PM. See this page for details.
  • Near Nancy, on June 16th from 2 PM to 6 PM. See this page for details.

The seminar is delivered in French, and the event is free after registration. The speaker, Alexandre Belloni, has worked on porting botloaders and the Linux kernel on a number of ARM platforms (Atmel, Freescale, Texas Instruments and more) and is the Linux kernel co-maintainer for the RTC subsystem and the support of the Atmel ARM processors.

Free Electrons contributing Linux kernel initial support for Annapurna Labs ARM64 Platform-on-Chip

We are happy to announce that on February 8th 2016 we submitted to the mainline Linux kernel the initial support for Annapurna Labs Alpine v2 Platform-on-Chip based on the 64-bit ARMv8 architecture.

Annapurna Labs was founded in 2011 in Israel. Annapurna Labs provides 32-bit and 64-bit ARM products including chips and subsystems under the Alpine brand for the home NAS, Gateway and WiFi router equipment, see this page for details. The 32-bit version already has support in the official Linux kernel (see alpine.dtsi), and we have started to add support for the quad core 64-bit version, called Alpine v2, which brings significant performance for the home.

This is our initial contribution and we plan to follow it with additional Alpine v2 functionality in the near future.

Free Electrons contributions to Linux 4.5

Adelie PenguinLinus Torvalds just released Linux 4.5, for which the major new features have been described by LWN.net in three articles: part 1, part 2 and part 3. On a total of 12080 commits, Free Electrons contributed 121 patches, almost exactly 1% of the total. Due to its large number of contribution by patch number, Free Electrons engineer Boris Brezillon appears in the statistics of top-contributors for the 4.5 kernel in the LWN.net statistics article.

This time around, our important contributions were:

  • Addition of a driver for the Microcrystal rv1805 RTC, by Alexandre Belloni.
  • A huge number of patches touching all NAND controller drivers and the MTD subsystem, from Boris Brezillon. They are the first step of a more general rework of how NAND controllers and NAND chips are handled in the Linux kernel. As Boris explains in the cover letter, his series aims at clarifying the relationship between the mtd and nand_chip structures and hiding NAND framework internals to NAND. […]. This allows removal of some of the boilerplate code done in all NAND controller drivers, but most importantly, it unifies a bit the way NAND chip structures are instantiated.
  • On the support for the Marvell ARM processors:
    • In the mvneta networking driver (used on Armada 370, XP, 38x and soon on Armada 3700): addition of naive RSS support with per-CPU queues, configure XPS support, numerous fixes for potential race conditions.
    • Fix in the Marvell CESA driver
    • Misc improvements to the mv_xor driver for the Marvell XOR engines.
    • After four years of development the 32-bits Marvell EBU platform support is now pretty mature and the majority of patches for this platform now are improvements of existing drivers or bug fixes rather than new hardware support. Of course, the support for the 64-bits Marvell EBU platform has just started, and will require a significant number of patches and contributions to be fully supported upstream, which is an on-going effort.
  • On the support for the Atmel ARM processors:
    • Addition of the support for the L+G VInCo platform.
    • Improvement to the macb network driver to reset the PHY using a GPIO.
    • Fix Ethernet PHY issues on Atmel SAMA5D4
  • On the support for Allwinner ARM processors:
    • Implement audio capture in the sun4i audio driver.
    • Add the support for a special pin controller available on Allwinner A80.

The complete list of our contributions:

  • Alexandre Belloni (11):
    • clk: at91: Revert “keep slow clk enabled to prevent system hang”
    • of: Add vendor prefix for QiaoDian Xianshi
    • ARM: mxs: dt: cfa10057: fix backlight PWM
    • Merge tag ‘ib-mfd-regulator-rtc-v4.5’ into rtc-next
    • rtc: abx80x: Add Microcrystal rv1805 support
    • rtc: abx80x: add alarm support
    • clockevents/tcb_clksrc: Prevent disabling an already disabled clock
    • ARM: dts: at91: at91sam9n12ek: fix panel compatible string
    • ARM: dts: at91: sama5d4 xplained: properly mux phy interrupt
    • phy: micrel: Ensure interrupts are reenabled on resume
    • phy: micrel: Disable auto negotiation on startup
  • Antoine Tenart (1):
    • MAINTAINERS: alpine: add a new maintainer and update the entry
  • Boris BREZILLON (81):
    • mtd: nand: convert to nand_get_flash_node()
    • mtd: nand: fix drivers abusing mtd->priv
    • mtd: nand: add an mtd_to_nand() helper
    • doc: mtd: nand: update examples to use mtd_to_nand()
    • mtd: nand: fix ONFI parameter page layout
    • ARM: nand: make use of mtd_to_nand() where appropriate
    • sh: nand: make use of mtd_to_nand() where appropriate
    • mtd: nand: make use of mtd_to_nand() in NAND core code
    • staging: mt29f_spinand: make use of mtd_to_nand()
    • mtd: nand: make use of mtd_to_nand() in NAND drivers
    • mtd: nand: embed an mtd_info structure into nand_chip
    • mtd: nand: add nand_to_mtd() helper
    • cris: nand: make use of mtd_to_nand() where appropriate
    • blackfin: nand: make use of mtd_to_nand() where appropriate
    • mips: nand: make use of mtd_to_nand() where appropriate
    • mtd: nand: denali: add missing nand_release() call in denali_remove()
    • mtd: nand: fsmc: create and use mtd_to_fsmc()
    • mtd: nand: nuc900: create and use mtd_to_nuc900()
    • mtd: nand: omap2: create and use mtd_to_omap()
    • mtd: nand: ams-delta: use the mtd instance embedded in struct nand_chip
    • mtd: nand: atmel: use the mtd instance embedded in struct nand_chip
    • mtd: nand: au1550nd: use the mtd instance embedded in struct nand_chip
    • mtd: nand: bf5xx: use the mtd instance embedded in struct nand_chip
    • mtd: nand: brcm: use the mtd instance embedded in struct nand_chip
    • mtd: nand: cafe: use the mtd instance embedded in struct nand_chip
    • mtd: nand: cs553x: use the mtd instance embedded in struct nand_chip
    • mtd: nand: cmx270: use the mtd instance embedded in struct nand_chip
    • mtd: nand: davinci: use the mtd instance embedded in struct nand_chip
    • mtd: nand: diskonchip: use the mtd instance embedded in struct nand_chip
    • mtd: nand: docg4: use the mtd instance embedded in struct nand_chip
    • mtd: nand: fsl_elbc: use the mtd instance embedded in struct nand_chip
    • mtd: nand: fsl_ifc: use the mtd instance embedded in struct nand_chip
    • mtd: nand: fsl_upm: use the mtd instance embedded in struct nand_chip
    • mtd: nand: fsmc: use the mtd instance embedded in struct nand_chip
    • mtd: nand: gpio: use the mtd instance embedded in struct nand_chip
    • mtd: nand: gpmi: use the mtd instance embedded in struct nand_chip
    • mtd: nand: hisi504: use the mtd instance embedded in struct nand_chip
    • mtd: nand: jz4740: use the mtd instance embedded in struct nand_chip
    • mtd: nand: lpc32xx: use the mtd instance embedded in struct nand_chip
    • mtd: nand: mpc5121: use the mtd instance embedded in struct nand_chip
    • mtd: nand: mxc: use the mtd instance embedded in struct nand_chip
    • mtd: nand: nandsim: use the mtd instance embedded in struct nand_chip
    • mtd: nand: ndfc: use the mtd instance embedded in struct nand_chip
    • mtd: nand: nuc900: use the mtd instance embedded in struct nand_chip
    • mtd: nand: omap2: use the mtd instance embedded in struct nand_chip
    • mtd: nand: orion: use the mtd instance embedded in struct nand_chip
    • mtd: nand: pasemi: use the mtd instance embedded in struct nand_chip
    • mtd: nand: plat: use the mtd instance embedded in struct nand_chip
    • mtd: nand: pxa3xx: use the mtd instance embedded in struct nand_chip
    • mtd: nand: r852: use the mtd instance embedded in struct nand_chip
    • mtd: nand: sh_flctl: use the mtd instance embedded in struct nand_chip
    • mtd: nand: sharpsl: use the mtd instance embedded in struct nand_chip
    • mtd: nand: sunxi: use the mtd instance embedded in struct nand_chip
    • mtd: nand: tmio: use the mtd instance embedded in struct nand_chip
    • mtd: nand: txx9ndfmc: use the mtd instance embedded in struct nand_chip
    • mtd: nand: vf610: use the mtd instance embedded in struct nand_chip
    • mtd: nand: update the documentation to reflect framework changes
    • mtd: nand: s3c2410: use the mtd instance embedded in struct nand_chip
    • staging: mt29f_spinand: use the mtd instance embedded in struct nand_chip
    • cris: nand: use the mtd instance embedded in struct nand_chip
    • mtd: nand: bcm47xx: use the mtd instance embedded in struct nand_chip
    • mtd: nand: socrates: use the mtd instance embedded in struct nand_chip
    • mtd: nand: denali: use the mtd instance embedded in struct nand_chip
    • mtd: nand: update mtd_to_nand()
    • mtd: nand: remove useless mtd->priv = chip assignments
    • cris: nand: remove useless mtd->priv = chip assignments
    • staging: mt29f_spinand: remove useless mtd->priv = chip assignment
    • mtd: nand: simplify nand_dt_init() usage
    • mtd: nand: kill the chip->flash_node field
    • mtd: nand: remove unused and buggy get_platform_nandchip() helper function
    • mtd: nand: return consistent error codes in ecc.correct() implementations
    • mtd: nand: use nand_check_erased_ecc_chunk in default ECC read functions
    • mtd: nand: davinci: remove custom ‘erased check’ implementation
    • mtd: nand: diskonchip: remove custom ‘erased check’ implementation
    • mtd: nand: jz4740: remove custom ‘erased check’ implementation
    • mtd: nand: add helpers to access ->priv
    • ARM: make use of nand_set/get_controller_data() helpers
    • mtd: nand: make use of nand_set/get_controller_data() helpers
    • staging: mt29f_spinand: make use of nand_set/get_controller_data() helpers
    • crypto: marvell/cesa – fix test in mv_cesa_dev_dma_init()
    • MAINTAINERS: add a maintainer for the NAND subsystem
  • Gregory CLEMENT (16):
    • net: mvneta: Make the default queue related for each port
    • net: mvneta: Associate RX queues with each CPU
    • net: mvneta: Add naive RSS support
    • net: mvneta: Configure XPS support
    • net/macb: add support for resetting PHY using GPIO
    • net/macb: Update device tree binding for resetting PHY using GPIO
    • ARM: at91/dt: Add Support for the L+G VInCo platform
    • rtc: rv8803: Extend compatibility with the rx8900
    • usb: host: xhci-plat: fix NULL pointer in probe for device tree case
    • net: mvneta: Fix for_each_present_cpu usage
    • net: mvneta: Fix the CPU choice in mvneta_percpu_elect
    • net: mvneta: Use on_each_cpu when possible
    • net: mvneta: Remove unused code
    • net: mvneta: Modify the queue related fields from each cpu
    • net: mvneta: The mvneta_percpu_elect function should be atomic
    • net: mvneta: Fix race condition during stopping
  • Maxime Ripard (5):
    • ASoC: sun4i: Implement MIC1 capture
    • ASoC: sunxi: Remove useless comments and variable
    • ASoC: sun4i-codec: pass through clk_set_rate error
    • pinctrl: sunxi: Add A80 special pin controller
    • drm/fb_cma_helper: Remove implicit call to disable_unused_functions
  • Thomas Petazzoni (8):
    • ARM: mvebu: remove duplicated regulator definition in Armada 388 GP
    • genirq: Implement irq_percpu_is_enabled()
    • dmaengine: mv_xor: remove mv_xor_chan->current_type field
    • dmaengine: mv_xor: de-duplicate mv_chan_set_mode*()
    • dmaengine: mv_xor: add suspend/resume support
    • PCI/MSI: Fix typos in
    • base: Export platform_msi_domain_[alloc,free]_irqs
    • ARM: mvebu: fix overlap of Crypto SRAM with PCIe memory window

Slides from Collaboration Summit talk on Linux kernel upstreaming

As we announced in a previous blog post, Free Electrons CTO Thomas Petazzoni gave a talk at the Collaboration Summit 2016 covering the topic of “Upstreaming hardware support in the Linux kernel: why and how?“.

The slides of the talk are now available in PDF format.

Upstreaming hardware support in the Linux kernel: why and how?

Upstreaming hardware support in the Linux kernel: why and how?

Upstreaming hardware support in the Linux kernel: why and how?

Through this talk, we identified a number of major reasons that should encourage hardware vendors to contribute the support for their hardware to the upstream Linux kernel, and some hints on how to achieve that. Of course, within a 25 minutes time slot, it was not possible to get into the details, but hopefully the general hints we have shared, based on our significant Linux kernel upstreaming experience, have been useful for the audience.

Unfortunately, none of the talks at the Collaboration Summit were recorded, so no video will be available for this talk.

Free Electrons engineer Boris Brezillon becomes Linux NAND subsystem maintainer

Free Electrons engineer Boris Brezillon has been involved in the support for NAND flashes in the Linux kernel for quite some time. He is the author of the NAND driver for the Allwinner ARM processors, did several improvements to the NAND GPMI controller driver, has initiated a significant rework of the NAND subsystem, and is working on supporting MLC NANDs. Boris is also very active on the linux-mtd mailing list by reviewing patches from others, and making suggestions.

Hynix NAND flash

For those reasons, Boris was recently appointed by the MTD maintainer Brian Norris as a new maintainer of the NAND subsystem. NAND is considered a sub-subsystem of the MTD subsystem, and as such, Boris will be sending pull requests to Brian, who in turn is sending pull requests to Linus Torvalds. See this commit for the addition of Boris as a NAND maintainer in the MAINTAINERS file. Boris will therefore be in charge of reviewing and merging all the patches touching drivers/mtd/nand/, which consist mainly of NAND drivers. Boris has created a nand/next on Github, where he has already merged a number of patches that will be pushed to Brian Norris during the 4.7 merge window.

We are happy to see one of our engineers taking another position as a maintainer in the kernel community. Maxime Ripard was already a co-maintainer of the Allwinner ARM platform support, Alexandre Belloni a co-maintainer of the RTC subsystem and Atmel ARM platform support, Grégory Clement a co-maintainer of the Marvell EBU platform support, and Antoine Ténart a co-maintainer of the Annapurna Labs platform support.

Slides from the Embedded Linux Conference

Two weeks ago, the entire Free Electrons engineering team (9 persons) attended the Embedded Linux Conference in San Diego. We had some really good time there, with lots of interesting talks and useful meetings and discussions.

Tim Bird opening the conferenceDiscussion between Linus Torvalds and Dirk Hohndel

In addition to attending the event, we also participated by giving 5 different talks on various topics, for which we are publishing the slides:

Boris Brezillon, the new NAND Linux subsystem maintainer, presented on Modernizing the NAND framework: The big picture.

Boris Brezillon's talk on the NAND subsystem

Antoine Ténart presented on Using DT overlays to support the C.H.I.P’s capes.

Antoine Tenart's talk on using DT overlays for the CHIP

Maxime Ripard, maintainer of the Allwinner platform support in Linux, presented on Bringing display and 3D to the C.H.I.P computer.

Maxime Ripard's talk on display and 3D for the CHIP

Alexandre Belloni and Thomas Petazzoni presented Buildroot vs. OpenEmbedded/Yocto Project: a four hands discussion.

Belloni and Petazzoni's talk on OpenEmbedded vs. Buildroot

Thomas Petazzoni presented GNU Autotools: a tutorial.

Petazzoni's tutorial on the autotools

All the other slides from the conference are available from the event page as well as from eLinux.org Wiki. All conferences have been recorded, and the videos will hopefully be posted soon by the Linux Foundation.

Article on the CHIP in French Linux magazine

Free Electrons engineer and Allwinner platform maintainer Maxime Ripard has written a long article presenting the Nextthing C.H.I.P platform in issue #18 of French magazine OpenSilicium, dedicated to open source in embedded systems. The C.H.I.P has even been used for the front cover of the magazine!

OpenSilicium #18

In this article, Maxime presents the C.H.I.P platform, its history and the choice of the Allwinner SoC. He then details how to set up a developer-friendly environment to use the board, building and flashing from scratch U-Boot, the kernel and a Debian-based root filesystem. Finally, he describes how to use Device Tree overlays to describe additional peripherals connected to the board, with the traditional example of the LED.

OpenSilicium #18 CHIP article

In the same issue, OpenSilicium also covers numerous other topics:

  • A feedback on the FOSDEM 2016 conference
  • Uploading code to STM32 microcontrollers: the case of STM32-F401RE
  • Kernel and userspace debugging with ftrace
  • IoT prototyping with Buildroot
  • RIOT, the free operating system for the IoT world
  • Interview of Cedric Bail, working on the Enligthenment Foundation Libraries for Samsung
  • Setup of Xenomai on the Zynq Zedboard
  • Decompression of 3R data stream using a VHDL-described circuit
  • Write a userspace device driver for a FPGA using UIO

How we found that the Linux nios2 memset() implementation had a bug!

NIOS II processorNiosII is a 32-bit RISC embedded processor architecture designed by Altera, for its family of FPGAs: Cyclone III, Cyclone IV, etc. Being a soft-core architecture, by using Altera’s Quartus Prime design software, you can adjust the CPU configuration to your needs and instantiate it into the FPGA. You can customize various parameters like the instruction or the data cache size, enable/disable the MMU, enable/disable an FPU, and so on. And for us embedded Linux engineers, a very interesting aspect is that both the Linux kernel and the U-Boot bootloader, in their official versions, support the NIOS II architecture.

Recently, one of our customers designed a custom NIOS II platform, and we are working on porting the mainline U-Boot bootloader and the mainline Linux kernel to this platform. The U-Boot porting went fine, and quickly allowed us to load and start a Linux kernel. However, the Linux kernel was crashing very early with:

[    0.000000] Linux version 4.5.0-00007-g1717be9-dirty (rperier@archy) (gcc version 4.9.2 (Altera 15.1 Build 185) ) #74 PREEMPT Fri Apr 22 17:43:22 CEST 2016
[    0.000000] bootconsole [early0] enabled
[    0.000000] early_console initialized at 0xe3080000
[    0.000000] BUG: failure at mm/bootmem.c:307/__free()!
[    0.000000] Kernel panic - not syncing: BUG!

This BUG() comes from the __free() function in mm/bootmem.c. The bootmem allocator is a simple page-based allocator used very early in the Linux kernel initialization for the very first allocations, even before the regular buddy page allocator and other allocators such as kmalloc are available. We were slightly surprised to hit a BUG in a generic part of the kernel, and immediately suspected some platform-specific issue, like an invalid load address for our kernel, or invalid link address, or other ideas like this. But we quickly came to the conclusion that everything was looking good on that side, and so we went on to actually understand what this BUG was all about.

The NIOS II memory initialization code in arch/nios2/kernel/setup.c does the following:

bootmap_size = init_bootmem_node(NODE_DATA(0),
                                 min_low_pfn, PFN_DOWN(PHYS_OFFSET),
free_bootmem(memory_start, memory_end - memory_start);

The first call init_bootmem_node() initializes the bootmem allocator, which primarily consists in allocating a bitmap, with one bit per page. The entire bootmem bitmap is set to 0xff via a memset() during this initialization:

static unsigned long __init init_bootmem_core(bootmem_data_t *bdata,
        unsigned long mapstart, unsigned long start, unsigned long end)
        mapsize = bootmap_bytes(end - start);
        memset(bdata->node_bootmem_map, 0xff, mapsize);

After doing the bootmem initialization, the NIOS II architecture code calls free_bootmem() to mark all the memory pages as available, except the ones that contain the kernel itself. To achieve this, the __free() function (which is the one triggering the BUG) clears the bits corresponding to the page to be marked as free. When clearing those bits, the function checks that the bit was previously set, and if it’s not the case, fires the BUG:

static void __init __free(bootmem_data_t *bdata,
                        unsigned long sidx, unsigned long eidx)
        for (idx = sidx; idx < eidx; idx++)
                if (!test_and_clear_bit(idx, bdata->node_bootmem_map))

So to summarize, we were in a situation where a bitmap is memset to 0xff, but almost immediately afterwards, a function that clears some bits finds that some of the bits are already cleared. Sounds odd, doesn’t it?

We started by double checking that the address of the bitmap was the same between the initialization function and the __free function, verifying that the code was not overwriting the bitmap, and other obvious issues. But everything looked alright. So we simply dumped the bitmap after it was initialized by memset to 0xff, and to our great surprise, we found that the bitmap was in fact initialized with the pattern 0xff00ff00 and not 0xffffffff. This obviously explained why we were hitting this BUG(): simply because the buffer was not properly initialized. At first, we really couldn’t believe this: how it is possible that something as essential as memset() in Linux was not doing its job properly?

On the NIOS II platform, memset() has an architecture-specific implementation, available in arch/nios2/lib/memset.c. For buffers smaller than 8 bytes, this memset implementation uses a simple naive loop, iterating byte by byte. For larger buffers, it uses a more optimized implementation, using inline assembly. This implementation copies data per blocks of 4-bytes rather than 1 byte to speed-up the memset.

We quickly tested a workaround that consisted in using the naive implementation for all buffer sizes, and it solved the problem: we had a booting kernel, all the way to the point where it mounts a root filesystem! So clearly, it’s the optimized implementation in assembly that had a bug.

After some investigation, we found out that the bug was in the very first instructions of the assembly code. The following piece of assembly is supposed to create a 4-byte value that repeats 4 times the 1-byte pattern passed as an argument to memset:

/* fill8 %3, %5 (c & 0xff) */
"       slli    %4, %5, 8\n"
"       or      %4, %4, %5\n"
"       slli    %3, %4, 16\n"
"       or      %3, %3, %4\n"

This code takes as input in %5 the one-byte pattern, and is supposed to return in %3 the 4-byte pattern. It goes through the following logic:

  • Stores in %4 the initial pattern shifted left by 8 bits. Provided an initial pattern of 0xff, %4 should now contain 0xff00
  • Does a logical or between %4 and %5, which leads to %4 containing 0xffff
  • Stores in %3 the 2-byte pattern shifted left by 16 bits. %3 should now contain 0xffff0000.
  • Does a logical or between code>%3 and %4, i.e between 0xffff0000 and 0xffff, which gives the expected 4-byte pattern 0xffffffff

When you look at the source code, it looks perfectly fine, so our source code review didn’t spot the problem. However, when looking at the actual compiled code disassembled, we got:

34:	280a923a 	slli	r5,r5,8
38:	294ab03a 	or	r5,r5,r5
3c:	2808943a 	slli	r4,r5,16
40:	2148b03a 	or	r4,r4,r5

Here r5 gets used for both %4 and %5. Due to this, the final pattern stored in r4 is 0xff00ff00 instead of the expected 0xffffffff.

Now, if we take a look at the output operands, %4 is defined with the "=r" constraint, i.e an output operand. How to prevent the compiler from re-using the corresponding register for another operand? As explained in this document, "=r" does not prevent gcc from using the same register for an output operand (%4) and input operand (%5). By adding the constrainst & (in addition to "=r"), we tell the compiler that the register associated with the given operand is an output-only register, and so, cannot be used with an input operand.

With this change, we get the following assembly output:

34:	2810923a 	slli	r8,r5,8
38:	4150b03a 	or	r8,r8,r5
3c:	400e943a 	slli	r7,r8,16
40:	3a0eb03a 	or	r7,r7,r8

Which is much better, and correctly produces the 0xffffffff pattern when 0xff is provided as the initial 1-byte pattern to memset.

In the end, the final patch only adds one character to adjust the inline assembly constraint and gets the proper behavior from gcc:

diff --git a/arch/nios2/lib/memset.c b/arch/nios2/lib/memset.c
index c2cfcb1..2fcefe7 100644
--- a/arch/nios2/lib/memset.c
+++ b/arch/nios2/lib/memset.c
@@ -68,7 +68,7 @@ void *memset(void *s, int c, size_t count)
 		  "=r" (charcnt),	/* %1  Output */
 		  "=r" (dwordcnt),	/* %2  Output */
 		  "=r" (fill8reg),	/* %3  Output */
-		  "=r" (wrkrega)	/* %4  Output */
+		  "=&r" (wrkrega)	/* %4  Output only */
 		: "r" (c),		/* %5  Input */
 		  "0" (s),		/* %0  Input/Output */
 		  "1" (count)		/* %1  Input/Output */

This patch was sent upstream to the NIOS II kernel maintainers:
[PATCH v2] nios2: memset: use the right constraint modifier for the %4 output operand, and has already been applied by the NIOS II maintainer.

We were quite surprised to find a bug in some common code for the NIOS II architecture: we were assuming it would have already been tested on enough platforms and with enough compilers/situations to not have such issues. But all in all, it was a fun debugging experience!

It is worth mentioning that in addition to this bug, we found another bug affecting NIOS II platforms, in the asm-generic implementation of the futex_atomic_cmpxchg_inatomic() function, which was causing some preemption imbalance warnings during the futex subsystem initialization. We also sent a patch for this problem, which has also been applied already.

Linux kernel support for Microcrystal RTCs

micro-crystalThanks to Microcrystal, a Switzerland-based real-time clock vendor, Free-Electrons has contributed support for a number of new I2C and SPI based real-time clocks to the Linux kernel over the last few months. More specifically, we added or improved support for the Microcrystal RV-1805, RV-4162, RV-3029 and RV-3049. In this blog post, we detail the contributions we have done to support those real-time clocks.


The RV-1805 RTC is similar to the Abracon 1805 one, for which a driver already existed in the Linux kernel. Therefore, the support for the RV-1805 RTC was added in the same driver, rtc-abx80x.c. The patch which adds the support of this RTC is already upstream since v4.5 (see Free-Electrons contributions to linux 4.5). In this kernel version, the support of the alarm has also been added. In the 4.6 kernel release, the support for two additional functionalities has been contributed: oscillator selection and handling of oscillator failure.

The oscillator selection functionality allows to select between the two oscillators available in this RTC:

  • The XT oscillator, a more stable, but also more power-hungy oscillator
  • The RC oscillator, a less accurate, but also more power-efficient oscillator

This patch adds the possibility to select which oscillator the RTC should use and also, a way to configure the auto-calibration (auto-calibration is a feature to calibrate the RC oscillator using the digital XT oscillator).

To select the oscillator, a sysfs entry has been added:

cat /sys/class/rtc/rtc0/device/oscillator

To configure and activate the autocalibration, another sysfs entry has been added:

cat /sys/class/rtc/rtc0/device/autocalibration

Here is an example of using RC oscillator and an autocalibration of 512 seconds cycle.

echo rc > /sys/class/rtc/rtc0/device/oscillator
echo 512 > /sys/class/rtc/rtc0/device/autocalibration

The other functionality that was added is handling the Oscillator Failure situation (see this patch). The Oscillator Failure is detected when the XT oscillator generates ticks at less than 8 kHz for more than 32 ms. In this case, the date and time can be wrong so an error is returned when an attempt to read the date from the RTC is made. This Oscillator Failure condition is cleared when a new date/time is set into the RTC.


The RV-4162 RTC is similar to ST M41T80 RTC family, so the existing driver has been used as well. However, as this driver was quite old, eight patches have been contributed to update the driver to newer APIs and to add new functionalities such as oscillator failure and alarm. The patches have already been merged by RTC maintainer Alexandre Belloni and should therefore find their way into the 4.7 Linux kernel release:

  • Cleanups
    • Update the sysfs entry export
    • Remove some unnecessary macro and use BIT macro
    • Update the i2c functions used
    • Remove warnings and obsolete functions
  • New functionalities:
    • alarm, wakealarm and oscillator failure.

See [PATCH 0/8] rtc: m41t80: update and add functionalities for the entire patch series. Thanks to this project, the RV-4162 is now supported in the Linux Kernel and the entire family of I2C-based M41T80 RTCs will benefit from these improvements.

RV-3029 / RV-3049

The RV-3029 RTC driver already existed in the Linux kernel, and the the RV-3049 is the same reference than the RV-3029 but it is an SPI-based interface instead of an I2C one. This is a typical case where the regmap mechanism of the Linux kernel is useful: it allows to abstract the register accesses, regardless of the bus being used to communicate with the hardware. Thanks to this, a single driver can easily handle two devices that are interfaced over different busses, but offering the same register set, which is the case with RV-3029 on I2C and RV-3049 on SPI.

For this driver, some updates were needed to prepare the switch to using the regmap mechanism. Once the driver had been converted to regmap and worked as before, the RV-3049 support has been added. Finally, the alarm functionality has been added and fixed. The corresponding patches have already been merged by the RTC maintainer, and should therefore also be part of Linux 4.7:

  • rtc: rv3029: remove ‘i2c’ in functions names
  • rtc: rv3029: convert to use regmap
  • rtc: rv3029: Add support of RV3049
  • rtc: rv3029: Remove some checks and warnings
  • rtc: rv3029: fix alarm support
  • rtc: rv3029: fix set_time function
  • rtc: rv3029: add alarm IRQ


It is great to see hardware vendors actively engaged in having support for their hardware in the upstream Linux kernel. This way, their users can immediately use the kernel version of their choice on their platform, without having to mess with outdated out-of-tree drivers. Thanks to Microcrystal for supporting this work!

Do not hesitate to contact us if you would like to see your hardware supported in the official Linux kernel. Read more about our Linux kernel upstreaming services.

Linux 4.6 released, with Free Electrons contributions

Adelie PenguinThe 4.6 version of the Linux kernel was released last Sunday by Linus Torvalds. As usual, LWN.net had a very nice coverage of this development cycle merge window, highlighting the most significant changes and improvements: part 1, part 2 and part 3. KernelNewbies is now active again, and has a very detailed page about this release.

On a total of 13517 non-merge commits, Free Electrons contributed for this release a total of 107 non-merge commits, a number slightly lower than our past contributions for previous kernel releases. That being said, there are still a few interesting contributions in those 107 patches. We are particular happy to see patches from all our eight engineers in this release, including from Mylène Josserand and Romain Perier, who just joined us mid-March! We also already have 194 patches lined-up for the next 4.7 release.

Here are the highlights of our contributions to the 4.6 release:

  • Atmel ARM processors support
    • Alexandre Belloni and Boris Brezillon contributed a number of patches to improve and cleanup the support for the PMC (Power Management and Clocks) hardware block. As expected, this involved patching both clock drivers and power management code for the Atmel platforms.
  • Annapurna Labs Alpine platforms support
    • As a newly appointed maintainer of the Annapurna Labs ARM/ARM64 Alpine platforms, Antoine Ténart contributed the base support for the ARM64 Alpine v2 platform: base platform support and Device Tree, and an interrupt controller driver to support MSI-X
  • Marvell ARM processors support
    • Grégory Clement added initial support for the Armada 3700, a new Cortex-A53 based ARM64 SoC from Marvell, as well as a first development board using this SoC. So far, the supported features are: UART, USB and SATA (as well as of course timers and interrupts).
    • Thomas Petazzoni added initial support for the Armada 7K/8K, a new Cortex-A72 based ARM64 SoC from Marvell, as well as a first development board using this SoC. So far, UART, I2C, SPI are supported. However, due to the lack of clock drivers, this initial support can’t be booted yet, the clock drivers and additional support is on its way to 4.7.
    • Thomas Petazzoni contributed an interrupt controller driver for the ODMI interrupt controller found in the Armada 7K/8K SoC.
    • Grégory Clement and Thomas Petazzoni did a few improvements to the support of Armada 38x. Thomas added support for the NAND flash used on Armada 370 DB and Armada XP DB.
    • Boris Brezillon contributed a number of fixes to the Marvell CESA driver, which is used to control the cryptographic engine found in most Marvell EBU processors.
    • Thomas Petazzoni contributed improvements to the irq-armada-370-xp interrupt controller driver, to use the new generic MSI infrastructure.
  • Allwinner ARM processors support
    • Maxime Ripard contributed a few improvements to Allwinner clock drivers, and a few other fixes.
  • MTD and NAND flash subsystem
    • As a maintainer of the NAND subsystem, Boris Brezillon did a number of contributions in this area. Most notably, he added support for the randomizer feature to the Allwinner NAND driver as well as related core NAND subsystem changes. This change is needed to support MLC NANDs on Allwinner platforms. He also contributed several patches to continue clean up and improve the NAND subsystem.
    • Thomas Petazzoni fixed an issue in the pxa3xx_nand driver used on Marvell EBU platforms that prevented using some of the ECC configurations (such as 8 bits BCH ECC on 4 KB pages). He also contributed minor improvements to the generic NAND code.
  • Networking subsystem
    • Grégory Clement contributed an extension to the core networking subsystem that allows to take advantage of hardware capable of doing HW-controlled buffer management. This new extension is used by the mvneta network driver, useful for several Marvell EBU platforms. We expect to extend this mechanism further in the future, in order to take advantage of additional hardware capabilities.
  • RTC subsystem
    • As a maintainer of the RTC subsystem, Alexandre Belloni did a number of fixes and improvements in various RTC drivers.
    • Mylène Josserand contributed a few improvements to the abx80x RTC driver.
  • Altera NIOSII support
    • Romain Perier contributed two patches to fix issues in the kernel running on the Altera NIOSII architecture. The first one, covered in a previous blog post, fixed the NIOSII-specific memset() implementation. The other patch fixes a problem in the generic futex code.

In addition, several our of engineers are maintainers of various platforms or subsystems, so they do a lot of work reviewing and merging the contributions from other kernel developers. This effort can be measured by looking at the number of patches on which they Signed-off-by, but for which they are not the author. Here are the number of patches that our engineered Signed-off-by, but for which they were not the author:

  • Alexandre Belloni, as the RTC subsystem maintainer and the Atmel ARM co-maintainer: 91 patches
  • Maxime Ripard, as the Allwinner ARM co-maintainer: 65 patches
  • Grégory Clement, as the Marvell EBU ARM co-maintainer: 45 patches
  • Thomas Petazzoni, simply resubmitting patches from others: 2 patches

Here is the detailed list of our contributions to the 4.6 kernel release:

  • Alexandre Belloni
    • rtc: rv8803: workaround i2c HW issue
    • rtc: rv3029: stop mentioning rv3029c2
    • rtc: pxa: fix Kconfig indentation
    • rtc: enable COMPILE_TEST
    • rtc: pcf8523: properly handle oscillator stop bit
    • rtc: pcf85063: remove struct pcf85063
    • rtc: pcf85063: remove useless DRV_VERSION
    • rtc: always show I2C
    • rtc: pcf85063: remove useless century handling
    • rtc: rv3029: reword Kconfig option
    • clk: at91: remove useless includes
    • clk: at91: pmc: remove useless capacities handling
    • clk: at91: pmc: drop at91_pmc_base
    • usb: gadget: atmel: access the PMC using regmap
    • ARM: at91: remove useless includes and function prototypes
    • ARM: at91: pm: move idle functions to pm.c
    • ARM: at91: pm: find and remap the pmc
    • ARM: at91: pm: simply call at91_pm_init
    • clk: at91: pmc: move pmc structures to C file
    • clk: at91: pmc: merge at91_pmc_init in atmel_pmc_probe
    • clk: at91: remove IRQ handling and use polling
    • rtc: rx8025: remove rv8803 id
  • Antoine Tenart
    • Documentation/bindings: Document the Alpine MSIX driver
    • irqchip: Add the Alpine MSIX interrupt controller
    • irqchip/gic-v3: Always return IRQ_SET_MASK_OK_DONE in gic_set_affinity
    • arm64: dts: alpine: add the MSIX node in the Alpine v2 dtsi
    • arm64: dts: add the Alpine v2 EVP
    • ARM: dts: alpine: add the MSIX node
    • ARM: alpine: select the Alpine MSI controller driver
    • arm64: alpine: select the Alpine MSI controller driver
    • arm64: defconfig: enable the Alpine family
    • arm64: add Alpine SoC family
  • Boris Brezillon
    • ARM: dts: at91: sam9x5: Fix the memory range assigned to the PMC
    • crypto: marvell/cesa – forward devm_ioremap_resource() error code
    • crypto: marvell/cesa – initialize hash states
    • crypto: marvell/cesa – fix memory leak
    • mtd: nand: simplify nand_bch_init() usage
    • mtd: mtdswap: remove useless if (!mtd->ecclayout) test
    • mtd: create an mtd_oobavail() helper and make use of it
    • mtd: kill the ecclayout->oobavail field
    • mtd: nand: sunxi: remove direct mtd->priv accesses
    • clk: at91: make use of syscon/regmap internally
    • clk: at91: make use of syscon to share PMC registers in several drivers
    • mtd: nand: vf610: remove useless mtd->ecclayout assignment
    • mtd: nand: lpc32xx_mlc: fix ecc.size
    • staging: mt29f_spinand: kill unused ecclayout field
    • mtd: nand: kill unused ->ecclayout field in platform_nand_chip struct
    • mtd: nand: jz4740: kill the ->ecc_layout field
    • mtd: nand: s3c2410: kill the ->ecc_layout field
    • mtd: nftl: kill unused oobinfo field
    • mtd: inftl: kill unused oobinfo field
    • mtd: nand: sunxi: add randomizer support
    • mtd: nand: add NAND_NEED_SCRAMBLING flag to the H27UCG8T2ATR-BC definition
    • mtd: nand: add NAND_NEED_SCRAMBLING option flag
  • Gregory Clement
    • net: mvneta: Fix spinlock usage
    • net: mvneta: Use the new hwbm framework
    • net: add a hardware buffer management helper API
    • ARM: dts: armada-xp-openblocks-ax3-4: Add BM support
    • arm64: defconfig: enable Armada 3700 related config
    • Documentation: arm: update supported Marvell EBU processors
    • MAINTAINERS: Extend dts entry for ARM64 mvebu files
    • arm64: add mvebu architecture entry
    • arm64: dts: add the Marvell Armada 3700 family and a development board
    • devicetree: bindings: add DT binding for the Marvell Armada 3700 SoC family
    • Documentation: dt: Tidy up the Marvell related files
    • Documentation: dt-bindings: Add a new compatible for the Armada 3700
    • irqchip/armada-370-xp: Do not enable it by default when ARCH_MVEBU is selected
    • ARM: dts: armada-370: Update the mpp63 function in the device tree on Armada 370
    • ARM: dts: armada-38x: use usb-nop-xceiv PHY for the xhci nodes on Armada 388 GP
    • ARM: mvebu: Add USB nop xceiv support in mvebu_v7_defconfig
  • Mylene Josserand
    • rtc: abx80x: handle the oscillator failure bit
    • rtc: abx80x: handle autocalibration
  • Romain Perier
    • nios2: memset: use the right constraint modifier for the %4 output operand
    • asm-generic/futex: Re-enable preemption in futex_atomic_cmpxchg_inatomic()
  • Thomas Petazzoni
    • dt-bindings: interrupt-controller: Add SoC-specific compatible string to Marvell ODMI
    • arm64: dts: marvell: re-order Device Tree nodes for Armada AP806
    • arm64: dts: marvell: update Armada AP806 clock description
    • arm64: dts: marvell: add Device Tree files for Armada 7K/8K
    • irqchip/mvebu-odmi: Add new driver for platform MSI on Marvell 7K/8K
    • arm64: update ARCH_MVEBU for Marvell Armada 7K/8K support
    • Documentation: arm: add Marvell Armada 7K and 8K families
    • Documentation: arm: add link to Armada 38x Functional Spec
    • Documentation: arm: improve Armada 37xx description
    • ARM: mvebu: Use the ARMADA_370_XP_IRQ option
    • irqchip/armada-370-xp: Allow allocation of multiple MSIs
    • irqchip/armada-370-xp: Use shorter names for irq_chip
    • irqchip/armada-370-xp: Use PCI_MSI_DOORBELL_START where appropriate
    • irqchip/armada-370-xp: Use the generic MSI infrastructure
    • irqchip/armada-370-xp: Add Kconfig option for the driver
    • mtd: nand: pxa3xx_nand: add support for partial chunks
    • ARM: dts: mvebu: add NAND description to Armada 370 DB and Armada XP DB
    • ARM: dts: armada-38x: add reference to ETH connectors for A385-AP
    • ARM: dts: armada-38x: change order of ethernet DT nodes on Armada 38x
    • ARM: dts: armada-38x: use regulator-boot-on for SATA regulators on Armada 388 GP
    • ARM: dts: armada-38x: adjust board name and compatible for Armada 388 GP
    • mtd: onenand: unexport onenand_default_bbt()
    • mtd: onenand: make onenand_scan_bbt() static
    • mtd: nand: remove EXPORT_SYMBOL of nand_scan_bbt()
  • Maxime Ripard
    • regulator: axp20x: Fix LDO4 linear voltage range
    • clk: sunxi: Remove clk_register_clkdev calls
    • clk: sunxi: Remove old probe and protection code
    • clk: sunxi: convert current clocks registration to CLK_OF_DECLARE
    • clk: sunxi: Make clocks setup functions take const pointer
    • clk: sunxi: Make clocks setup functions return their clock
    • reset: Move DT cell size check to the core
    • reset: Make reset_control_ops const
    • ARM: sun5i: chip: Add CPU regulator for cpufreq