Checklist for Linux SoC ports (Thomas Petazzoni)

Thomas works on kernel support for Marvell Armada 370 and Armada XP.

The ARM cleanup means that things have been changing a lot in the last two years. This makes it harder to know what is the proper way to work now.

Russel King is core ARM maintainer, Arnd Bergmann and Olof Johansson look after the SoC code (i.e. mach-* and plat-*) – they make sure things are coherent between the different SoCs. Git tree in linux/kernel/git/arm/arm-soc.git. In addition, there are maintainers of other subsystems: clocksource, irqchip, pinctrl, gpio, clk.

Do not reuse existing SoC code. Most of it is rubbish that doesn’t use the existing infrastructures.

Start minimal:

  • Device tree. No more machine ID passed by boot loader; instead it’s a device tree. Device tree is split into a .dtsi for the SoC and a .dts that includes it for the board. Board DTS “inherits” some of the SoC nodes, typically just overriding the status from “disabled” to “okay”.
  • arch/arm/mach/mach-mvebu/armadaxp.c contains DT_MACHINE_START(). Also a header file that contains the minimal register definitions for a debug UART. Don’t use any #if to make code depend on the SoC – it has to be detected at runtime based on the DTB. DT_MACHINE_START is matched against the compatible field of the DT. Most of the other stuff is there to support early debug IO. init_machine just calls of_platform_populate().
  • earlyprintk support: is currently only working for one SoC (i.e you can boot multiple machines but only get earlyprintk on one of them). Your earlyprintk support is in an assembly file. You can also just implement an “addruart” macro and use one of the existing UART implementations.
  • IRQ controller: GIC and VIC from ARM are already in arch/arm/common, but they will move to drivers/irqchip.  Referenced by handle_irq and init_irq fields in DT_MACHINE_START. IRQ controller pdata is retrieved from DT.
  • timer driver: in drivers/clocksource. Register two devices: a free-running clocksource, and a programmable interrupting clockevents.
  • UART driver in drivers/tty/serial. Must have DT binding.

With this, you can boot an initramfs. This can be submitted already, so you can catch feedback.

Clock framework: in the past, each subarch had its own clock tree implementation. Clock framework creates common API for clk_get, clk_put, clk_get_rate, … DT declares the available clocks and their relations. DT also specifies how devices are connected to clocks.  So the driver just does clk_get(&dev->dev) to get the clock for that device.

Pinmuxing:had to be done by the BSP, not the driver, so you could end up with a driver that has unusable pins. Pinctrl combines API for driver to request a certain muxing, with automatic setting of other controls correctly (e.g. pull-up). SoC DT describes the different choices for each pin. board DT maps for each device the required pins. GPIO drivers must also use pincttrl.

Other drivers: not much has changed, except DT bindings are required (look at other drivers so reuse existing binding names). Not allowed to include mach/… because that conflicts with multiplatform.

Good examples: highbank, socfpga, bcm2835, mxs, mvebu.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s