diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm2708.dtsi linux-vendor/arch/arm/boot/dts/bcm2708.dtsi --- linux-4.18.16/arch/arm/boot/dts/bcm2708.dtsi 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/bcm2708.dtsi 2018-10-29 19:31:20.480786145 +0100 @@ -0,0 +1,11 @@ +#include "bcm2835.dtsi" +#include "bcm270x.dtsi" +#include "bcm2708-rpi.dtsi" + +/ { + /delete-node/ cpus; + + __overrides__ { + arm_freq; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm2708-rpi-0-w.dts linux-vendor/arch/arm/boot/dts/bcm2708-rpi-0-w.dts --- linux-4.18.16/arch/arm/boot/dts/bcm2708-rpi-0-w.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/bcm2708-rpi-0-w.dts 2018-10-29 19:31:20.458787243 +0100 @@ -0,0 +1,166 @@ +/dts-v1/; + +#include "bcm2708.dtsi" + +/ { + compatible = "raspberrypi,model-zero-w", "brcm,bcm2835"; + model = "Raspberry Pi Zero W"; + + chosen { + bootargs = "8250.nr_uarts=1"; + }; + + aliases { + serial0 = &uart1; + serial1 = &uart0; + }; +}; + +&gpio { + spi0_pins: spi0_pins { + brcm,pins = <9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + + spi0_cs_pins: spi0_cs_pins { + brcm,pins = <8 7>; + brcm,function = <1>; /* output */ + }; + + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; + }; + + i2c1_pins: i2c1 { + brcm,pins = <2 3>; + brcm,function = <4>; + }; + + i2s_pins: i2s { + brcm,pins = <18 19 20 21>; + brcm,function = <4>; /* alt0 */ + }; + + sdio_pins: sdio_pins { + brcm,pins = <34 35 36 37 38 39>; + brcm,function = <7>; /* ALT3 = SD1 */ + brcm,pull = <0 2 2 2 2 2>; + }; + + bt_pins: bt_pins { + brcm,pins = <43>; + brcm,function = <4>; /* alt0:GPCLK2 */ + brcm,pull = <0>; /* none */ + }; + + uart0_pins: uart0_pins { + brcm,pins = <30 31 32 33>; + brcm,function = <7>; /* alt3=UART0 */ + brcm,pull = <2 0 0 2>; /* up none none up */ + }; + + uart1_pins: uart1_pins { + brcm,pins; + brcm,function; + brcm,pull; + }; + + audio_pins: audio_pins { + brcm,pins = <>; + brcm,function = <>; + }; +}; + +&mmc { + pinctrl-names = "default"; + pinctrl-0 = <&sdio_pins>; + non-removable; + bus-width = <4>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins &bt_pins>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "okay"; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + + spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; + + spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + clock-frequency = <100000>; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <100000>; +}; + +&i2c2 { + clock-frequency = <100000>; +}; + +&i2s { + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s_pins>; +}; + +&random { + status = "okay"; +}; + +&leds { + act_led: act { + label = "led0"; + linux,default-trigger = "mmc0"; + gpios = <&gpio 47 0>; + }; +}; + +&hdmi { + hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; +}; + +&audio { + pinctrl-names = "default"; + pinctrl-0 = <&audio_pins>; +}; + +/ { + __overrides__ { + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm2708-rpi-b.dts linux-vendor/arch/arm/boot/dts/bcm2708-rpi-b.dts --- linux-4.18.16/arch/arm/boot/dts/bcm2708-rpi-b.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/bcm2708-rpi-b.dts 2018-10-29 19:31:20.458787243 +0100 @@ -0,0 +1,112 @@ +/dts-v1/; + +#include "bcm2708.dtsi" +#include "bcm283x-rpi-smsc9512.dtsi" + +/ { + model = "Raspberry Pi Model B"; +}; + +&gpio { + spi0_pins: spi0_pins { + brcm,pins = <9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + + spi0_cs_pins: spi0_cs_pins { + brcm,pins = <8 7>; + brcm,function = <1>; /* output */ + }; + + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; + }; + + i2c1_pins: i2c1 { + brcm,pins = <2 3>; + brcm,function = <4>; + }; + + i2s_pins: i2s { + brcm,pins = <28 29 30 31>; + brcm,function = <6>; /* alt2 */ + }; + + audio_pins: audio_pins { + brcm,pins = <40 45>; + brcm,function = <4>; + }; +}; + +&uart0 { + status = "okay"; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + + spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; + + spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + clock-frequency = <100000>; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <100000>; +}; + +&i2c2 { + clock-frequency = <100000>; +}; + +&i2s { + pinctrl-names = "default"; + pinctrl-0 = <&i2s_pins>; +}; + +&leds { + act_led: act { + label = "led0"; + linux,default-trigger = "mmc0"; + gpios = <&gpio 16 1>; + }; +}; + +&hdmi { + hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; +}; + +&audio { + pinctrl-names = "default"; + pinctrl-0 = <&audio_pins>; +}; + +/ { + __overrides__ { + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts linux-vendor/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts --- linux-4.18.16/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts 2018-10-29 19:31:20.458787243 +0100 @@ -0,0 +1,122 @@ +/dts-v1/; + +#include "bcm2708.dtsi" +#include "bcm283x-rpi-smsc9514.dtsi" + +/ { + model = "Raspberry Pi Model B+"; +}; + +&gpio { + spi0_pins: spi0_pins { + brcm,pins = <9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + + spi0_cs_pins: spi0_cs_pins { + brcm,pins = <8 7>; + brcm,function = <1>; /* output */ + }; + + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; + }; + + i2c1_pins: i2c1 { + brcm,pins = <2 3>; + brcm,function = <4>; + }; + + i2s_pins: i2s { + brcm,pins = <18 19 20 21>; + brcm,function = <4>; /* alt0 */ + }; + + audio_pins: audio_pins { + brcm,pins = <40 45>; + brcm,function = <4>; + }; +}; + +&uart0 { + status = "okay"; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + + spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; + + spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + clock-frequency = <100000>; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <100000>; +}; + +&i2c2 { + clock-frequency = <100000>; +}; + +&i2s { + pinctrl-names = "default"; + pinctrl-0 = <&i2s_pins>; +}; + +&leds { + act_led: act { + label = "led0"; + linux,default-trigger = "mmc0"; + gpios = <&gpio 47 0>; + }; + + pwr_led: pwr { + label = "led1"; + linux,default-trigger = "input"; + gpios = <&gpio 35 0>; + }; +}; + +&hdmi { + hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; +}; + +&audio { + pinctrl-names = "default"; + pinctrl-0 = <&audio_pins>; +}; + +/ { + __overrides__ { + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; + + pwr_led_gpio = <&pwr_led>,"gpios:4"; + pwr_led_activelow = <&pwr_led>,"gpios:8"; + pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm2708-rpi-cm.dts linux-vendor/arch/arm/boot/dts/bcm2708-rpi-cm.dts --- linux-4.18.16/arch/arm/boot/dts/bcm2708-rpi-cm.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/bcm2708-rpi-cm.dts 2018-10-29 19:31:20.458787243 +0100 @@ -0,0 +1,95 @@ +/dts-v1/; + +#include "bcm2708-rpi-cm.dtsi" + +/ { + model = "Raspberry Pi Compute Module"; +}; + +&uart0 { + status = "okay"; +}; + +&gpio { + spi0_pins: spi0_pins { + brcm,pins = <9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + + spi0_cs_pins: spi0_cs_pins { + brcm,pins = <8 7>; + brcm,function = <1>; /* output */ + }; + + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; + }; + + i2c1_pins: i2c1 { + brcm,pins = <2 3>; + brcm,function = <4>; + }; + + i2s_pins: i2s { + brcm,pins = <18 19 20 21>; + brcm,function = <4>; /* alt0 */ + }; + + audio_pins: audio_pins { + brcm,pins; + brcm,function; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + + spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; + + spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + clock-frequency = <100000>; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <100000>; +}; + +&i2c2 { + clock-frequency = <100000>; +}; + +&i2s { + pinctrl-names = "default"; + pinctrl-0 = <&i2s_pins>; +}; + +&audio { + pinctrl-names = "default"; + pinctrl-0 = <&audio_pins>; +}; + +&hdmi { + hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi linux-vendor/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi --- linux-4.18.16/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi 2018-10-29 19:31:20.459787193 +0100 @@ -0,0 +1,17 @@ +#include "bcm2708.dtsi" + +&leds { + act_led: act { + label = "led0"; + linux,default-trigger = "mmc0"; + gpios = <&gpio 47 0>; + }; +}; + +/ { + __overrides__ { + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm2708-rpi.dtsi linux-vendor/arch/arm/boot/dts/bcm2708-rpi.dtsi --- linux-4.18.16/arch/arm/boot/dts/bcm2708-rpi.dtsi 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/bcm2708-rpi.dtsi 2018-10-29 19:31:20.480786145 +0100 @@ -0,0 +1,159 @@ +/* Downstream version of bcm2835-rpi.dtsi */ + +#include + +/ { + memory { + device_type = "memory"; + reg = <0x0 0x0>; + }; + + aliases { + audio = &audio; + aux = &aux; + sound = &sound; + soc = &soc; + dma = &dma; + intc = &intc; + watchdog = &watchdog; + random = &random; + mailbox = &mailbox; + gpio = &gpio; + uart0 = &uart0; + sdhost = &sdhost; + mmc0 = &sdhost; + i2s = &i2s; + spi0 = &spi0; + i2c0 = &i2c0; + uart1 = &uart1; + spi1 = &spi1; + spi2 = &spi2; + mmc = &mmc; + mmc1 = &mmc; + i2c1 = &i2c1; + i2c2 = &i2c2; + usb = &usb; + leds = &leds; + fb = &fb; + thermal = &thermal; + axiperf = &axiperf; + }; + + leds: leds { + compatible = "gpio-leds"; + }; + + soc { + gpiomem { + compatible = "brcm,bcm2835-gpiomem"; + reg = <0x7e200000 0x1000>; + }; + + firmware: firmware { + compatible = "raspberrypi,bcm2835-firmware"; + mboxes = <&mailbox>; + }; + + power: power { + compatible = "raspberrypi,bcm2835-power"; + firmware = <&firmware>; + #power-domain-cells = <1>; + }; + + fb: fb { + compatible = "brcm,bcm2708-fb"; + firmware = <&firmware>; + status = "disabled"; + }; + + mailbox@7e00b840 { + compatible = "brcm,bcm2835-vchiq"; + reg = <0x7e00b840 0x3c>; + interrupts = <0 2>; + }; + + vcsm: vcsm { + compatible = "raspberrypi,bcm2835-vcsm"; + firmware = <&firmware>; + status = "okay"; + }; + + /* Onboard audio */ + audio: audio { + compatible = "brcm,bcm2835-audio"; + brcm,pwm-channels = <8>; + status = "disabled"; + }; + + /* External sound card */ + sound: sound { + status = "disabled"; + }; + }; + + __overrides__ { + cache_line_size; + + uart0 = <&uart0>,"status"; + uart1 = <&uart1>,"status"; + i2s = <&i2s>,"status"; + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; + i2c1 = <&i2c1>,"status"; + i2c2_iknowwhatimdoing = <&i2c2>,"status"; + i2c0_baudrate = <&i2c0>,"clock-frequency:0"; + i2c1_baudrate = <&i2c1>,"clock-frequency:0"; + i2c2_baudrate = <&i2c2>,"clock-frequency:0"; + + audio = <&audio>,"status"; + watchdog = <&watchdog>,"status"; + random = <&random>,"status"; + sd_overclock = <&sdhost>,"brcm,overclock-50:0"; + sd_force_pio = <&sdhost>,"brcm,force-pio?"; + sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; + sd_debug = <&sdhost>,"brcm,debug"; + sdio_overclock = <&mmc>,"brcm,overclock-50:0"; + axiperf = <&axiperf>,"status"; + }; +}; + +&dma { + brcm,dma-channel-mask = <0x7f34>; +}; + +&hdmi { + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; +}; + +&usb { + power-domains = <&power RPI_POWER_DOMAIN_USB>; +}; + +&clocks { + firmware = <&firmware>; +}; + +sdhost_pins: &sdhost_gpio48 { + /* Add alias */ +}; + +&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + bus-width = <4>; + brcm,overclock-50 = <0>; + brcm,pio-limit = <1>; + status = "okay"; +}; + +&fb { + status = "okay"; +}; + +&cpu_thermal { + /delete-node/ trips; +}; + +&vec { + status = "disabled"; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm2709.dtsi linux-vendor/arch/arm/boot/dts/bcm2709.dtsi --- linux-4.18.16/arch/arm/boot/dts/bcm2709.dtsi 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/bcm2709.dtsi 2018-10-29 19:31:20.481786095 +0100 @@ -0,0 +1,19 @@ +#include "bcm2836.dtsi" +#include "bcm270x.dtsi" +#include "bcm2708-rpi.dtsi" + +/ { + soc { + ranges = <0x7e000000 0x3f000000 0x01000000>, + <0x40000000 0x40000000 0x00040000>; + + /delete-node/ timer@7e003000; + }; + + __overrides__ { + arm_freq = <&v7_cpu0>, "clock-frequency:0", + <&v7_cpu1>, "clock-frequency:0", + <&v7_cpu2>, "clock-frequency:0", + <&v7_cpu3>, "clock-frequency:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm2709-rpi-2-b.dts linux-vendor/arch/arm/boot/dts/bcm2709-rpi-2-b.dts --- linux-4.18.16/arch/arm/boot/dts/bcm2709-rpi-2-b.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/bcm2709-rpi-2-b.dts 2018-10-29 19:31:20.481786095 +0100 @@ -0,0 +1,123 @@ +/dts-v1/; + +#include "bcm2709.dtsi" +#include "bcm283x-rpi-smsc9514.dtsi" + +/ { + compatible = "raspberrypi,2-model-b", "brcm,bcm2836"; + model = "Raspberry Pi 2 Model B"; +}; + +&gpio { + spi0_pins: spi0_pins { + brcm,pins = <9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + + spi0_cs_pins: spi0_cs_pins { + brcm,pins = <8 7>; + brcm,function = <1>; /* output */ + }; + + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; + }; + + i2c1_pins: i2c1 { + brcm,pins = <2 3>; + brcm,function = <4>; + }; + + i2s_pins: i2s { + brcm,pins = <18 19 20 21>; + brcm,function = <4>; /* alt0 */ + }; + + audio_pins: audio_pins { + brcm,pins = <40 45>; + brcm,function = <4>; + }; +}; + +&uart0 { + status = "okay"; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + + spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; + + spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + clock-frequency = <100000>; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <100000>; +}; + +&i2c2 { + clock-frequency = <100000>; +}; + +&i2s { + pinctrl-names = "default"; + pinctrl-0 = <&i2s_pins>; +}; + +&leds { + act_led: act { + label = "led0"; + linux,default-trigger = "mmc0"; + gpios = <&gpio 47 0>; + }; + + pwr_led: pwr { + label = "led1"; + linux,default-trigger = "input"; + gpios = <&gpio 35 0>; + }; +}; + +&hdmi { + hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; +}; + +&audio { + pinctrl-names = "default"; + pinctrl-0 = <&audio_pins>; +}; + +/ { + __overrides__ { + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; + + pwr_led_gpio = <&pwr_led>,"gpios:4"; + pwr_led_activelow = <&pwr_led>,"gpios:8"; + pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm270x.dtsi linux-vendor/arch/arm/boot/dts/bcm270x.dtsi --- linux-4.18.16/arch/arm/boot/dts/bcm270x.dtsi 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/bcm270x.dtsi 2018-10-29 19:31:20.481786095 +0100 @@ -0,0 +1,152 @@ +/* Downstream bcm283x.dtsi diff */ +#include + +/ { + chosen { + bootargs = ""; + /delete-property/ stdout-path; + }; + + soc: soc { + + watchdog: watchdog@7e100000 { + /* Add alias */ + }; + + random: rng@7e104000 { + /* Add alias */ + }; + + gpio@7e200000 { /* gpio */ + interrupts = <2 17>, <2 18>; + }; + + serial@7e201000 { /* uart0 */ + /* Enable CTS bug workaround */ + cts-event-workaround; + }; + + i2s@7e203000 { /* i2s */ + #sound-dai-cells = <0>; + reg = <0x7e203000 0x24>; + clocks = <&clocks BCM2835_CLOCK_PCM>; + }; + + spi0: spi@7e204000 { + /* Add alias */ + dmas = <&dma 6>, <&dma 7>; + dma-names = "tx", "rx"; + }; + + pixelvalve0: pixelvalve@7e206000 { + /* Add alias */ + status = "disabled"; + }; + + pixelvalve1: pixelvalve@7e207000 { + /* Add alias */ + status = "disabled"; + }; + + dpi: dpi@7e208000 { + compatible = "brcm,bcm2835-dpi"; + reg = <0x7e208000 0x8c>; + clocks = <&clocks BCM2835_CLOCK_VPU>, + <&clocks BCM2835_CLOCK_DPI>; + clock-names = "core", "pixel"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + /delete-node/ sdhci@7e300000; + + mmc: mmc@7e300000 { + compatible = "brcm,bcm2835-mmc", "brcm,bcm2835-sdhci"; + reg = <0x7e300000 0x100>; + interrupts = <2 30>; + clocks = <&clocks BCM2835_CLOCK_EMMC>; + dmas = <&dma 11>; + dma-names = "rx-tx"; + brcm,overclock-50 = <0>; + status = "disabled"; + }; + + hvs: hvs@7e400000 { + /* Add alias */ + status = "disabled"; + }; + + firmwarekms: firmwarekms@7e600000 { + compatible = "raspberrypi,rpi-firmware-kms"; + /* SMI interrupt reg */ + reg = <0x7e600000 0x100>; + interrupts = <2 16>; + brcm,firmware = <&firmware>; + status = "disabled"; + }; + + smi: smi@7e600000 { + compatible = "brcm,bcm2835-smi"; + reg = <0x7e600000 0x100>; + interrupts = <2 16>; + clocks = <&clocks BCM2835_CLOCK_SMI>; + assigned-clocks = <&clocks BCM2835_CLOCK_SMI>; + assigned-clock-rates = <125000000>; + dmas = <&dma 4>; + dma-names = "rx-tx"; + status = "disabled"; + }; + + pixelvalve2: pixelvalve@7e807000 { + /* Add alias */ + status = "disabled"; + }; + + hdmi@7e902000 { /* hdmi */ + status = "disabled"; + }; + + usb@7e980000 { /* usb */ + compatible = "brcm,bcm2708-usb"; + reg = <0x7e980000 0x10000>, + <0x7e006000 0x1000>; + interrupts = <2 0>, + <1 9>; + }; + + v3d@7ec00000 { /* vd3 */ + compatible = "brcm,vc4-v3d"; + power-domains = <&power RPI_POWER_DOMAIN_V3D>; + status = "disabled"; + }; + + axiperf: axiperf { + compatible = "brcm,bcm2835-axiperf"; + reg = <0x7e009800 0x100>, + <0x7ee08000 0x100>; + firmware = <&firmware>; + status = "disabled"; + }; + }; + + vdd_5v0_reg: fixedregulator_5v0 { + compatible = "regulator-fixed"; + regulator-name = "5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + vdd_3v3_reg: fixedregulator_3v3 { + compatible = "regulator-fixed"; + regulator-name = "3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; +}; + +&vc4 { + status = "disabled"; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm2710.dtsi linux-vendor/arch/arm/boot/dts/bcm2710.dtsi --- linux-4.18.16/arch/arm/boot/dts/bcm2710.dtsi 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/bcm2710.dtsi 2018-10-29 19:31:20.481786095 +0100 @@ -0,0 +1,29 @@ +#include "bcm2837.dtsi" +#include "bcm270x.dtsi" +#include "bcm2708-rpi.dtsi" + +/ { + compatible = "brcm,bcm2837", "brcm,bcm2836"; + + soc { + + arm-pmu { +#ifdef RPI364 + compatible = "arm,armv8-pmuv3", "arm,cortex-a7-pmu"; +#else + compatible = "arm,cortex-a7-pmu"; +#endif + interrupt-parent = <&local_intc>; + interrupts = <9 IRQ_TYPE_LEVEL_HIGH>; + }; + + /delete-node/ timer@7e003000; + }; + + __overrides__ { + arm_freq = <&cpu0>, "clock-frequency:0", + <&cpu1>, "clock-frequency:0", + <&cpu2>, "clock-frequency:0", + <&cpu3>, "clock-frequency:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm2710-rpi-3-b.dts linux-vendor/arch/arm/boot/dts/bcm2710-rpi-3-b.dts --- linux-4.18.16/arch/arm/boot/dts/bcm2710-rpi-3-b.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/bcm2710-rpi-3-b.dts 2018-10-29 19:31:20.481786095 +0100 @@ -0,0 +1,191 @@ +/dts-v1/; + +#include "bcm2710.dtsi" +#include "bcm283x-rpi-smsc9514.dtsi" + +/ { + compatible = "raspberrypi,3-model-b", "brcm,bcm2837"; + model = "Raspberry Pi 3 Model B"; + + chosen { + bootargs = "8250.nr_uarts=1"; + }; + + aliases { + serial0 = &uart1; + serial1 = &uart0; + }; +}; + +&gpio { + spi0_pins: spi0_pins { + brcm,pins = <9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + + spi0_cs_pins: spi0_cs_pins { + brcm,pins = <8 7>; + brcm,function = <1>; /* output */ + }; + + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; + }; + + i2c1_pins: i2c1 { + brcm,pins = <2 3>; + brcm,function = <4>; + }; + + i2s_pins: i2s { + brcm,pins = <18 19 20 21>; + brcm,function = <4>; /* alt0 */ + }; + + sdio_pins: sdio_pins { + brcm,pins = <34 35 36 37 38 39>; + brcm,function = <7>; // alt3 = SD1 + brcm,pull = <0 2 2 2 2 2>; + }; + + bt_pins: bt_pins { + brcm,pins = <43>; + brcm,function = <4>; /* alt0:GPCLK2 */ + brcm,pull = <0>; + }; + + uart0_pins: uart0_pins { + brcm,pins = <32 33>; + brcm,function = <7>; /* alt3=UART0 */ + brcm,pull = <0 2>; + }; + + uart1_pins: uart1_pins { + brcm,pins; + brcm,function; + brcm,pull; + }; + + audio_pins: audio_pins { + brcm,pins = <40 41>; + brcm,function = <4>; + }; +}; + +&mmc { + pinctrl-names = "default"; + pinctrl-0 = <&sdio_pins>; + non-removable; + bus-width = <4>; + status = "okay"; + brcm,overclock-50 = <0>; +}; + +&soc { + virtgpio: virtgpio { + compatible = "brcm,bcm2835-virtgpio"; + gpio-controller; + #gpio-cells = <2>; + firmware = <&firmware>; + status = "okay"; + }; + + expgpio: expgpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; + #gpio-cells = <2>; + firmware = <&firmware>; + status = "okay"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins &bt_pins>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "okay"; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + + spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; + + spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + clock-frequency = <100000>; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <100000>; +}; + +&i2c2 { + clock-frequency = <100000>; +}; + +&i2s { + pinctrl-names = "default"; + pinctrl-0 = <&i2s_pins>; +}; + +&leds { + act_led: act { + label = "led0"; + linux,default-trigger = "mmc0"; + gpios = <&virtgpio 0 0>; + }; + + pwr_led: pwr { + label = "led1"; + linux,default-trigger = "input"; + gpios = <&expgpio 7 0>; + }; +}; + +&hdmi { + hpd-gpios = <&expgpio 4 GPIO_ACTIVE_LOW>; +}; + +&audio { + pinctrl-names = "default"; + pinctrl-0 = <&audio_pins>; +}; + +/ { + __overrides__ { + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; + + pwr_led_gpio = <&pwr_led>,"gpios:4"; + pwr_led_activelow = <&pwr_led>,"gpios:8"; + pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts linux-vendor/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts --- linux-4.18.16/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts 2018-10-29 19:31:20.481786095 +0100 @@ -0,0 +1,183 @@ +/dts-v1/; + +#include "bcm2710.dtsi" +#include "bcm283x-rpi-lan7515.dtsi" + +/ { + compatible = "raspberrypi,3-model-b-plus", "brcm,bcm2837"; + model = "Raspberry Pi 3 Model B+"; + + chosen { + bootargs = "8250.nr_uarts=1"; + }; + + aliases { + serial0 = &uart1; + serial1 = &uart0; + }; +}; + +&gpio { + spi0_pins: spi0_pins { + brcm,pins = <9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + + spi0_cs_pins: spi0_cs_pins { + brcm,pins = <8 7>; + brcm,function = <1>; /* output */ + }; + + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; + }; + + i2c1_pins: i2c1 { + brcm,pins = <2 3>; + brcm,function = <4>; + }; + + i2s_pins: i2s { + brcm,pins = <18 19 20 21>; + brcm,function = <4>; /* alt0 */ + }; + + sdio_pins: sdio_pins { + brcm,pins = <34 35 36 37 38 39>; + brcm,function = <7>; // alt3 = SD1 + brcm,pull = <0 2 2 2 2 2>; + }; + + bt_pins: bt_pins { + brcm,pins = <43>; + brcm,function = <4>; /* alt0:GPCLK2 */ + brcm,pull = <0>; + }; + + uart0_pins: uart0_pins { + brcm,pins = <32 33>; + brcm,function = <7>; /* alt3=UART0 */ + brcm,pull = <0 2>; + }; + + uart1_pins: uart1_pins { + brcm,pins; + brcm,function; + brcm,pull; + }; + + audio_pins: audio_pins { + brcm,pins = <40 41>; + brcm,function = <4>; + }; +}; + +&mmc { + pinctrl-names = "default"; + pinctrl-0 = <&sdio_pins>; + non-removable; + bus-width = <4>; + status = "okay"; + brcm,overclock-50 = <0>; +}; + +&soc { + expgpio: expgpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; + #gpio-cells = <2>; + firmware = <&firmware>; + status = "okay"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins &bt_pins>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "okay"; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + + spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; + + spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + clock-frequency = <100000>; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <100000>; +}; + +&i2c2 { + clock-frequency = <100000>; +}; + +&i2s { + pinctrl-names = "default"; + pinctrl-0 = <&i2s_pins>; +}; + +&leds { + act_led: act { + label = "led0"; + linux,default-trigger = "mmc0"; + gpios = <&gpio 29 0>; + }; + + pwr_led: pwr { + label = "led1"; + linux,default-trigger = "default-on"; + gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; + }; +}; + +&hdmi { + hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>; +}; + +&audio { + pinctrl-names = "default"; + pinctrl-0 = <&audio_pins>; +}; + +/ { + __overrides__ { + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; + + pwr_led_gpio = <&pwr_led>,"gpios:4"; + pwr_led_activelow = <&pwr_led>,"gpios:8"; + pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm2710-rpi-cm3.dts linux-vendor/arch/arm/boot/dts/bcm2710-rpi-cm3.dts --- linux-4.18.16/arch/arm/boot/dts/bcm2710-rpi-cm3.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/bcm2710-rpi-cm3.dts 2018-10-29 19:31:20.481786095 +0100 @@ -0,0 +1,129 @@ +/dts-v1/; + +#include "bcm2710.dtsi" + +/ { + model = "Raspberry Pi Compute Module 3"; +}; + +&uart0 { + status = "okay"; +}; + +&gpio { + spi0_pins: spi0_pins { + brcm,pins = <9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + + spi0_cs_pins: spi0_cs_pins { + brcm,pins = <8 7>; + brcm,function = <1>; /* output */ + }; + + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; + }; + + i2c1_pins: i2c1 { + brcm,pins = <2 3>; + brcm,function = <4>; + }; + + i2s_pins: i2s { + brcm,pins = <18 19 20 21>; + brcm,function = <4>; /* alt0 */ + }; + + audio_pins: audio_pins { + brcm,pins; + brcm,function; + }; +}; + +&soc { + virtgpio: virtgpio { + compatible = "brcm,bcm2835-virtgpio"; + gpio-controller; + #gpio-cells = <2>; + firmware = <&firmware>; + status = "okay"; + }; + + expgpio: expgpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; + #gpio-cells = <2>; + firmware = <&firmware>; + status = "okay"; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + + spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; + + spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + clock-frequency = <100000>; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <100000>; +}; + +&i2c2 { + clock-frequency = <100000>; +}; + +&i2s { + pinctrl-names = "default"; + pinctrl-0 = <&i2s_pins>; +}; + +&leds { + act_led: act { + label = "led0"; + linux,default-trigger = "mmc0"; + gpios = <&virtgpio 0 0>; + }; +}; + +&hdmi { + hpd-gpios = <&expgpio 0 GPIO_ACTIVE_LOW>; +}; + +&audio { + pinctrl-names = "default"; + pinctrl-0 = <&audio_pins>; +}; + +/ { + __overrides__ { + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm2835-rpi.dtsi linux-vendor/arch/arm/boot/dts/bcm2835-rpi.dtsi --- linux-4.18.16/arch/arm/boot/dts/bcm2835-rpi.dtsi 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/boot/dts/bcm2835-rpi.dtsi 2018-10-29 19:31:20.491785595 +0100 @@ -32,7 +32,7 @@ mailbox@7e00b840 { compatible = "brcm,bcm2835-vchiq"; - reg = <0x7e00b840 0xf>; + reg = <0x7e00b840 0x3c>; interrupts = <0 2>; }; }; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/bcm283x-rpi-lan7515.dtsi linux-vendor/arch/arm/boot/dts/bcm283x-rpi-lan7515.dtsi --- linux-4.18.16/arch/arm/boot/dts/bcm283x-rpi-lan7515.dtsi 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/boot/dts/bcm283x-rpi-lan7515.dtsi 2018-10-29 19:31:20.491785595 +0100 @@ -21,7 +21,24 @@ ethernet: ethernet@1 { compatible = "usb424,7800"; reg = <1>; + microchip,eee-enabled; + microchip,tx-lpi-timer = <600>; /* non-aggressive*/ + /* + * led0 = 1:link1000/activity + * led1 = 6:link10/100/activity + */ + microchip,led-modes = <1 6>; }; }; }; }; + + +/ { + __overrides__ { + eee = <ðernet>,"microchip,eee-enabled?"; + tx_lpi_timer = <ðernet>,"microchip,tx-lpi-timer:0"; + eth_led0 = <ðernet>,"microchip,led-modes:0"; + eth_led1 = <ðernet>,"microchip,led-modes:4"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/Makefile linux-vendor/arch/arm/boot/dts/Makefile --- linux-4.18.16/arch/arm/boot/dts/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/boot/dts/Makefile 2018-10-29 19:31:20.444787941 +0100 @@ -1,4 +1,15 @@ # SPDX-License-Identifier: GPL-2.0 + +dtb-$(CONFIG_ARCH_BCM2835) += \ + bcm2708-rpi-b.dtb \ + bcm2708-rpi-b-plus.dtb \ + bcm2708-rpi-cm.dtb \ + bcm2708-rpi-0-w.dtb \ + bcm2709-rpi-2-b.dtb \ + bcm2710-rpi-3-b.dtb \ + bcm2710-rpi-3-b-plus.dtb \ + bcm2710-rpi-cm3.dtb + dtb-$(CONFIG_ARCH_ALPINE) += \ alpine-db.dtb dtb-$(CONFIG_MACH_ARTPEC6) += \ @@ -1184,3 +1195,13 @@ aspeed-bmc-opp-zaius.dtb \ aspeed-bmc-portwell-neptune.dtb \ aspeed-bmc-quanta-q71l.dtb + +targets += dtbs dtbs_install +targets += $(dtb-y) + +subdir-y := overlays + +# Enable fixups to support overlays on BCM2835 platforms +ifeq ($(CONFIG_ARCH_BCM2835),y) + DTC_FLAGS ?= -@ +endif diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/adau1977-adc-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/adau1977-adc-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/adau1977-adc-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/adau1977-adc-overlay.dts 2018-10-29 19:31:20.519784199 +0100 @@ -0,0 +1,40 @@ +// Definitions for ADAU1977 ADC +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2c>; + + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + adau1977: codec@11 { + compatible = "adi,adau1977"; + reg = <0x11>; + reset-gpios = <&gpio 5 0>; + AVDD-supply = <&vdd_3v3_reg>; + }; + }; + }; + + fragment@1 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "adi,adau1977-adc"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/adau7002-simple-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/adau7002-simple-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/adau7002-simple-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/adau7002-simple-overlay.dts 2018-10-29 19:31:20.519784199 +0100 @@ -0,0 +1,52 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target-path = "/"; + __overlay__ { + adau7002_codec: adau7002-codec { + #sound-dai-cells = <0>; + compatible = "adi,adau7002"; +/* IOVDD-supply = <&supply>;*/ + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + sound_overlay: __overlay__ { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "adau7002"; + simple-audio-card,bitclock-slave = <&dailink0_slave>; + simple-audio-card,frame-slave = <&dailink0_slave>; + simple-audio-card,widgets = + "Microphone", "Microphone Jack"; + simple-audio-card,routing = + "PDM_DAT", "Microphone Jack"; + status = "okay"; + simple-audio-card,cpu { + sound-dai = <&i2s>; + }; + dailink0_slave: simple-audio-card,codec { + sound-dai = <&adau7002_codec>; + }; + }; + }; + + + __overrides__ { + card-name = <&sound_overlay>,"simple-audio-card,name"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/ads1015-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/ads1015-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/ads1015-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/ads1015-overlay.dts 2018-10-29 19:31:20.519784199 +0100 @@ -0,0 +1,98 @@ +/* + * 2016 - Erik Sejr + */ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + /* ----------- ADS1015 ------------ */ + fragment@0 { + target = <&i2c_arm>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + ads1015: ads1015 { + compatible = "ti,ads1015"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x48>; + }; + }; + }; + + fragment@1 { + target-path = "i2c_arm/ads1015"; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + channel_a: channel_a { + reg = <4>; + ti,gain = <2>; + ti,datarate = <4>; + }; + }; + }; + + fragment@2 { + target-path = "i2c_arm/ads1015"; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + channel_b: channel_b { + reg = <5>; + ti,gain = <2>; + ti,datarate = <4>; + }; + }; + }; + + fragment@3 { + target-path = "i2c_arm/ads1015"; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + channel_c: channel_c { + reg = <6>; + ti,gain = <2>; + ti,datarate = <4>; + }; + }; + }; + + fragment@4 { + target-path = "i2c_arm/ads1015"; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + channel_d: channel_d { + reg = <7>; + ti,gain = <2>; + ti,datarate = <4>; + }; + }; + }; + + __overrides__ { + addr = <&ads1015>,"reg:0"; + cha_enable = <0>,"=1"; + cha_cfg = <&channel_a>,"reg:0"; + cha_gain = <&channel_a>,"ti,gain:0"; + cha_datarate = <&channel_a>,"ti,datarate:0"; + chb_enable = <0>,"=2"; + chb_cfg = <&channel_b>,"reg:0"; + chb_gain = <&channel_b>,"ti,gain:0"; + chb_datarate = <&channel_b>,"ti,datarate:0"; + chc_enable = <0>,"=3"; + chc_cfg = <&channel_c>,"reg:0"; + chc_gain = <&channel_c>,"ti,gain:0"; + chc_datarate = <&channel_c>,"ti,datarate:0"; + chd_enable = <0>,"=4"; + chd_cfg = <&channel_d>,"reg:0"; + chd_gain = <&channel_d>,"ti,gain:0"; + chd_datarate = <&channel_d>,"ti,datarate:0"; + }; + +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/ads1115-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/ads1115-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/ads1115-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/ads1115-overlay.dts 2018-10-29 19:31:20.519784199 +0100 @@ -0,0 +1,103 @@ +/* + * TI ADS1115 multi-channel ADC overlay + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2c_arm>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ads1115: ads1115 { + compatible = "ti,ads1115"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x48>; + }; + }; + }; + + fragment@1 { + target-path = "i2c_arm/ads1115"; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + channel_a: channel_a { + reg = <4>; + ti,gain = <1>; + ti,datarate = <7>; + }; + }; + }; + + fragment@2 { + target-path = "i2c_arm/ads1115"; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + channel_b: channel_b { + reg = <5>; + ti,gain = <1>; + ti,datarate = <7>; + }; + }; + }; + + fragment@3 { + target-path = "i2c_arm/ads1115"; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + channel_c: channel_c { + reg = <6>; + ti,gain = <1>; + ti,datarate = <7>; + }; + }; + }; + + fragment@4 { + target-path = "i2c_arm/ads1115"; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + channel_d: channel_d { + reg = <7>; + ti,gain = <1>; + ti,datarate = <7>; + }; + }; + }; + + __overrides__ { + addr = <&ads1115>,"reg:0"; + cha_enable = <0>,"=1"; + cha_cfg = <&channel_a>,"reg:0"; + cha_gain = <&channel_a>,"ti,gain:0"; + cha_datarate = <&channel_a>,"ti,datarate:0"; + chb_enable = <0>,"=2"; + chb_cfg = <&channel_b>,"reg:0"; + chb_gain = <&channel_b>,"ti,gain:0"; + chb_datarate = <&channel_b>,"ti,datarate:0"; + chc_enable = <0>,"=3"; + chc_cfg = <&channel_c>,"reg:0"; + chc_gain = <&channel_c>,"ti,gain:0"; + chc_datarate = <&channel_c>,"ti,datarate:0"; + chd_enable = <0>,"=4"; + chd_cfg = <&channel_d>,"reg:0"; + chd_gain = <&channel_d>,"ti,gain:0"; + chd_datarate = <&channel_d>,"ti,datarate:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/ads7846-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/ads7846-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/ads7846-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/ads7846-overlay.dts 2018-10-29 19:31:20.519784199 +0100 @@ -0,0 +1,89 @@ +/* + * Generic Device Tree overlay for the ADS7846 touch controller + * + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&spidev1>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@3 { + target = <&gpio>; + __overlay__ { + ads7846_pins: ads7846_pins { + brcm,pins = <255>; /* illegal default value */ + brcm,function = <0>; /* in */ + brcm,pull = <0>; /* none */ + }; + }; + }; + + fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + ads7846: ads7846@1 { + compatible = "ti,ads7846"; + reg = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&ads7846_pins>; + + spi-max-frequency = <2000000>; + interrupts = <255 2>; /* high-to-low edge triggered */ + interrupt-parent = <&gpio>; + pendown-gpio = <&gpio 255 0>; + + /* driver defaults */ + ti,x-min = /bits/ 16 <0>; + ti,y-min = /bits/ 16 <0>; + ti,x-max = /bits/ 16 <0x0FFF>; + ti,y-max = /bits/ 16 <0x0FFF>; + ti,pressure-min = /bits/ 16 <0>; + ti,pressure-max = /bits/ 16 <0xFFFF>; + ti,x-plate-ohms = /bits/ 16 <400>; + }; + }; + }; + __overrides__ { + cs = <&ads7846>,"reg:0"; + speed = <&ads7846>,"spi-max-frequency:0"; + penirq = <&ads7846_pins>,"brcm,pins:0", /* REQUIRED */ + <&ads7846>,"interrupts:0", + <&ads7846>,"pendown-gpio:4"; + penirq_pull = <&ads7846_pins>,"brcm,pull:0"; + swapxy = <&ads7846>,"ti,swap-xy?"; + xmin = <&ads7846>,"ti,x-min;0"; + ymin = <&ads7846>,"ti,y-min;0"; + xmax = <&ads7846>,"ti,x-max;0"; + ymax = <&ads7846>,"ti,y-max;0"; + pmin = <&ads7846>,"ti,pressure-min;0"; + pmax = <&ads7846>,"ti,pressure-max;0"; + xohms = <&ads7846>,"ti,x-plate-ohms;0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts 2018-10-29 19:31:20.520784149 +0100 @@ -0,0 +1,49 @@ +// Definitions for Digital Dreamtime Akkordion using IQaudIO DAC+ or DACZero +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcm5122@4c { + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4c>; + AVDD-supply = <&vdd_3v3_reg>; + DVDD-supply = <&vdd_3v3_reg>; + CPVDD-supply = <&vdd_3v3_reg>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + frag2: __overlay__ { + compatible = "iqaudio,iqaudio-dac"; + card_name = "Akkordion"; + dai_name = "IQaudIO DAC"; + dai_stream_name = "IQaudIO DAC HiFi"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + + __overrides__ { + 24db_digital_gain = <&frag2>,"iqaudio,24db_digital_gain?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/allo-boss-dac-pcm512x-audio-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/allo-boss-dac-pcm512x-audio-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/allo-boss-dac-pcm512x-audio-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/allo-boss-dac-pcm512x-audio-overlay.dts 2018-10-29 19:31:20.520784149 +0100 @@ -0,0 +1,59 @@ +/* + * Definitions for Allo Boss DAC board + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/clocks"; + __overlay__ { + boss_osc: boss_osc { + compatible = "allo,dac-clk"; + #clock-cells = <0>; + }; + }; + }; + + fragment@1 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcm5122@4d { + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + clocks = <&boss_osc>; + reg = <0x4d>; + status = "okay"; + }; + }; + }; + + fragment@3 { + target = <&sound>; + boss_dac: __overlay__ { + compatible = "allo,boss-dac"; + i2s-controller = <&i2s>; + mute-gpios = <&gpio 6 1>; + status = "okay"; + }; + }; + + __overrides__ { + 24db_digital_gain = <&boss_dac>,"allo,24db_digital_gain?"; + slave = <&boss_dac>,"allo,slave?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/allo-digione-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/allo-digione-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/allo-digione-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/allo-digione-overlay.dts 2018-10-29 19:31:20.521784099 +0100 @@ -0,0 +1,44 @@ +// Definitions for Allo DigiOne +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + wm8804@3b { + #sound-dai-cells = <0>; + compatible = "wlf,wm8804"; + reg = <0x3b>; + PVDD-supply = <&vdd_3v3_reg>; + DVDD-supply = <&vdd_3v3_reg>; + status = "okay"; + wlf,reset-gpio = <&gpio 17 0>; + }; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "allo,allo-digione"; + i2s-controller = <&i2s>; + status = "okay"; + clock44-gpio = <&gpio 5 0>; + clock48-gpio = <&gpio 6 0>; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/allo-katana-dac-audio-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/allo-katana-dac-audio-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/allo-katana-dac-audio-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/allo-katana-dac-audio-overlay.dts 2018-10-29 19:31:20.521784099 +0100 @@ -0,0 +1,57 @@ +/* + * Definitions for Allo Katana DAC boards + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + #sound-dai-cells = <0>; + status = "okay"; + cpu_port: port { + cpu_endpoint: endpoint { + remote-endpoint = <&codec_endpoint>; + bitclock-master = <&codec_endpoint>; + frame-master = <&codec_endpoint>; + dai-format = "i2s"; + }; + }; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + allo-katana-codec@30 { + #sound-dai-cells = <0>; + compatible = "allo,allo-katana-codec"; + reg = <0x30>; + port { + codec_endpoint: endpoint { + remote-endpoint = <&cpu_endpoint>; + }; + }; + }; + }; + }; + + fragment@2 { + target = <&sound>; + katana_dac: __overlay__ { + compatible = "audio-graph-card"; + label = "Allo Katana"; + dais = <&cpu_port>; + status = "okay"; + }; + }; +}; + diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/allo-piano-dac-pcm512x-audio-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/allo-piano-dac-pcm512x-audio-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/allo-piano-dac-pcm512x-audio-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/allo-piano-dac-pcm512x-audio-overlay.dts 2018-10-29 19:31:20.521784099 +0100 @@ -0,0 +1,54 @@ +/* + * Definitions for Allo Piano DAC (2.0/2.1) boards + * + * NB. The Piano DAC 2.1 board contains 2x TI PCM5142 DAC's. One DAC is stereo + * (left/right) and the other provides a subwoofer output, using DSP on the + * chip for digital high/low pass crossover. + * The initial support for this hardware, that doesn't require any codec driver + * modifications, uses only one DAC chip for stereo (left/right) output, the + * chip with 0x4c slave address. The other chip at 0x4d is currently ignored! + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcm5142@4c { + #sound-dai-cells = <0>; + compatible = "ti,pcm5142"; + reg = <0x4c>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + piano_dac: __overlay__ { + compatible = "allo,piano-dac"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + + __overrides__ { + 24db_digital_gain = + <&piano_dac>,"allo,24db_digital_gain?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts 2018-10-29 19:31:20.521784099 +0100 @@ -0,0 +1,55 @@ +// Definitions for Piano DAC +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + allo_pcm5122_4c: pcm5122@4c { + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4c>; + status = "okay"; + }; + allo_pcm5122_4d: pcm5122@4d { + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4d>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + piano_dac: __overlay__ { + compatible = "allo,piano-dac-plus"; + audio-codec = <&allo_pcm5122_4c &allo_pcm5122_4d>; + i2s-controller = <&i2s>; + mute1-gpios = <&gpio 6 1>; + mute2-gpios = <&gpio 25 1>; + status = "okay"; + }; + }; + + __overrides__ { + 24db_digital_gain = + <&piano_dac>,"allo,24db_digital_gain?"; + glb_mclk = + <&piano_dac>,"allo,glb_mclk?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/applepi-dac-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/applepi-dac-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/applepi-dac-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/applepi-dac-overlay.dts 2018-10-29 19:31:20.521784099 +0100 @@ -0,0 +1,57 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&sound>; + __overlay__ { + compatible = "simple-audio-card"; + simple-audio-card,name = "ApplePi-DAC"; + + status = "okay"; + + playback_link: simple-audio-card,dai-link@1 { + format = "i2s"; + + p_cpu_dai: cpu { + sound-dai = <&i2s>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + }; + + p_codec_dai: codec { + sound-dai = <&codec_out>; + }; + }; + }; + }; + + fragment@1 { + target-path = "/"; + __overlay__ { + codec_out: pcm1794a-codec { + #sound-dai-cells = <0>; + compatible = "ti,pcm1794a"; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&i2s>; + __overlay__ { + #sound-dai-cells = <0>; + status = "okay"; + }; + }; +}; + +/* + Written by: Leonid Ayzenshtat + Company: Orchard Audio (www.orchardaudio.com) + + compile with: + dtc -@ -H epapr -O dtb -o ApplePi-DAC.dtbo -W no-unit_address_vs_reg ApplePi-DAC.dts +*/ diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/at86rf233-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/at86rf233-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/at86rf233-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/at86rf233-overlay.dts 2018-10-29 19:31:20.521784099 +0100 @@ -0,0 +1,57 @@ +/dts-v1/; +/plugin/; + +/* Overlay for Atmel AT86RF233 IEEE 802.15.4 WPAN transceiver on spi0.0 */ + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + lowpan0: at86rf233@0 { + compatible = "atmel,at86rf233"; + reg = <0>; + interrupt-parent = <&gpio>; + interrupts = <23 4>; /* active high */ + reset-gpio = <&gpio 24 1>; + sleep-gpio = <&gpio 25 1>; + spi-max-frequency = <3000000>; + xtal-trim = /bits/ 8 <0xf>; + }; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&gpio>; + __overlay__ { + lowpan0_pins: lowpan0_pins { + brcm,pins = <23 24 25>; + brcm,function = <0 1 1>; /* in out out */ + }; + }; + }; + + __overrides__ { + interrupt = <&lowpan0>, "interrupts:0", + <&lowpan0_pins>, "brcm,pins:0"; + reset = <&lowpan0>, "reset-gpio:4", + <&lowpan0_pins>, "brcm,pins:4"; + sleep = <&lowpan0>, "sleep-gpio:4", + <&lowpan0_pins>, "brcm,pins:8"; + speed = <&lowpan0>, "spi-max-frequency:0"; + trim = <&lowpan0>, "xtal-trim.0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts 2018-10-29 19:31:20.521784099 +0100 @@ -0,0 +1,59 @@ +// Definitions for audioinjector.net audio add on soundcard +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + cs42448: cs42448@48 { + #sound-dai-cells = <0>; + compatible = "cirrus,cs42448"; + reg = <0x48>; + clocks = <&cs42448_mclk>; + clock-names = "mclk"; + VA-supply = <&vdd_5v0_reg>; + VD-supply = <&vdd_3v3_reg>; + VLS-supply = <&vdd_3v3_reg>; + VLC-supply = <&vdd_3v3_reg>; + status = "okay"; + }; + + cs42448_mclk: codec-mclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <49152000>; + }; + }; + }; + + fragment@2 { + target = <&sound>; + snd: __overlay__ { + compatible = "ai,audioinjector-octo-soundcard"; + mult-gpios = <&gpio 27 0>, <&gpio 22 0>, <&gpio 23 0>, + <&gpio 24 0>; + reset-gpios = <&gpio 5 0>; + i2s-controller = <&i2s>; + codec = <&cs42448>; + status = "okay"; + }; + }; + + __overrides__ { + non-stop-clocks = <&snd>, "non-stop-clocks?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/audioinjector-wm8731-audio-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/audioinjector-wm8731-audio-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/audioinjector-wm8731-audio-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/audioinjector-wm8731-audio-overlay.dts 2018-10-29 19:31:20.522784049 +0100 @@ -0,0 +1,39 @@ +// Definitions for audioinjector.net audio add on soundcard +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + wm8731@1a { + #sound-dai-cells = <0>; + compatible = "wlf,wm8731"; + reg = <0x1a>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "ai,audioinjector-pi-soundcard"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/audremap-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/audremap-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/audremap-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/audremap-overlay.dts 2018-10-29 19:31:20.522784049 +0100 @@ -0,0 +1,19 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&audio_pins>; + frag0: __overlay__ { + brcm,pins = < 12 13 >; + brcm,function = < 4 >; /* alt0 alt0 */ + }; + }; + + __overrides__ { + swap_lr = <&frag0>, "swap_lr?"; + enable_jack = <&frag0>, "enable_jack?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/balena-fin-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/balena-fin-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/balena-fin-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/balena-fin-overlay.dts 2018-10-29 19:31:20.522784049 +0100 @@ -0,0 +1,79 @@ +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&mmc>; + sdio_wifi: __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&sdio_pins>; + bus-width = <4>; + brcm,overclock-50 = <35>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + sdio_pins: sdio_pins { + brcm,pins = <34 35 36 37 38 39>; + brcm,function = <7>; /* ALT3 = SD1 */ + brcm,pull = <0 2 2 2 2 2>; + }; + + power_ctrl_pins: power_ctrl_pins { + brcm,pins = <40>; + brcm,function = <1>; // out + }; + }; + }; + + fragment@2 { + target-path = "/"; + __overlay__ { + // We should investigate how to switch to mmc-pwrseq-sd8787 + // Currently that module requires two GPIOs to function since it + // targets a slightly different chip + power_ctrl: power_ctrl { + compatible = "gpio-poweroff"; + gpios = <&gpio 40 1>; + force; + }; + + i2c_soft: i2c@0 { + compatible = "i2c-gpio"; + gpios = <&gpio 43 0 /* sda */ &gpio 42 0 /* scl */>; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; + + fragment@3 { + target = <&i2c_soft>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + gpio_expander: gpio_expander@20 { + compatible = "nxp,pca9554"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x20>; + status = "okay"; + }; + + // rtc clock + ds1307: ds1307@68 { + compatible = "maxim,ds1307"; + reg = <0x68>; + status = "okay"; + }; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts 2018-10-29 19:31:20.522784049 +0100 @@ -0,0 +1,23 @@ +// Definitions for BMP085/BMP180 digital barometric pressure and temperature sensors from Bosch Sensortec +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2c_arm>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + bmp085@77 { + compatible = "bosch,bmp085"; + reg = <0x77>; + default-oversampling = <3>; + status = "okay"; + }; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/dht11-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/dht11-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/dht11-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/dht11-overlay.dts 2018-10-29 19:31:20.522784049 +0100 @@ -0,0 +1,39 @@ +/* + * Overlay for the DHT11/21/22 humidity/temperature sensor modules. + */ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/"; + __overlay__ { + + dht11: dht11@0 { + compatible = "dht11"; + pinctrl-names = "default"; + pinctrl-0 = <&dht11_pins>; + gpios = <&gpio 4 0>; + status = "okay"; + }; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + dht11_pins: dht11_pins { + brcm,pins = <4>; + brcm,function = <0>; // in + brcm,pull = <0>; // off + }; + }; + }; + + __overrides__ { + gpiopin = <&dht11_pins>,"brcm,pins:0", + <&dht11>,"gpios:4"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/dionaudio-loco-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/dionaudio-loco-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/dionaudio-loco-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/dionaudio-loco-overlay.dts 2018-10-29 19:31:20.522784049 +0100 @@ -0,0 +1,39 @@ +// Definitions for Dion Audio LOCO DAC-AMP + +/* + * PCM5242 DAC (in hardware mode) and TPA3118 AMP. + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target-path = "/"; + __overlay__ { + pcm5102a-codec { + #sound-dai-cells = <0>; + compatible = "ti,pcm5102a"; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "dionaudio,loco-pcm5242-tpa3118"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts 2018-10-29 19:31:20.522784049 +0100 @@ -0,0 +1,49 @@ +/* + * Definitions for Dion Audio LOCO-V2 DAC-AMP + * eg. dtoverlay=dionaudio-loco-v2 + * + * PCM5242 DAC (in software mode) and TPA3255 AMP. + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&sound>; + frag0: __overlay__ { + compatible = "dionaudio,dionaudio-loco-v2"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcm5122@4c { + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4d>; + status = "okay"; + }; + }; + }; + + __overrides__ { + 24db_digital_gain = <&frag0>,"dionaudio,24db_digital_gain?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/dpi18-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/dpi18-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/dpi18-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/dpi18-overlay.dts 2018-10-29 19:31:20.522784049 +0100 @@ -0,0 +1,31 @@ +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + // There is no DPI driver module, but we need a platform device + // node (that doesn't already use pinctrl) to hang the pinctrl + // reference on - leds will do + + fragment@0 { + target = <&leds>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&dpi18_pins>; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + dpi18_pins: dpi18_pins { + brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 + 12 13 14 15 16 17 18 19 20 + 21>; + brcm,function = <6>; /* alt2 */ + brcm,pull = <0>; /* no pull */ + }; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/dpi24-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/dpi24-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/dpi24-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/dpi24-overlay.dts 2018-10-29 19:31:20.522784049 +0100 @@ -0,0 +1,31 @@ +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + // There is no DPI driver module, but we need a platform device + // node (that doesn't already use pinctrl) to hang the pinctrl + // reference on - leds will do + + fragment@0 { + target = <&leds>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&dpi24_pins>; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + dpi24_pins: dpi24_pins { + brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 + 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27>; + brcm,function = <6>; /* alt2 */ + brcm,pull = <0>; /* no pull */ + }; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/dwc2-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/dwc2-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/dwc2-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/dwc2-overlay.dts 2018-10-29 19:31:20.523783999 +0100 @@ -0,0 +1,28 @@ +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&usb>; + #address-cells = <1>; + #size-cells = <1>; + dwc2_usb: __overlay__ { + compatible = "brcm,bcm2835-usb"; + reg = <0x7e980000 0x10000>; + interrupts = <1 9>; + dr_mode = "otg"; + g-np-tx-fifo-size = <32>; + g-rx-fifo-size = <256>; + g-tx-fifo-size = <512 512 512 512 512 256 256>; + status = "okay"; + }; + }; + + __overrides__ { + dr_mode = <&dwc2_usb>, "dr_mode"; + g-np-tx-fifo-size = <&dwc2_usb>,"g-np-tx-fifo-size:0"; + g-rx-fifo-size = <&dwc2_usb>,"g-rx-fifo-size:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts 2018-10-29 19:31:20.523783999 +0100 @@ -0,0 +1,20 @@ +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&usb>; + #address-cells = <1>; + #size-cells = <1>; + __overlay__ { + compatible = "brcm,bcm2708-usb"; + reg = <0x7e980000 0x10000>, + <0x7e006000 0x1000>; + interrupts = <2 0>, + <1 9>; + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/enc28j60-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/enc28j60-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/enc28j60-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/enc28j60-overlay.dts 2018-10-29 19:31:20.523783999 +0100 @@ -0,0 +1,53 @@ +// Overlay for the Microchip ENC28J60 Ethernet Controller +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + eth1: enc28j60@0{ + compatible = "microchip,enc28j60"; + reg = <0>; /* CE0 */ + pinctrl-names = "default"; + pinctrl-0 = <ð1_pins>; + interrupt-parent = <&gpio>; + interrupts = <25 0x2>; /* falling edge */ + spi-max-frequency = <12000000>; + status = "okay"; + }; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&gpio>; + __overlay__ { + eth1_pins: eth1_pins { + brcm,pins = <25>; + brcm,function = <0>; /* in */ + brcm,pull = <0>; /* none */ + }; + }; + }; + + __overrides__ { + int_pin = <ð1>, "interrupts:0", + <ð1_pins>, "brcm,pins:0"; + speed = <ð1>, "spi-max-frequency:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/enc28j60-spi2-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/enc28j60-spi2-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/enc28j60-spi2-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/enc28j60-spi2-overlay.dts 2018-10-29 19:31:20.523783999 +0100 @@ -0,0 +1,47 @@ +// Overlay for the Microchip ENC28J60 Ethernet Controller - SPI2 Compute Module +// Interrupt pin: 39 +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&spi2>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + eth1: enc28j60@0{ + compatible = "microchip,enc28j60"; + reg = <0>; /* CE0 */ + pinctrl-names = "default"; + pinctrl-0 = <ð1_pins>; + interrupt-parent = <&gpio>; + interrupts = <39 0x2>; /* falling edge */ + spi-max-frequency = <12000000>; + status = "okay"; + }; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + eth1_pins: eth1_pins { + brcm,pins = <39>; + brcm,function = <0>; /* in */ + brcm,pull = <0>; /* none */ + }; + }; + }; + + __overrides__ { + int_pin = <ð1>, "interrupts:0", + <ð1_pins>, "brcm,pins:0"; + speed = <ð1>, "spi-max-frequency:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/exc3000-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/exc3000-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/exc3000-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/exc3000-overlay.dts 2018-10-29 19:31:20.523783999 +0100 @@ -0,0 +1,48 @@ +// Device tree overlay for I2C connected EETI EXC3000 multiple touch controller +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&gpio>; + __overlay__ { + exc3000_pins: exc3000_pins { + brcm,pins = <4>; // interrupt + brcm,function = <0>; // in + brcm,pull = <2>; // pull-up + }; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + exc3000: exc3000@2a { + compatible = "eeti,exc3000"; + reg = <0x2a>; + pinctrl-names = "default"; + pinctrl-0 = <&exc3000_pins>; + interrupt-parent = <&gpio>; + interrupts = <4 8>; // active low level-sensitive + touchscreen-size-x = <4096>; + touchscreen-size-y = <4096>; + }; + }; + }; + + __overrides__ { + interrupt = <&exc3000_pins>,"brcm,pins:0", + <&exc3000>,"interrupts:0"; + sizex = <&exc3000>,"touchscreen-size-x:0"; + sizey = <&exc3000>,"touchscreen-size-y:0"; + invx = <&exc3000>,"touchscreen-inverted-x?"; + invy = <&exc3000>,"touchscreen-inverted-y?"; + swapxy = <&exc3000>,"touchscreen-swapped-x-y?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts 2018-10-29 19:31:20.523783999 +0100 @@ -0,0 +1,70 @@ +// Definitions for Fe-Pi Audio +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&clocks>; + __overlay__ { + sgtl5000_mclk: sgtl5000_mclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <12288000>; + clock-output-names = "sgtl5000-mclk"; + }; + }; + }; + + fragment@1 { + target = <&soc>; + __overlay__ { + reg_1v8: reg_1v8@0 { + compatible = "regulator-fixed"; + regulator-name = "1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + }; + }; + + fragment@2 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + sgtl5000@0a { + #sound-dai-cells = <0>; + compatible = "fepi,sgtl5000"; + reg = <0x0a>; + clocks = <&sgtl5000_mclk>; + micbias-resistor-k-ohms = <2>; + micbias-voltage-m-volts = <3000>; + VDDA-supply = <&vdd_3v3_reg>; + VDDIO-supply = <&vdd_3v3_reg>; + VDDD-supply = <®_1v8>; + status = "okay"; + }; + }; + }; + + fragment@3 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@4 { + target = <&sound>; + __overlay__ { + compatible = "fe-pi,fe-pi-audio"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/goodix-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/goodix-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/goodix-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/goodix-overlay.dts 2018-10-29 19:31:20.523783999 +0100 @@ -0,0 +1,46 @@ +// Device tree overlay for I2C connected Goodix gt9271 multiple touch controller +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&gpio>; + __overlay__ { + goodix_pins: goodix_pins { + brcm,pins = <4 17>; // interrupt and reset + brcm,function = <0 0>; // in + brcm,pull = <2 2>; // pull-up + }; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + gt9271: gt9271@14 { + compatible = "goodix,gt9271"; + reg = <0x14>; + pinctrl-names = "default"; + pinctrl-0 = <&goodix_pins>; + interrupt-parent = <&gpio>; + interrupts = <4 2>; // high-to-low edge triggered + irq-gpios = <&gpio 4 0>; // Pin7 on GPIO header + reset-gpios = <&gpio 17 0>; // Pin11 on GPIO header + }; + }; + }; + + __overrides__ { + interrupt = <&goodix_pins>,"brcm,pins:0", + <>9271>,"interrupts:0", + <>9271>,"irq-gpios:4"; + reset = <&goodix_pins>,"brcm,pins:4", + <>9271>,"reset-gpios:4"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/googlevoicehat-soundcard-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/googlevoicehat-soundcard-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/googlevoicehat-soundcard-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/googlevoicehat-soundcard-overlay.dts 2018-10-29 19:31:20.523783999 +0100 @@ -0,0 +1,49 @@ +// Definitions for Google voiceHAT v1 soundcard overlay +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + googlevoicehat_pins: googlevoicehat_pins { + brcm,pins = <16>; + brcm,function = <1>; /* out */ + brcm,pull = <0>; /* up */ + }; + }; + }; + + + fragment@2 { + target-path = "/"; + __overlay__ { + voicehat-codec { + #sound-dai-cells = <0>; + compatible = "google,voicehat"; + pinctrl-names = "default"; + pinctrl-0 = <&googlevoicehat_pins>; + sdmode-gpios= <&gpio 16 0>; + status = "okay"; + }; + }; + }; + + fragment@3 { + target = <&sound>; + __overlay__ { + compatible = "googlevoicehat,googlevoicehat-soundcard"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts 2018-10-29 19:31:20.524783949 +0100 @@ -0,0 +1,48 @@ +// Definitions for ir-gpio module +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/"; + __overlay__ { + gpio_ir: ir-receiver@12 { + compatible = "gpio-ir-receiver"; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_ir_pins>; + + // pin number, high or low + gpios = <&gpio 18 1>; + + // parameter for keymap name + linux,rc-map-name = "rc-rc6-mce"; + + status = "okay"; + }; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + gpio_ir_pins: gpio_ir_pins@12 { + brcm,pins = <18>; // pin 18 + brcm,function = <0>; // in + brcm,pull = <1>; // down + }; + }; + }; + + __overrides__ { + // parameters + gpio_pin = <&gpio_ir>,"gpios:4", // pin number + <&gpio_ir>,"reg:0", + <&gpio_ir_pins>,"brcm,pins:0", + <&gpio_ir_pins>,"reg:0"; + gpio_pull = <&gpio_ir_pins>,"brcm,pull:0"; // pull-up/down state + + rc-map-name = <&gpio_ir>,"linux,rc-map-name"; // default rc map + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/gpio-ir-tx-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/gpio-ir-tx-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/gpio-ir-tx-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/gpio-ir-tx-overlay.dts 2018-10-29 19:31:20.524783949 +0100 @@ -0,0 +1,36 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&gpio>; + __overlay__ { + gpio_ir_tx_pins: gpio_ir_tx_pins@12 { + brcm,pins = <18>; + brcm,function = <1>; // out + }; + }; + }; + + fragment@1 { + target-path = "/"; + __overlay__ { + gpio_ir_tx: gpio-ir-transmitter@12 { + compatible = "gpio-ir-tx"; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_ir_tx_pins>; + gpios = <&gpio 18 0>; + }; + }; + }; + + __overrides__ { + gpio_pin = <&gpio_ir_tx>, "gpios:4", // pin number + <&gpio_ir_tx>, "reg:0", + <&gpio_ir_tx_pins>, "brcm,pins:0", + <&gpio_ir_tx_pins>, "reg:0"; + invert = <&gpio_ir_tx>, "gpios:8"; // 1 = active low + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/gpio-key-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/gpio-key-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/gpio-key-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/gpio-key-overlay.dts 2018-10-29 19:31:20.524783949 +0100 @@ -0,0 +1,48 @@ +// Definitions for gpio-key module +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + // Configure the gpio pin controller + target = <&gpio>; + __overlay__ { + pin_state: button_pins@0 { + brcm,pins = <3>; // gpio number + brcm,function = <0>; // 0 = input, 1 = output + brcm,pull = <2>; // 0 = none, 1 = pull down, 2 = pull up + }; + }; + }; + fragment@1 { + target-path = "/"; + __overlay__ { + button: button@0 { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pin_state>; + status = "okay"; + + key: key { + linux,code = <116>; + gpios = <&gpio 3 1>; + label = "KEY_POWER"; + }; + }; + }; + }; + + __overrides__ { + gpio = <&key>,"gpios:4", + <&button>,"reg:0", + <&pin_state>,"brcm,pins:0", + <&pin_state>,"reg:0"; + label = <&key>,"label"; + keycode = <&key>,"linux,code:0"; + gpio_pull = <&pin_state>,"brcm,pull:0"; + active_low = <&key>,"gpios:8"; + }; + +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/gpio-no-irq-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/gpio-no-irq-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/gpio-no-irq-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/gpio-no-irq-overlay.dts 2018-10-29 19:31:20.524783949 +0100 @@ -0,0 +1,14 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835"; + + fragment@0 { + // Configure the gpio pin controller + target = <&gpio>; + __overlay__ { + interrupts; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts 2018-10-29 19:31:20.524783949 +0100 @@ -0,0 +1,36 @@ +// Definitions for gpio-poweroff module +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/"; + __overlay__ { + power_ctrl: power_ctrl { + compatible = "gpio-poweroff"; + gpios = <&gpio 26 0>; + force; + }; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + power_ctrl_pins: power_ctrl_pins { + brcm,pins = <26>; + brcm,function = <1>; // out + }; + }; + }; + + __overrides__ { + gpiopin = <&power_ctrl>,"gpios:4", + <&power_ctrl_pins>,"brcm,pins:0"; + active_low = <&power_ctrl>,"gpios:8"; + input = <&power_ctrl>,"input?"; + export = <&power_ctrl>,"export?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts 2018-10-29 19:31:20.524783949 +0100 @@ -0,0 +1,80 @@ +// Definitions for gpio-poweroff module +/dts-v1/; +/plugin/; + +// This overlay sets up an input device that generates KEY_POWER events +// when a given GPIO pin changes. It defaults to using GPIO3, which can +// also be used to wake up (start) the Rpi again after shutdown. Since +// wakeup is active-low, this defaults to active-low with a pullup +// enabled, but all of this can be changed using overlay parameters (but +// note that GPIO3 has an external pullup on at least some boards). + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + // Configure the gpio pin controller + target = <&gpio>; + __overlay__ { + // Define a pinctrl state, that sets up the gpio + // as an input with a pullup enabled. This does + // not take effect by itself, only when referenced + // by a "pinctrl client", as is done below. See: + // https://www.kernel.org/doc/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt + // https://www.kernel.org/doc/Documentation/devicetree/bindings/pinctrl/brcm,bcm2835-gpio.txt + pin_state: shutdown_button_pins { + brcm,pins = <3>; // gpio number + brcm,function = <0>; // 0 = input, 1 = output + brcm,pull = <2>; // 0 = none, 1 = pull down, 2 = pull up + }; + }; + }; + fragment@1 { + // Add a new device to the /soc devicetree node + target-path = "/soc"; + __overlay__ { + shutdown_button { + // Let the gpio-keys driver handle this device. See: + // https://www.kernel.org/doc/Documentation/devicetree/bindings/input/gpio-keys.txt + compatible = "gpio-keys"; + + // Declare a single pinctrl state (referencing the one declared above) and name it + // default, so it is activated automatically. + pinctrl-names = "default"; + pinctrl-0 = <&pin_state>; + + // Enable this device + status = "okay"; + + // Define a single key, called "shutdown" that monitors the gpio and sends KEY_POWER + // (keycode 116, see + // https://github.com/torvalds/linux/blob/v4.12/include/uapi/linux/input-event-codes.h#L190) + button: shutdown { + label = "shutdown"; + linux,code = <116>; // KEY_POWER + gpios = <&gpio 3 1>; + }; + }; + }; + }; + + // This defines parameters that can be specified when loading + // the overlay. Each foo = line specifies one parameter, named + // foo. The rest of the specification gives properties where the + // parameter value is inserted into (changing the values above + // or adding new ones). + __overrides__ { + // Allow overriding the GPIO number. + gpio_pin = <&button>,"gpios:4", + <&pin_state>,"brcm,pins:0"; + + // Allow changing the internal pullup/down state. 0 = none, 1 = pulldown, 2 = pullup + // Note that GPIO3 and GPIO2 are the I2c pins and have an external pullup (at least + // on some boards). + gpio_pull = <&pin_state>,"brcm,pull:0"; + + // Allow setting the active_low flag. 0 = active high, 1 = active low + active_low = <&button>,"gpios:8"; + }; + +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts 2018-10-29 19:31:20.524783949 +0100 @@ -0,0 +1,39 @@ +// Definitions for HiFiBerry Amp/Amp+ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + tas5713@1b { + #sound-dai-cells = <0>; + compatible = "ti,tas5713"; + reg = <0x1b>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "hifiberry,hifiberry-amp"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts 2018-10-29 19:31:20.524783949 +0100 @@ -0,0 +1,34 @@ +// Definitions for HiFiBerry DAC +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target-path = "/"; + __overlay__ { + pcm5102a-codec { + #sound-dai-cells = <0>; + compatible = "ti,pcm5102a"; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "hifiberry,hifiberry-dac"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts 2018-10-29 19:31:20.525783899 +0100 @@ -0,0 +1,71 @@ +// Definitions for HiFiBerry DAC+ADC +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/clocks"; + __overlay__ { + dacpro_osc: dacpro_osc { + compatible = "hifiberry,dacpro-clk"; + #clock-cells = <0>; + }; + }; + }; + + fragment@1 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcm_codec: pcm5122@4d { + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4d>; + clocks = <&dacpro_osc>; + AVDD-supply = <&vdd_3v3_reg>; + DVDD-supply = <&vdd_3v3_reg>; + CPVDD-supply = <&vdd_3v3_reg>; + status = "okay"; + }; + }; + }; + + fragment@3 { + target-path = "/"; + __overlay__ { + dmic { + #sound-dai-cells = <0>; + compatible = "dmic-codec"; + num-channels = <2>; + status = "okay"; + }; + }; + }; + + fragment@4 { + target = <&sound>; + hifiberry_dacplusadc: __overlay__ { + compatible = "hifiberry,hifiberry-dacplusadc"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + + __overrides__ { + 24db_digital_gain = + <&hifiberry_dacplusadc>,"hifiberry,24db_digital_gain?"; + slave = <&hifiberry_dacplusadc>,"hifiberry-dacplusadc,slave?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts 2018-10-29 19:31:20.525783899 +0100 @@ -0,0 +1,59 @@ +// Definitions for HiFiBerry DAC+ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/clocks"; + __overlay__ { + dacpro_osc: dacpro_osc { + compatible = "hifiberry,dacpro-clk"; + #clock-cells = <0>; + }; + }; + }; + + fragment@1 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcm5122@4d { + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4d>; + clocks = <&dacpro_osc>; + AVDD-supply = <&vdd_3v3_reg>; + DVDD-supply = <&vdd_3v3_reg>; + CPVDD-supply = <&vdd_3v3_reg>; + status = "okay"; + }; + }; + }; + + fragment@3 { + target = <&sound>; + hifiberry_dacplus: __overlay__ { + compatible = "hifiberry,hifiberry-dacplus"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + + __overrides__ { + 24db_digital_gain = + <&hifiberry_dacplus>,"hifiberry,24db_digital_gain?"; + slave = <&hifiberry_dacplus>,"hifiberry-dacplus,slave?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts 2018-10-29 19:31:20.525783899 +0100 @@ -0,0 +1,41 @@ +// Definitions for HiFiBerry Digi +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + wm8804@3b { + #sound-dai-cells = <0>; + compatible = "wlf,wm8804"; + reg = <0x3b>; + PVDD-supply = <&vdd_3v3_reg>; + DVDD-supply = <&vdd_3v3_reg>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "hifiberry,hifiberry-digi"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts 2018-10-29 19:31:20.525783899 +0100 @@ -0,0 +1,43 @@ +// Definitions for HiFiBerry Digi Pro +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + wm8804@3b { + #sound-dai-cells = <0>; + compatible = "wlf,wm8804"; + reg = <0x3b>; + PVDD-supply = <&vdd_3v3_reg>; + DVDD-supply = <&vdd_3v3_reg>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "hifiberry,hifiberry-digi"; + i2s-controller = <&i2s>; + status = "okay"; + clock44-gpio = <&gpio 5 0>; + clock48-gpio = <&gpio 6 0>; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/hy28a-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/hy28a-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/hy28a-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/hy28a-overlay.dts 2018-10-29 19:31:20.525783899 +0100 @@ -0,0 +1,93 @@ +/* + * Device Tree overlay for HY28A display + * + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&spidev1>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@3 { + target = <&gpio>; + __overlay__ { + hy28a_pins: hy28a_pins { + brcm,pins = <17 25 18>; + brcm,function = <0 1 1>; /* in out out */ + }; + }; + }; + + fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + hy28a: hy28a@0{ + compatible = "ilitek,ili9320"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&hy28a_pins>; + + spi-max-frequency = <32000000>; + spi-cpol; + spi-cpha; + rotate = <270>; + bgr; + fps = <50>; + buswidth = <8>; + startbyte = <0x70>; + reset-gpios = <&gpio 25 0>; + led-gpios = <&gpio 18 1>; + debug = <0>; + }; + + hy28a_ts: hy28a-ts@1 { + compatible = "ti,ads7846"; + reg = <1>; + + spi-max-frequency = <2000000>; + interrupts = <17 2>; /* high-to-low edge triggered */ + interrupt-parent = <&gpio>; + pendown-gpio = <&gpio 17 0>; + ti,x-plate-ohms = /bits/ 16 <100>; + ti,pressure-max = /bits/ 16 <255>; + }; + }; + }; + __overrides__ { + speed = <&hy28a>,"spi-max-frequency:0"; + rotate = <&hy28a>,"rotate:0"; + fps = <&hy28a>,"fps:0"; + debug = <&hy28a>,"debug:0"; + xohms = <&hy28a_ts>,"ti,x-plate-ohms;0"; + resetgpio = <&hy28a>,"reset-gpios:4", + <&hy28a_pins>, "brcm,pins:4"; + ledgpio = <&hy28a>,"led-gpios:4", + <&hy28a_pins>, "brcm,pins:8"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/hy28b-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/hy28b-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/hy28b-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/hy28b-overlay.dts 2018-10-29 19:31:20.525783899 +0100 @@ -0,0 +1,148 @@ +/* + * Device Tree overlay for HY28b display shield by Texy + * + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&spidev1>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@3 { + target = <&gpio>; + __overlay__ { + hy28b_pins: hy28b_pins { + brcm,pins = <17 25 18>; + brcm,function = <0 1 1>; /* in out out */ + }; + }; + }; + + fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + hy28b: hy28b@0{ + compatible = "ilitek,ili9325"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&hy28b_pins>; + + spi-max-frequency = <48000000>; + spi-cpol; + spi-cpha; + rotate = <270>; + bgr; + fps = <50>; + buswidth = <8>; + startbyte = <0x70>; + reset-gpios = <&gpio 25 0>; + led-gpios = <&gpio 18 1>; + + gamma = "04 1F 4 7 7 0 7 7 6 0\n0F 00 1 7 4 0 0 0 6 7"; + + init = <0x10000e7 0x0010 + 0x1000000 0x0001 + 0x1000001 0x0100 + 0x1000002 0x0700 + 0x1000003 0x1030 + 0x1000004 0x0000 + 0x1000008 0x0207 + 0x1000009 0x0000 + 0x100000a 0x0000 + 0x100000c 0x0001 + 0x100000d 0x0000 + 0x100000f 0x0000 + 0x1000010 0x0000 + 0x1000011 0x0007 + 0x1000012 0x0000 + 0x1000013 0x0000 + 0x2000032 + 0x1000010 0x1590 + 0x1000011 0x0227 + 0x2000032 + 0x1000012 0x009c + 0x2000032 + 0x1000013 0x1900 + 0x1000029 0x0023 + 0x100002b 0x000e + 0x2000032 + 0x1000020 0x0000 + 0x1000021 0x0000 + 0x2000032 + 0x1000050 0x0000 + 0x1000051 0x00ef + 0x1000052 0x0000 + 0x1000053 0x013f + 0x1000060 0xa700 + 0x1000061 0x0001 + 0x100006a 0x0000 + 0x1000080 0x0000 + 0x1000081 0x0000 + 0x1000082 0x0000 + 0x1000083 0x0000 + 0x1000084 0x0000 + 0x1000085 0x0000 + 0x1000090 0x0010 + 0x1000092 0x0000 + 0x1000093 0x0003 + 0x1000095 0x0110 + 0x1000097 0x0000 + 0x1000098 0x0000 + 0x1000007 0x0133 + 0x1000020 0x0000 + 0x1000021 0x0000 + 0x2000064>; + debug = <0>; + }; + + hy28b_ts: hy28b-ts@1 { + compatible = "ti,ads7846"; + reg = <1>; + + spi-max-frequency = <2000000>; + interrupts = <17 2>; /* high-to-low edge triggered */ + interrupt-parent = <&gpio>; + pendown-gpio = <&gpio 17 0>; + ti,x-plate-ohms = /bits/ 16 <100>; + ti,pressure-max = /bits/ 16 <255>; + }; + }; + }; + __overrides__ { + speed = <&hy28b>,"spi-max-frequency:0"; + rotate = <&hy28b>,"rotate:0"; + fps = <&hy28b>,"fps:0"; + debug = <&hy28b>,"debug:0"; + xohms = <&hy28b_ts>,"ti,x-plate-ohms;0"; + resetgpio = <&hy28b>,"reset-gpios:4", + <&hy28b_pins>, "brcm,pins:4"; + ledgpio = <&hy28b>,"led-gpios:4", + <&hy28b_pins>, "brcm,pins:8"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts 2018-10-29 19:31:20.526783849 +0100 @@ -0,0 +1,69 @@ +/* + * Device tree overlay for i2c_bcm2708, i2c0 bus + * + * Compile: + * dtc -@ -I dts -O dtb -o i2c0-bcm2708-overlay.dtb i2c0-bcm2708-overlay.dts + */ + +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2c0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c0_pins>; + frag1: __overlay__ { + brcm,pins = <0 1>; + brcm,function = <4>; /* alt0 */ + }; + }; + + fragment@2 { + target = <&i2c0_pins>; + __dormant__ { + brcm,pins = <28 29>; + brcm,function = <4>; /* alt0 */ + }; + }; + + fragment@3 { + target = <&i2c0_pins>; + __dormant__ { + brcm,pins = <44 45>; + brcm,function = <5>; /* alt1 */ + }; + }; + + fragment@4 { + target = <&i2c0_pins>; + __dormant__ { + brcm,pins = <46 47>; + brcm,function = <4>; /* alt0 */ + }; + }; + + fragment@5 { + target = <&i2c0>; + __dormant__ { + compatible = "brcm,bcm2708-i2c"; + }; + }; + + __overrides__ { + sda0_pin = <&frag1>,"brcm,pins:0"; + scl0_pin = <&frag1>,"brcm,pins:4"; + pins_0_1 = <0>,"+1-2-3-4"; + pins_28_29 = <0>,"-1+2-3-4"; + pins_44_45 = <0>,"-1-2+3-4"; + pins_46_47 = <0>,"-1-2-3+4"; + combine = <0>, "!5"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts 2018-10-29 19:31:20.526783849 +0100 @@ -0,0 +1,43 @@ +/* + * Device tree overlay for i2c_bcm2708, i2c1 bus + * + * Compile: + * dtc -@ -I dts -O dtb -o i2c1-bcm2708-overlay.dtb i2c1-bcm2708-overlay.dts + */ + +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2c1>; + __overlay__ { + pinctrl-0 = <&i2c1_pins>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1_pins>; + pins: __overlay__ { + brcm,pins = <2 3>; + brcm,function = <4>; /* alt 0 */ + }; + }; + + fragment@2 { + target = <&i2c1>; + __dormant__ { + compatible = "brcm,bcm2708-i2c"; + }; + }; + + __overrides__ { + sda1_pin = <&pins>,"brcm,pins:0"; + scl1_pin = <&pins>,"brcm,pins:4"; + pin_func = <&pins>,"brcm,function:0"; + combine = <0>, "!2"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/i2c-bcm2708-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/i2c-bcm2708-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/i2c-bcm2708-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/i2c-bcm2708-overlay.dts 2018-10-29 19:31:20.525783899 +0100 @@ -0,0 +1,13 @@ +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2c_arm>; + __overlay__ { + compatible = "brcm,bcm2708-i2c"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts 2018-10-29 19:31:20.525783899 +0100 @@ -0,0 +1,43 @@ +// Overlay for i2c_gpio bitbanging host bus. +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/"; + __overlay__ { + i2c_gpio: i2c@0 { + compatible = "i2c-gpio"; + gpios = <&gpio 23 0 /* sda */ + &gpio 24 0 /* scl */ + >; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; + + fragment@1 { + target-path = "/aliases"; + __overlay__ { + i2c_gpio = "/i2c@0"; + }; + }; + + fragment@2 { + target-path = "/__symbols__"; + __overlay__ { + i2c_gpio = "/i2c@0"; + }; + }; + + __overrides__ { + i2c_gpio_sda = <&i2c_gpio>,"gpios:4"; + i2c_gpio_scl = <&i2c_gpio>,"gpios:16"; + i2c_gpio_delay_us = <&i2c_gpio>,"i2c-gpio,delay-us:0"; + bus = <&i2c_gpio>, "reg:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/i2c-mux-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/i2c-mux-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/i2c-mux-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/i2c-mux-overlay.dts 2018-10-29 19:31:20.525783899 +0100 @@ -0,0 +1,139 @@ +// Umbrella I2C Mux overlay + +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pca9542: mux@70 { + compatible = "nxp,pca9542"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + }; + }; + }; + + fragment@1 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pca9545: mux@70 { + compatible = "nxp,pca9545"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + }; + }; + }; + + fragment@2 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pca9548: mux@70 { + compatible = "nxp,pca9548"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; + }; + }; + + __overrides__ { + pca9542 = <0>, "+0"; + pca9545 = <0>, "+1"; + pca9548 = <0>, "+2"; + + addr = <&pca9542>,"reg:0", + <&pca9545>,"reg:0", + <&pca9548>,"reg:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts 2018-10-29 19:31:20.526783849 +0100 @@ -0,0 +1,26 @@ +// Definitions for NXP PCA9685A I2C PWM controller on ARM I2C bus. +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2c_arm>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pca: pca@40 { + compatible = "nxp,pca9685"; + #pwm-cells = <2>; + reg = <0x40>; + status = "okay"; + }; + }; + }; + __overrides__ { + addr = <&pca>,"reg:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts 2018-10-29 19:31:20.526783849 +0100 @@ -0,0 +1,183 @@ +// Definitions for several I2C based Real Time Clocks +// Available through i2c-gpio +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/"; + __overlay__ { + i2c_gpio: i2c-gpio-rtc@0 { + compatible = "i2c-gpio"; + gpios = <&gpio 23 0 /* sda */ + &gpio 24 0 /* scl */ + >; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; + + fragment@1 { + target = <&i2c_gpio>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + abx80x: abx80x@69 { + compatible = "abracon,abx80x"; + reg = <0x69>; + abracon,tc-diode = "standard"; + abracon,tc-resistor = <0>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&i2c_gpio>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ds1307: ds1307@68 { + compatible = "maxim,ds1307"; + reg = <0x68>; + status = "okay"; + }; + }; + }; + + fragment@3 { + target = <&i2c_gpio>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ds1339: ds1339@68 { + compatible = "dallas,ds1339"; + trickle-resistor-ohms = <0>; + reg = <0x68>; + status = "okay"; + }; + }; + }; + + fragment@4 { + target = <&i2c_gpio>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ds3231: ds3231@68 { + compatible = "maxim,ds3231"; + reg = <0x68>; + status = "okay"; + }; + }; + }; + + fragment@5 { + target = <&i2c_gpio>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + mcp7940x: mcp7940x@6f { + compatible = "microchip,mcp7940x"; + reg = <0x6f>; + status = "okay"; + }; + }; + }; + + fragment@6 { + target = <&i2c_gpio>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + mcp7941x: mcp7941x@6f { + compatible = "microchip,mcp7941x"; + reg = <0x6f>; + status = "okay"; + }; + }; + }; + + fragment@7 { + target = <&i2c_gpio>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcf2127: pcf2127@51 { + compatible = "nxp,pcf2127"; + reg = <0x51>; + status = "okay"; + }; + }; + }; + + fragment@8 { + target = <&i2c_gpio>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcf8523: pcf8523@68 { + compatible = "nxp,pcf8523"; + reg = <0x68>; + status = "okay"; + }; + }; + }; + + fragment@9 { + target = <&i2c_gpio>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcf8563: pcf8563@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + status = "okay"; + }; + }; + }; + + __overrides__ { + abx80x = <0>,"+1"; + ds1307 = <0>,"+2"; + ds1339 = <0>,"+3"; + ds3231 = <0>,"+4"; + mcp7940x = <0>,"+5"; + mcp7941x = <0>,"+6"; + pcf2127 = <0>,"+7"; + pcf8523 = <0>,"+8"; + pcf8563 = <0>,"+9"; + trickle-diode-type = <&abx80x>,"abracon,tc-diode"; + trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0", + <&abx80x>,"abracon,tc-resistor"; + wakeup-source = <&ds1339>,"wakeup-source?", + <&ds3231>,"wakeup-source?", + <&mcp7940x>,"wakeup-source?", + <&mcp7941x>,"wakeup-source?"; + i2c_gpio_sda = <&i2c_gpio>,"gpios:4"; + i2c_gpio_scl = <&i2c_gpio>,"gpios:16"; + i2c_gpio_delay_us = <&i2c_gpio>,"i2c-gpio,delay-us:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts 2018-10-29 19:31:20.526783849 +0100 @@ -0,0 +1,181 @@ +// Definitions for several I2C based Real Time Clocks +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + abx80x: abx80x@69 { + compatible = "abracon,abx80x"; + reg = <0x69>; + abracon,tc-diode = "standard"; + abracon,tc-resistor = <0>; + status = "okay"; + }; + }; + }; + + fragment@1 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ds1307: ds1307@68 { + compatible = "maxim,ds1307"; + reg = <0x68>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ds1339: ds1339@68 { + compatible = "dallas,ds1339"; + trickle-resistor-ohms = <0>; + reg = <0x68>; + status = "okay"; + }; + }; + }; + + fragment@3 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ds3231: ds3231@68 { + compatible = "maxim,ds3231"; + reg = <0x68>; + status = "okay"; + }; + }; + }; + + fragment@4 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + mcp7940x: mcp7940x@6f { + compatible = "microchip,mcp7940x"; + reg = <0x6f>; + status = "okay"; + }; + }; + }; + + fragment@5 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + mcp7941x: mcp7941x@6f { + compatible = "microchip,mcp7941x"; + reg = <0x6f>; + status = "okay"; + }; + }; + }; + + fragment@6 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcf2127: pcf2127@51 { + compatible = "nxp,pcf2127"; + reg = <0x51>; + status = "okay"; + }; + }; + }; + + fragment@7 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcf8523: pcf8523@68 { + compatible = "nxp,pcf8523"; + reg = <0x68>; + status = "okay"; + }; + }; + }; + + fragment@8 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcf8563: pcf8563@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + status = "okay"; + }; + }; + }; + + fragment@9 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + m41t62: m41t62@68 { + compatible = "st,m41t62"; + reg = <0x68>; + status = "okay"; + }; + }; + }; + + __overrides__ { + abx80x = <0>,"+0"; + ds1307 = <0>,"+1"; + ds1339 = <0>,"+2"; + ds3231 = <0>,"+3"; + mcp7940x = <0>,"+4"; + mcp7941x = <0>,"+5"; + pcf2127 = <0>,"+6"; + pcf8523 = <0>,"+7"; + pcf8563 = <0>,"+8"; + m41t62 = <0>,"+9"; + trickle-diode-type = <&abx80x>,"abracon,tc-diode"; + trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0", + <&abx80x>,"abracon,tc-resistor"; + wakeup-source = <&ds1339>,"wakeup-source?", + <&ds3231>,"wakeup-source?", + <&mcp7940x>,"wakeup-source?", + <&mcp7941x>,"wakeup-source?", + <&m41t62>,"wakeup-source?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts 2018-10-29 19:31:20.526783849 +0100 @@ -0,0 +1,223 @@ +// Definitions for I2C based sensors using the Industrial IO or HWMON interface. +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + bme280: bme280@76 { + compatible = "bosch,bme280"; + reg = <0x76>; + status = "okay"; + }; + }; + }; + + fragment@1 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + bmp085: bmp085@77 { + compatible = "bosch,bmp085"; + reg = <0x77>; + default-oversampling = <3>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + bmp180: bmp180@77 { + compatible = "bosch,bmp180"; + reg = <0x77>; + status = "okay"; + }; + }; + }; + + fragment@3 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + bmp280: bmp280@76 { + compatible = "bosch,bmp280"; + reg = <0x76>; + status = "okay"; + }; + }; + }; + + fragment@4 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + htu21: htu21@40 { + compatible = "htu21"; + reg = <0x40>; + status = "okay"; + }; + }; + }; + + fragment@5 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + lm75: lm75@4f { + compatible = "lm75"; + reg = <0x4f>; + status = "okay"; + }; + }; + }; + + fragment@6 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + si7020: si7020@40 { + compatible = "si7020"; + reg = <0x40>; + status = "okay"; + }; + }; + }; + + fragment@7 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + tmp102: tmp102@48 { + compatible = "ti,tmp102"; + reg = <0x48>; + status = "okay"; + }; + }; + }; + + fragment@8 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + hdc100x: hdc100x@40 { + compatible = "hdc100x"; + reg = <0x40>; + status = "okay"; + }; + }; + }; + + fragment@9 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + tsl4531: tsl4531@29 { + compatible = "tsl4531"; + reg = <0x29>; + status = "okay"; + }; + }; + }; + + fragment@10 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + veml6070: veml6070@38 { + compatible = "veml6070"; + reg = <0x38>; + status = "okay"; + }; + }; + }; + + fragment@11 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + sht3x: sht3x@44 { + compatible = "sht3x"; + reg = <0x44>; + status = "okay"; + }; + }; + }; + + fragment@12 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ds1621: ds1621@48 { + compatible = "ds1621"; + reg = <0x48>; + status = "okay"; + }; + }; + }; + + __overrides__ { + addr = <&bme280>,"reg:0", <&bmp280>,"reg:0", <&tmp102>,"reg:0", + <&lm75>,"reg:0", <&hdc100x>,"reg:0", <&sht3x>,"reg:0", + <&ds1621>,"reg:0"; + bme280 = <0>,"+0"; + bmp085 = <0>,"+1"; + bmp180 = <0>,"+2"; + bmp280 = <0>,"+3"; + htu21 = <0>,"+4"; + lm75 = <0>,"+5"; + lm75addr = <&lm75>,"reg:0"; + si7020 = <0>,"+6"; + tmp102 = <0>,"+7"; + hdc100x = <0>,"+8"; + tsl4531 = <0>,"+9"; + veml6070 = <0>,"+10"; + sht3x = <0>,"+11"; + ds1621 = <0>,"+12"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/i2s-gpio28-31-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/i2s-gpio28-31-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/i2s-gpio28-31-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/i2s-gpio28-31-overlay.dts 2018-10-29 19:31:20.526783849 +0100 @@ -0,0 +1,18 @@ +/* + * Device tree overlay to move i2s to gpio 28 to 31 on CM + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&i2s_pins>; + __overlay__ { + brcm,pins = <28 29 30 31>; + brcm,function = <6>; /* alt2 */ + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts 2018-10-29 19:31:20.526783849 +0100 @@ -0,0 +1,46 @@ +// Definitions for IQaudIO DAC +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcm5122@4c { + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4c>; + AVDD-supply = <&vdd_3v3_reg>; + DVDD-supply = <&vdd_3v3_reg>; + CPVDD-supply = <&vdd_3v3_reg>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + frag2: __overlay__ { + compatible = "iqaudio,iqaudio-dac"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + + __overrides__ { + 24db_digital_gain = <&frag2>,"iqaudio,24db_digital_gain?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts 2018-10-29 19:31:20.527783799 +0100 @@ -0,0 +1,49 @@ +// Definitions for IQaudIO DAC+ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcm5122@4c { + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4c>; + AVDD-supply = <&vdd_3v3_reg>; + DVDD-supply = <&vdd_3v3_reg>; + CPVDD-supply = <&vdd_3v3_reg>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + iqaudio_dac: __overlay__ { + compatible = "iqaudio,iqaudio-dac"; + i2s-controller = <&i2s>; + mute-gpios = <&gpio 22 0>; + status = "okay"; + }; + }; + + __overrides__ { + 24db_digital_gain = <&iqaudio_dac>,"iqaudio,24db_digital_gain?"; + auto_mute_amp = <&iqaudio_dac>,"iqaudio-dac,auto-mute-amp?"; + unmute_amp = <&iqaudio_dac>,"iqaudio-dac,unmute-amp?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/iqaudio-digi-wm8804-audio-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/iqaudio-digi-wm8804-audio-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/iqaudio-digi-wm8804-audio-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/iqaudio-digi-wm8804-audio-overlay.dts 2018-10-29 19:31:20.527783799 +0100 @@ -0,0 +1,47 @@ +// Definitions for IQAudIO Digi WM8804 audio board +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + wm8804@3b { + #sound-dai-cells = <0>; + compatible = "wlf,wm8804"; + reg = <0x3b>; + status = "okay"; + DVDD-supply = <&vdd_3v3_reg>; + PVDD-supply = <&vdd_3v3_reg>; + }; + }; + }; + + fragment@2 { + target = <&sound>; + wm8804_digi: __overlay__ { + compatible = "iqaudio,wm8804-digi"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + + __overrides__ { + card_name = <&wm8804_digi>,"wm8804-digi,card-name"; + dai_name = <&wm8804_digi>,"wm8804-digi,dai-name"; + dai_stream_name = <&wm8804_digi>,"wm8804-digi,dai-stream-name"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/jedec-spi-nor-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/jedec-spi-nor-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/jedec-spi-nor-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/jedec-spi-nor-overlay.dts 2018-10-29 19:31:20.527783799 +0100 @@ -0,0 +1,309 @@ +// Overlay for JEDEC SPI-NOR Flash Devices (aka m25p80) + +// dtparams: +// flash-spi- - Enables flash device on SPI, CS#. +// flash-fastr-spi- - Enables flash device with fast read capability on SPI, CS#. +// +// If devices are present on SPI1 or SPI2, those interfaces must be enabled with one of the spi1-1/2/3cs and/or spi2-1/2/3cs overlays. +// +// Example: A single flash device with fast read capability on SPI0, CS#0: +// dtoverlay=jedec-spi-nor:flash-fastr-spi0-0 + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + // disable spi-dev on spi0.0 + fragment@0 { + target = <&spidev0>; + __dormant__ { + status = "disabled"; + }; + }; + + // disable spi-dev on spi0.1 + fragment@1 { + target = <&spidev1>; + __dormant__ { + status = "disabled"; + }; + }; + + // disable spi-dev on spi1.0 + fragment@2 { + target-path = "spi1/spidev@0"; + __dormant__ { + status = "disabled"; + }; + }; + + // disable spi-dev on spi1.1 + fragment@3 { + target-path = "spi1/spidev@1"; + __dormant__ { + status = "disabled"; + }; + }; + + // disable spi-dev on spi1.2 + fragment@4 { + target-path = "spi1/spidev@2"; + __dormant__ { + status = "disabled"; + }; + }; + + // disable spi-dev on spi2.0 + fragment@5 { + target-path = "spi2/spidev@0"; + __dormant__ { + status = "disabled"; + }; + }; + + // disable spi-dev on spi2.1 + fragment@6 { + target-path = "spi2/spidev@1"; + __dormant__ { + status = "disabled"; + }; + }; + + // disable spi-dev on spi2.2 + fragment@7 { + target-path = "spi2/spidev@2"; + __dormant__ { + status = "disabled"; + }; + }; + + // enable flash on spi0.0 + fragment@8 { + target = <&spi0>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + spi_nor_00: spi_nor@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <500000>; + }; + }; + }; + + // enable flash on spi0.1 + fragment@9 { + target = <&spi0>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + spi_nor_01: spi_nor@1 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <1>; + spi-max-frequency = <500000>; + }; + }; + }; + + // enable flash on spi1.0 + fragment@10 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + spi_nor_10: spi_nor@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <500000>; + }; + }; + }; + + // enable flash on spi1.1 + fragment@11 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + spi_nor_11: spi_nor@1 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <1>; + spi-max-frequency = <500000>; + }; + }; + }; + + // enable flash on spi1.2 + fragment@12 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + spi_nor_12: spi_nor@2 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <2>; + spi-max-frequency = <500000>; + }; + }; + }; + + // enable flash on spi2.0 + fragment@13 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + spi_nor_20: spi_nor@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <500000>; + }; + }; + }; + + // enable flash on spi2.1 + fragment@14 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + spi_nor_21: spi_nor@1 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <1>; + spi-max-frequency = <500000>; + }; + }; + }; + + // enable flash on spi2.2 + fragment@15 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + spi_nor_22: spi_nor@2 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <2>; + spi-max-frequency = <500000>; + }; + }; + }; + + // Enable fast read for device on spi0.0. + // Use default active low interrupt signalling. + fragment@16 { + target = <&spi_nor_00>; + __dormant__ { + m25p,fast-read; + }; + }; + + // Enable fast read for device on spi0.1. + // Use default active low interrupt signalling. + fragment@17 { + target = <&spi_nor_01>; + __dormant__ { + m25p,fast-read; + }; + }; + + // Enable fast read for device on spi1.0. + // Use default active low interrupt signalling. + fragment@18 { + target = <&spi_nor_10>; + __dormant__ { + m25p,fast-read; + }; + }; + + // Enable fast read for device on spi1.1. + // Use default active low interrupt signalling. + fragment@19 { + target = <&spi_nor_11>; + __dormant__ { + m25p,fast-read; + }; + }; + + // Enable fast read for device on spi1.2. + // Use default active low interrupt signalling. + fragment@20 { + target = <&spi_nor_12>; + __dormant__ { + m25p,fast-read; + }; + }; + + // Enable fast read for device on spi2.0. + // Use default active low interrupt signalling. + fragment@21 { + target = <&spi_nor_20>; + __dormant__ { + m25p,fast-read; + }; + }; + + // Enable fast read for device on spi2.1. + // Use default active low interrupt signalling. + fragment@22 { + target = <&spi_nor_21>; + __dormant__ { + m25p,fast-read; + }; + }; + + // Enable fast read for device on spi2.2. + // Use default active low interrupt signalling. + fragment@23 { + target = <&spi_nor_22>; + __dormant__ { + m25p,fast-read; + }; + }; + + __overrides__ { + flash-spi0-0 = <0>,"+0+8"; + flash-spi0-1 = <0>,"+1+9"; + flash-spi1-0 = <0>,"+2+10"; + flash-spi1-1 = <0>,"+3+11"; + flash-spi1-2 = <0>,"+4+12"; + flash-spi2-0 = <0>,"+5+13"; + flash-spi2-1 = <0>,"+6+14"; + flash-spi2-2 = <0>,"+7+15"; + flash-fastr-spi0-0 = <0>,"+0+8+16"; + flash-fastr-spi0-1 = <0>,"+1+9+17"; + flash-fastr-spi1-0 = <0>,"+2+10+18"; + flash-fastr-spi1-1 = <0>,"+3+11+19"; + flash-fastr-spi1-2 = <0>,"+4+12+20"; + flash-fastr-spi2-0 = <0>,"+5+13+21"; + flash-fastr-spi2-1 = <0>,"+6+14+22"; + flash-fastr-spi2-2 = <0>,"+7+15+23"; + }; +}; + diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/justboom-dac-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/justboom-dac-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/justboom-dac-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/justboom-dac-overlay.dts 2018-10-29 19:31:20.527783799 +0100 @@ -0,0 +1,46 @@ +// Definitions for JustBoom DAC +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcm5122@4d { + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4d>; + AVDD-supply = <&vdd_3v3_reg>; + DVDD-supply = <&vdd_3v3_reg>; + CPVDD-supply = <&vdd_3v3_reg>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + frag2: __overlay__ { + compatible = "justboom,justboom-dac"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + + __overrides__ { + 24db_digital_gain = <&frag2>,"justboom,24db_digital_gain?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/justboom-digi-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/justboom-digi-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/justboom-digi-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/justboom-digi-overlay.dts 2018-10-29 19:31:20.527783799 +0100 @@ -0,0 +1,41 @@ +// Definitions for JustBoom Digi +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + wm8804@3b { + #sound-dai-cells = <0>; + compatible = "wlf,wm8804"; + reg = <0x3b>; + PVDD-supply = <&vdd_3v3_reg>; + DVDD-supply = <&vdd_3v3_reg>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "justboom,justboom-digi"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts 2018-10-29 19:31:20.527783799 +0100 @@ -0,0 +1,57 @@ +// Definitions for lirc-rpi module +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/"; + __overlay__ { + lirc_rpi: lirc_rpi { + compatible = "rpi,lirc-rpi"; + pinctrl-names = "default"; + pinctrl-0 = <&lirc_pins>; + status = "okay"; + + // Override autodetection of IR receiver circuit + // (0 = active high, 1 = active low, -1 = no override ) + rpi,sense = <0xffffffff>; + + // Software carrier + // (0 = off, 1 = on) + rpi,softcarrier = <1>; + + // Invert output + // (0 = off, 1 = on) + rpi,invert = <0>; + + // Enable debugging messages + // (0 = off, 1 = on) + rpi,debug = <0>; + }; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + lirc_pins: lirc_pins { + brcm,pins = <17 18>; + brcm,function = <1 0>; // out in + brcm,pull = <0 1>; // off down + }; + }; + }; + + __overrides__ { + gpio_out_pin = <&lirc_pins>,"brcm,pins:0"; + gpio_in_pin = <&lirc_pins>,"brcm,pins:4"; + gpio_in_pull = <&lirc_pins>,"brcm,pull:4"; + + sense = <&lirc_rpi>,"rpi,sense:0"; + softcarrier = <&lirc_rpi>,"rpi,softcarrier:0"; + invert = <&lirc_rpi>,"rpi,invert:0"; + debug = <&lirc_rpi>,"rpi,debug:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/ltc294x-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/ltc294x-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/ltc294x-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/ltc294x-overlay.dts 2018-10-29 19:31:20.527783799 +0100 @@ -0,0 +1,86 @@ +/dts-v1/; +/plugin/; + + +/ { + compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ltc2941: ltc2941@64 { + compatible = "lltc,ltc2941"; + reg = <0x64>; + lltc,resistor-sense = <50>; + lltc,prescaler-exponent = <7>; + }; + }; + }; + + fragment@1 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ltc2942: ltc2942@64 { + compatible = "lltc,ltc2942"; + reg = <0x64>; + lltc,resistor-sense = <50>; + lltc,prescaler-exponent = <7>; + }; + }; + }; + + fragment@2 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ltc2943: ltc2943@64 { + compatible = "lltc,ltc2943"; + reg = <0x64>; + lltc,resistor-sense = <50>; + lltc,prescaler-exponent = <7>; + }; + }; + }; + + fragment@3 { + target = <&i2c_arm>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ltc2944: ltc2944@64 { + compatible = "lltc,ltc2944"; + reg = <0x64>; + lltc,resistor-sense = <50>; + lltc,prescaler-exponent = <7>; + }; + }; + }; + + __overrides__ { + ltc2941 = <0>,"+0"; + ltc2942 = <0>,"+1"; + ltc2943 = <0>,"+2"; + ltc2944 = <0>,"+3"; + resistor-sense = <<c2941>, "lltc,resistor-sense:0", + <<c2942>, "lltc,resistor-sense:0", + <<c2943>, "lltc,resistor-sense:0", + <<c2944>, "lltc,resistor-sense:0"; + prescaler-exponent = <<c2941>, "lltc,prescaler-exponent:0", + <<c2942>, "lltc,prescaler-exponent:0", + <<c2943>, "lltc,prescaler-exponent:0", + <<c2944>, "lltc,prescaler-exponent:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/Makefile linux-vendor/arch/arm/boot/dts/overlays/Makefile --- linux-4.18.16/arch/arm/boot/dts/overlays/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/Makefile 2018-10-29 19:31:20.516784349 +0100 @@ -0,0 +1,148 @@ +# Overlays for the Raspberry Pi platform + +dtbo-$(CONFIG_ARCH_BCM2835) += \ + adau1977-adc.dtbo \ + adau7002-simple.dtbo \ + ads1015.dtbo \ + ads1115.dtbo \ + ads7846.dtbo \ + akkordion-iqdacplus.dtbo \ + allo-boss-dac-pcm512x-audio.dtbo \ + allo-digione.dtbo \ + allo-katana-dac-audio.dtbo \ + allo-piano-dac-pcm512x-audio.dtbo \ + allo-piano-dac-plus-pcm512x-audio.dtbo \ + applepi-dac.dtbo \ + at86rf233.dtbo \ + audioinjector-addons.dtbo \ + audioinjector-wm8731-audio.dtbo \ + audremap.dtbo \ + balena-fin.dtbo \ + bmp085_i2c-sensor.dtbo \ + dht11.dtbo \ + dionaudio-loco.dtbo \ + dionaudio-loco-v2.dtbo \ + dpi18.dtbo \ + dpi24.dtbo \ + dwc-otg.dtbo \ + dwc2.dtbo \ + enc28j60.dtbo \ + enc28j60-spi2.dtbo \ + exc3000.dtbo \ + fe-pi-audio.dtbo \ + goodix.dtbo \ + googlevoicehat-soundcard.dtbo \ + gpio-ir.dtbo \ + gpio-ir-tx.dtbo \ + gpio-key.dtbo \ + gpio-no-irq.dtbo \ + gpio-poweroff.dtbo \ + gpio-shutdown.dtbo \ + hifiberry-amp.dtbo \ + hifiberry-dac.dtbo \ + hifiberry-dacplus.dtbo \ + hifiberry-dacplusadc.dtbo \ + hifiberry-digi.dtbo \ + hifiberry-digi-pro.dtbo \ + hy28a.dtbo \ + hy28b.dtbo \ + i2c-bcm2708.dtbo \ + i2c-gpio.dtbo \ + i2c-mux.dtbo \ + i2c-pwm-pca9685a.dtbo \ + i2c-rtc.dtbo \ + i2c-rtc-gpio.dtbo \ + i2c-sensor.dtbo \ + i2c0-bcm2708.dtbo \ + i2c1-bcm2708.dtbo \ + i2s-gpio28-31.dtbo \ + iqaudio-dac.dtbo \ + iqaudio-dacplus.dtbo \ + iqaudio-digi-wm8804-audio.dtbo \ + jedec-spi-nor.dtbo \ + justboom-dac.dtbo \ + justboom-digi.dtbo \ + lirc-rpi.dtbo \ + ltc294x.dtbo \ + mbed-dac.dtbo \ + mcp23017.dtbo \ + mcp23s17.dtbo \ + mcp2515-can0.dtbo \ + mcp2515-can1.dtbo \ + mcp3008.dtbo \ + mcp3202.dtbo \ + media-center.dtbo \ + midi-uart0.dtbo \ + midi-uart1.dtbo \ + mmc.dtbo \ + mpu6050.dtbo \ + mz61581.dtbo \ + papirus.dtbo \ + pi3-act-led.dtbo \ + pi3-disable-bt.dtbo \ + pi3-disable-wifi.dtbo \ + pi3-miniuart-bt.dtbo \ + pibell.dtbo \ + piscreen.dtbo \ + piscreen2r.dtbo \ + pisound.dtbo \ + pitft22.dtbo \ + pitft28-capacitive.dtbo \ + pitft28-resistive.dtbo \ + pitft35-resistive.dtbo \ + pps-gpio.dtbo \ + pwm.dtbo \ + pwm-2chan.dtbo \ + pwm-ir-tx.dtbo \ + qca7000.dtbo \ + rotary-encoder.dtbo \ + rpi-backlight.dtbo \ + rpi-cirrus-wm5102.dtbo \ + rpi-dac.dtbo \ + rpi-display.dtbo \ + rpi-ft5406.dtbo \ + rpi-poe.dtbo \ + rpi-proto.dtbo \ + rpi-sense.dtbo \ + rpi-tv.dtbo \ + rra-digidac1-wm8741-audio.dtbo \ + sc16is750-i2c.dtbo \ + sc16is752-i2c.dtbo \ + sc16is752-spi1.dtbo \ + sdhost.dtbo \ + sdio.dtbo \ + sdio-1bit.dtbo \ + sdtweak.dtbo \ + smi.dtbo \ + smi-dev.dtbo \ + smi-nand.dtbo \ + spi-gpio35-39.dtbo \ + spi-rtc.dtbo \ + spi0-cs.dtbo \ + spi0-hw-cs.dtbo \ + spi1-1cs.dtbo \ + spi1-2cs.dtbo \ + spi1-3cs.dtbo \ + spi2-1cs.dtbo \ + spi2-2cs.dtbo \ + spi2-3cs.dtbo \ + superaudioboard.dtbo \ + sx150x.dtbo \ + tinylcd35.dtbo \ + tpm-slb9670.dtbo \ + uart0.dtbo \ + uart1.dtbo \ + upstream.dtbo \ + upstream-aux-interrupt.dtbo \ + vc4-fkms-v3d.dtbo \ + vc4-kms-v3d.dtbo \ + vga666.dtbo \ + w1-gpio.dtbo \ + w1-gpio-pullup.dtbo \ + wittypi.dtbo + +targets += dtbs dtbs_install +targets += $(dtbo-y) + +always := $(dtbo-y) +clean-files := *.dtbo diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/mbed-dac-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/mbed-dac-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/mbed-dac-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/mbed-dac-overlay.dts 2018-10-29 19:31:20.527783799 +0100 @@ -0,0 +1,64 @@ +// Definitions for mbed DAC +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + tlv320aic23: codec@1a { + #sound-dai-cells = <0>; + reg = <0x1a>; + compatible = "ti,tlv320aic23"; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "simple-audio-card"; + i2s-controller = <&i2s>; + status = "okay"; + + simple-audio-card,name = "mbed-DAC"; + + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Line", "Line In", + "Headphone", "Headphone Jack"; + + simple-audio-card,routing = + "Headphone Jack", "LHPOUT", + "Headphone Jack", "RHPOUT", + "LLINEIN", "Line In", + "RLINEIN", "Line In", + "MICIN", "Mic Jack"; + + simple-audio-card,format = "i2s"; + + simple-audio-card,cpu { + sound-dai = <&i2s>; + }; + + sound_master: simple-audio-card,codec { + sound-dai = <&tlv320aic23>; + system-clock-frequency = <12288000>; + }; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/mcp23017-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/mcp23017-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/mcp23017-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/mcp23017-overlay.dts 2018-10-29 19:31:20.528783749 +0100 @@ -0,0 +1,54 @@ +// Definitions for MCP23017 Gpio Extender from Microchip Semiconductor + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&i2c1>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + mcp23017_pins: mcp23017_pins { + brcm,pins = <4>; + brcm,function = <0>; + }; + }; + }; + + fragment@2 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + mcp23017: mcp@20 { + compatible = "microchip,mcp23017"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells=<2>; + interrupt-parent = <&gpio>; + interrupts = <4 2>; + interrupt-controller; + microchip,irq-mirror; + + status = "okay"; + }; + }; + }; + + __overrides__ { + gpiopin = <&mcp23017_pins>,"brcm,pins:0", + <&mcp23017>,"interrupts:0"; + addr = <&mcp23017>,"reg:0"; + }; +}; + diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/mcp23s17-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/mcp23s17-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/mcp23s17-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/mcp23s17-overlay.dts 2018-10-29 19:31:20.528783749 +0100 @@ -0,0 +1,732 @@ +// Overlay for MCP23S08/17 GPIO Extenders from Microchip Semiconductor + +// dtparams: +// s08-spi--present - 4-bit integer, bitmap indicating MCP23S08 devices present on SPI, CS#. +// s17-spi--present - 8-bit integer, bitmap indicating MCP23S17 devices present on SPI, CS#. +// s08-spi--int-gpio - integer, enables interrupts on a single MCP23S08 device on SPI, CS#, specifies the GPIO pin to which INT output is connected. +// s17-spi--int-gpio - integer, enables mirrored interrupts on a single MCP23S17 device on SPI, CS#, specifies the GPIO pin to which either INTA or INTB output is connected. +// +// If devices are present on SPI1 or SPI2, those interfaces must be enabled with one of the spi1-1/2/3cs and/or spi2-1/2/3cs overlays. +// If interrupts are enabled for a device on a given CS# on a SPI bus, that device must be the only one present on that SPI bus/CS#. +// +// Example 1: A single MCP23S17 device on SPI0, CS#0 with its SPI addr set to 0 and INTA output connected to GPIO25: +// dtoverlay=mcp23s17:s17-spi0-0-present=1,s17-spi0-0-int-gpio=25 +// +// Example 2: Two MCP23S08 devices on SPI1, CS#0 with their addrs set to 2 and 3. Three MCP23S17 devices on SPI1, CS#1 with their addrs set to 0, 1 and 7: +// dtoverlay=spi1-2cs +// dtoverlay=mcp23s17:s08-spi1-0-present=12,s17-spi1-1-present=131 + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + // disable spi-dev on spi0.0 + fragment@0 { + target = <&spidev0>; + __dormant__ { + status = "disabled"; + }; + }; + + // disable spi-dev on spi0.1 + fragment@1 { + target = <&spidev1>; + __dormant__ { + status = "disabled"; + }; + }; + + // disable spi-dev on spi1.0 + fragment@2 { + target-path = "spi1/spidev@0"; + __dormant__ { + status = "disabled"; + }; + }; + + // disable spi-dev on spi1.1 + fragment@3 { + target-path = "spi1/spidev@1"; + __dormant__ { + status = "disabled"; + }; + }; + + // disable spi-dev on spi1.2 + fragment@4 { + target-path = "spi1/spidev@2"; + __dormant__ { + status = "disabled"; + }; + }; + + // disable spi-dev on spi2.0 + fragment@5 { + target-path = "spi2/spidev@0"; + __dormant__ { + status = "disabled"; + }; + }; + + // disable spi-dev on spi2.1 + fragment@6 { + target-path = "spi2/spidev@1"; + __dormant__ { + status = "disabled"; + }; + }; + + // disable spi-dev on spi2.2 + fragment@7 { + target-path = "spi2/spidev@2"; + __dormant__ { + status = "disabled"; + }; + }; + + // enable one or more mcp23s08s on spi0.0 + fragment@8 { + target = <&spi0>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s08_00: mcp23s08@0 { + compatible = "microchip,mcp23s08"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s08-spi0-0-present parameter */ + reg = <0>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s08-spi0-0-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s08s on spi0.1 + fragment@9 { + target = <&spi0>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s08_01: mcp23s08@1 { + compatible = "microchip,mcp23s08"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s08-spi0-1-present parameter */ + reg = <1>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s08-spi0-1-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s08s on spi1.0 + fragment@10 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s08_10: mcp23s08@0 { + compatible = "microchip,mcp23s08"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s08-spi1-0-present parameter */ + reg = <0>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s08-spi1-0-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s08s on spi1.1 + fragment@11 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s08_11: mcp23s08@1 { + compatible = "microchip,mcp23s08"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s08-spi1-1-present parameter */ + reg = <1>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s08-spi1-1-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s08s on spi1.2 + fragment@12 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s08_12: mcp23s08@2 { + compatible = "microchip,mcp23s08"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s08-spi1-2-present parameter */ + reg = <2>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s08-spi1-2-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s08s on spi2.0 + fragment@13 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s08_20: mcp23s08@0 { + compatible = "microchip,mcp23s08"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s08-spi2-0-present parameter */ + reg = <0>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s08-spi2-0-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s08s on spi2.1 + fragment@14 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s08_21: mcp23s08@1 { + compatible = "microchip,mcp23s08"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s08-spi2-1-present parameter */ + reg = <1>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s08-spi2-1-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s08s on spi2.2 + fragment@15 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s08_22: mcp23s08@2 { + compatible = "microchip,mcp23s08"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s08-spi2-2-present parameter */ + reg = <2>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s08-spi2-2-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s17s on spi0.0 + fragment@16 { + target = <&spi0>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s17_00: mcp23s17@0 { + compatible = "microchip,mcp23s17"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s17-spi0-0-present parameter */ + reg = <0>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s17-spi0-0-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s17s on spi0.1 + fragment@17 { + target = <&spi0>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s17_01: mcp23s17@1 { + compatible = "microchip,mcp23s17"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s17-spi0-1-present parameter */ + reg = <1>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s17-spi0-1-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s17s on spi1.0 + fragment@18 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s17_10: mcp23s17@0 { + compatible = "microchip,mcp23s17"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s17-spi1-0-present parameter */ + reg = <0>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s17-spi1-0-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s17s on spi1.1 + fragment@19 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s17_11: mcp23s17@1 { + compatible = "microchip,mcp23s17"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s17-spi1-1-present parameter */ + reg = <1>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s17-spi1-1-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s17s on spi1.2 + fragment@20 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s17_12: mcp23s17@2 { + compatible = "microchip,mcp23s17"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s17-spi1-2-present parameter */ + reg = <2>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s17-spi1-2-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s17s on spi2.0 + fragment@21 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s17_20: mcp23s17@0 { + compatible = "microchip,mcp23s17"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s17-spi2-0-present parameter */ + reg = <0>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s17-spi2-0-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s17s on spi2.1 + fragment@22 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s17_21: mcp23s17@1 { + compatible = "microchip,mcp23s17"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s17-spi2-1-present parameter */ + reg = <1>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s17-spi2-1-int-gpio parameter */ + }; + }; + }; + + // enable one or more mcp23s17s on spi2.2 + fragment@23 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + mcp23s17_22: mcp23s17@2 { + compatible = "microchip,mcp23s17"; + gpio-controller; + #gpio-cells = <2>; + microchip,spi-present-mask = <0x00>; /* overwritten by mcp23s17-spi2-2-present parameter */ + reg = <2>; + spi-max-frequency = <500000>; + status = "okay"; + #interrupt-cells=<2>; + interrupts = <0 2>; /* 1st word overwritten by mcp23s17-spi2-2-int-gpio parameter */ + }; + }; + }; + + // Configure GPIO pin connected to INT(A/B) output of mcp23s08/17 on spi0.0 as a input with no pull-up/down + fragment@24 { + target = <&gpio>; + __dormant__ { + spi0_0_int_pins: spi0_0_int_pins { + brcm,pins = <0>; /* overwritten by mcp23s08/17-spi0-0-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to INT(A/B) output of mcp23s08/17 on spi0.1 as a input with no pull-up/down + fragment@25 { + target = <&gpio>; + __dormant__ { + spi0_1_int_pins: spi0_1_int_pins { + brcm,pins = <0>; /* overwritten by mcp23s08/17-spi0-1-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to INT(A/B) output of mcp23s08/17 on spi1.0 as a input with no pull-up/down + fragment@26 { + target = <&gpio>; + __dormant__ { + spi1_0_int_pins: spi1_0_int_pins { + brcm,pins = <0>; /* overwritten by mcp23s08/17-spi1-0-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to INT(A/B) output of mcp23s08/17 on spi1.1 as a input with no pull-up/down + fragment@27 { + target = <&gpio>; + __dormant__ { + spi1_1_int_pins: spi1_1_int_pins { + brcm,pins = <0>; /* overwritten by mcp23s08/17-spi1-1-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to INT(A/B) output of mcp23s08/17 on spi1.2 as a input with no pull-up/down + fragment@28 { + target = <&gpio>; + __dormant__ { + spi1_2_int_pins: spi1_2_int_pins { + brcm,pins = <0>; /* overwritten by mcp23s08/17-spi1-2-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to INT(A/B) output of mcp23s08/17 on spi2.0 as a input with no pull-up/down + fragment@29 { + target = <&gpio>; + __dormant__ { + spi2_0_int_pins: spi2_0_int_pins { + brcm,pins = <0>; /* overwritten by mcp23s08/17-spi2-0-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to INT(A/B) output of mcp23s08/17 on spi2.1 as a input with no pull-up/down + fragment@30 { + target = <&gpio>; + __dormant__ { + spi2_1_int_pins: spi2_1_int_pins { + brcm,pins = <0>; /* overwritten by mcp23s08/17-spi2-1-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to INT(A/B) output of mcp23s08/17 on spi2.2 as a input with no pull-up/down + fragment@31 { + target = <&gpio>; + __dormant__ { + spi2_2_int_pins: spi2_2_int_pins { + brcm,pins = <0>; /* overwritten by mcp23s08/17-spi2-2-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Enable interrupts for a mcp23s08 on spi0.0. + // Use default active low interrupt signalling. + fragment@32 { + target = <&mcp23s08_00>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + }; + }; + + // Enable interrupts for a mcp23s08 on spi0.1. + // Use default active low interrupt signalling. + fragment@33 { + target = <&mcp23s08_01>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + }; + }; + + // Enable interrupts for a mcp23s08 on spi1.0. + // Use default active low interrupt signalling. + fragment@34 { + target = <&mcp23s08_10>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + }; + }; + + // Enable interrupts for a mcp23s08 on spi1.1. + // Use default active low interrupt signalling. + fragment@35 { + target = <&mcp23s08_11>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + }; + }; + + // Enable interrupts for a mcp23s08 on spi1.2. + // Use default active low interrupt signalling. + fragment@36 { + target = <&mcp23s08_12>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + }; + }; + + // Enable interrupts for a mcp23s08 on spi2.0. + // Use default active low interrupt signalling. + fragment@37 { + target = <&mcp23s08_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + }; + }; + + // Enable interrupts for a mcp23s08 on spi2.1. + // Use default active low interrupt signalling. + fragment@38 { + target = <&mcp23s08_21>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + }; + }; + + // Enable interrupts for a mcp23s08 on spi2.2. + // Use default active low interrupt signalling. + fragment@39 { + target = <&mcp23s08_22>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + }; + }; + + // Enable interrupts for a mcp23s17 on spi0.0. + // Enable mirroring so that either INTA or INTB output of mcp23s17 can be connected to the GPIO pin. + // Use default active low interrupt signalling. + fragment@40 { + target = <&mcp23s17_00>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + microchip,irq-mirror; + }; + }; + + // Enable interrupts for a mcp23s17 on spi0.1. + // Enable mirroring so that either INTA or INTB output of mcp23s17 can be connected to the GPIO pin. + // Configure INTA/B outputs of mcp23s08/17 as active low. + fragment@41 { + target = <&mcp23s17_01>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + microchip,irq-mirror; + }; + }; + + // Enable interrupts for a mcp23s17 on spi1.0. + // Enable mirroring so that either INTA or INTB output of mcp23s17 can be connected to the GPIO pin. + // Configure INTA/B outputs of mcp23s08/17 as active low. + fragment@42 { + target = <&mcp23s17_10>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + microchip,irq-mirror; + }; + }; + + // Enable interrupts for a mcp23s17 on spi1.1. + // Enable mirroring so that either INTA or INTB output of mcp23s17 can be connected to the GPIO pin. + // Configure INTA/B outputs of mcp23s08/17 as active low. + fragment@43 { + target = <&mcp23s17_11>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + microchip,irq-mirror; + }; + }; + + // Enable interrupts for a mcp23s17 on spi1.2. + // Enable mirroring so that either INTA or INTB output of mcp23s17 can be connected to the GPIO pin. + // Configure INTA/B outputs of mcp23s08/17 as active low. + fragment@44 { + target = <&mcp23s17_12>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + microchip,irq-mirror; + }; + }; + + // Enable interrupts for a mcp23s17 on spi2.0. + // Enable mirroring so that either INTA or INTB output of mcp23s17 can be connected to the GPIO pin. + // Configure INTA/B outputs of mcp23s08/17 as active low. + fragment@45 { + target = <&mcp23s17_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + microchip,irq-mirror; + }; + }; + + // Enable interrupts for a mcp23s17 on spi2.1. + // Enable mirroring so that either INTA or INTB output of mcp23s17 can be connected to the GPIO pin. + // Configure INTA/B outputs of mcp23s08/17 as active low. + fragment@46 { + target = <&mcp23s17_21>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + microchip,irq-mirror; + }; + }; + + // Enable interrupts for a mcp23s17 on spi2.2. + // Enable mirroring so that either INTA or INTB output of mcp23s17 can be connected to the GPIO pin. + // Configure INTA/B outputs of mcp23s08/17 as active low. + fragment@47 { + target = <&mcp23s17_22>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + microchip,irq-mirror; + }; + }; + + __overrides__ { + s08-spi0-0-present = <0>,"+0+8", <&mcp23s08_00>,"microchip,spi-present-mask:0"; + s08-spi0-1-present = <0>,"+1+9", <&mcp23s08_01>,"microchip,spi-present-mask:0"; + s08-spi1-0-present = <0>,"+2+10", <&mcp23s08_10>,"microchip,spi-present-mask:0"; + s08-spi1-1-present = <0>,"+3+11", <&mcp23s08_11>,"microchip,spi-present-mask:0"; + s08-spi1-2-present = <0>,"+4+12", <&mcp23s08_12>,"microchip,spi-present-mask:0"; + s08-spi2-0-present = <0>,"+5+13", <&mcp23s08_20>,"microchip,spi-present-mask:0"; + s08-spi2-1-present = <0>,"+6+14", <&mcp23s08_21>,"microchip,spi-present-mask:0"; + s08-spi2-2-present = <0>,"+7+15", <&mcp23s08_22>,"microchip,spi-present-mask:0"; + s17-spi0-0-present = <0>,"+0+16", <&mcp23s17_00>,"microchip,spi-present-mask:0"; + s17-spi0-1-present = <0>,"+1+17", <&mcp23s17_01>,"microchip,spi-present-mask:0"; + s17-spi1-0-present = <0>,"+2+18", <&mcp23s17_10>,"microchip,spi-present-mask:0"; + s17-spi1-1-present = <0>,"+3+19", <&mcp23s17_11>,"microchip,spi-present-mask:0"; + s17-spi1-2-present = <0>,"+4+20", <&mcp23s17_12>,"microchip,spi-present-mask:0"; + s17-spi2-0-present = <0>,"+5+21", <&mcp23s17_20>,"microchip,spi-present-mask:0"; + s17-spi2-1-present = <0>,"+6+22", <&mcp23s17_21>,"microchip,spi-present-mask:0"; + s17-spi2-2-present = <0>,"+7+23", <&mcp23s17_22>,"microchip,spi-present-mask:0"; + s08-spi0-0-int-gpio = <0>,"+24+32", <&spi0_0_int_pins>,"brcm,pins:0", <&mcp23s08_00>,"interrupts:0"; + s08-spi0-1-int-gpio = <0>,"+25+33", <&spi0_1_int_pins>,"brcm,pins:0", <&mcp23s08_01>,"interrupts:0"; + s08-spi1-0-int-gpio = <0>,"+26+34", <&spi1_0_int_pins>,"brcm,pins:0", <&mcp23s08_10>,"interrupts:0"; + s08-spi1-1-int-gpio = <0>,"+27+35", <&spi1_1_int_pins>,"brcm,pins:0", <&mcp23s08_11>,"interrupts:0"; + s08-spi1-2-int-gpio = <0>,"+28+36", <&spi1_2_int_pins>,"brcm,pins:0", <&mcp23s08_12>,"interrupts:0"; + s08-spi2-0-int-gpio = <0>,"+29+37", <&spi2_0_int_pins>,"brcm,pins:0", <&mcp23s08_20>,"interrupts:0"; + s08-spi2-1-int-gpio = <0>,"+30+38", <&spi2_1_int_pins>,"brcm,pins:0", <&mcp23s08_21>,"interrupts:0"; + s08-spi2-2-int-gpio = <0>,"+31+39", <&spi2_2_int_pins>,"brcm,pins:0", <&mcp23s08_22>,"interrupts:0"; + s17-spi0-0-int-gpio = <0>,"+24+40", <&spi0_0_int_pins>,"brcm,pins:0", <&mcp23s17_00>,"interrupts:0"; + s17-spi0-1-int-gpio = <0>,"+25+41", <&spi0_1_int_pins>,"brcm,pins:0", <&mcp23s17_01>,"interrupts:0"; + s17-spi1-0-int-gpio = <0>,"+26+42", <&spi1_0_int_pins>,"brcm,pins:0", <&mcp23s17_10>,"interrupts:0"; + s17-spi1-1-int-gpio = <0>,"+27+43", <&spi1_1_int_pins>,"brcm,pins:0", <&mcp23s17_11>,"interrupts:0"; + s17-spi1-2-int-gpio = <0>,"+28+44", <&spi1_2_int_pins>,"brcm,pins:0", <&mcp23s17_12>,"interrupts:0"; + s17-spi2-0-int-gpio = <0>,"+29+45", <&spi2_0_int_pins>,"brcm,pins:0", <&mcp23s17_20>,"interrupts:0"; + s17-spi2-1-int-gpio = <0>,"+30+46", <&spi2_1_int_pins>,"brcm,pins:0", <&mcp23s17_21>,"interrupts:0"; + s17-spi2-2-int-gpio = <0>,"+31+47", <&spi2_2_int_pins>,"brcm,pins:0", <&mcp23s17_22>,"interrupts:0"; + }; +}; + diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts 2018-10-29 19:31:20.528783749 +0100 @@ -0,0 +1,73 @@ +/* + * Device tree overlay for mcp251x/can0 on spi0.0 + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; + /* disable spi-dev for spi0.0 */ + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + /* the interrupt pin of the can-controller */ + fragment@2 { + target = <&gpio>; + __overlay__ { + can0_pins: can0_pins { + brcm,pins = <25>; + brcm,function = <0>; /* input */ + }; + }; + }; + + /* the clock/oscillator of the can-controller */ + fragment@3 { + target-path = "/clocks"; + __overlay__ { + /* external oscillator of mcp2515 on SPI0.0 */ + can0_osc: can0_osc { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <16000000>; + }; + }; + }; + + /* the spi config of the can-controller itself binding everything together */ + fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + can0: mcp2515@0 { + reg = <0>; + compatible = "microchip,mcp2515"; + pinctrl-names = "default"; + pinctrl-0 = <&can0_pins>; + spi-max-frequency = <10000000>; + interrupt-parent = <&gpio>; + interrupts = <25 8>; /* IRQ_TYPE_LEVEL_LOW */ + clocks = <&can0_osc>; + }; + }; + }; + __overrides__ { + oscillator = <&can0_osc>,"clock-frequency:0"; + spimaxfrequency = <&can0>,"spi-max-frequency:0"; + interrupt = <&can0_pins>,"brcm,pins:0",<&can0>,"interrupts:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts 2018-10-29 19:31:20.528783749 +0100 @@ -0,0 +1,73 @@ +/* + * Device tree overlay for mcp251x/can1 on spi0.1 edited by petit_miner + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; + /* disable spi-dev for spi0.1 */ + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev1>; + __overlay__ { + status = "disabled"; + }; + }; + + /* the interrupt pin of the can-controller */ + fragment@2 { + target = <&gpio>; + __overlay__ { + can1_pins: can1_pins { + brcm,pins = <25>; + brcm,function = <0>; /* input */ + }; + }; + }; + + /* the clock/oscillator of the can-controller */ + fragment@3 { + target-path = "/clocks"; + __overlay__ { + /* external oscillator of mcp2515 on spi0.1 */ + can1_osc: can1_osc { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <16000000>; + }; + }; + }; + + /* the spi config of the can-controller itself binding everything together */ + fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + can1: mcp2515@1 { + reg = <1>; + compatible = "microchip,mcp2515"; + pinctrl-names = "default"; + pinctrl-0 = <&can1_pins>; + spi-max-frequency = <10000000>; + interrupt-parent = <&gpio>; + interrupts = <25 8>; /* IRQ_TYPE_LEVEL_LOW */ + clocks = <&can1_osc>; + }; + }; + }; + __overrides__ { + oscillator = <&can1_osc>,"clock-frequency:0"; + spimaxfrequency = <&can1>,"spi-max-frequency:0"; + interrupt = <&can1_pins>,"brcm,pins:0",<&can1>,"interrupts:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/mcp3008-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/mcp3008-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/mcp3008-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/mcp3008-overlay.dts 2018-10-29 19:31:20.528783749 +0100 @@ -0,0 +1,205 @@ +/* + * Device tree overlay for Microchip mcp3008 10-Bit A/D Converters + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spidev0>; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@1 { + target = <&spidev1>; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@2 { + target-path = "spi1/spidev@0"; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@3 { + target-path = "spi1/spidev@1"; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@4 { + target-path = "spi1/spidev@2"; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@5 { + target-path = "spi2/spidev@0"; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@6 { + target-path = "spi2/spidev@1"; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@7 { + target-path = "spi2/spidev@2"; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@8 { + target = <&spi0>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3008_00: mcp3008@0 { + compatible = "mcp3008"; + reg = <0>; + spi-max-frequency = <1600000>; + }; + }; + }; + + fragment@9 { + target = <&spi0>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3008_01: mcp3008@1 { + compatible = "mcp3008"; + reg = <1>; + spi-max-frequency = <1600000>; + }; + }; + }; + + fragment@10 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3008_10: mcp3008@0 { + compatible = "mcp3008"; + reg = <0>; + spi-max-frequency = <1600000>; + }; + }; + }; + + fragment@11 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3008_11: mcp3008@1 { + compatible = "mcp3008"; + reg = <1>; + spi-max-frequency = <1600000>; + }; + }; + }; + + fragment@12 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3008_12: mcp3008@2 { + compatible = "mcp3008"; + reg = <2>; + spi-max-frequency = <1600000>; + }; + }; + }; + + fragment@13 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3008_20: mcp3008@0 { + compatible = "mcp3008"; + reg = <0>; + spi-max-frequency = <1600000>; + }; + }; + }; + + fragment@14 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3008_21: mcp3008@1 { + compatible = "mcp3008"; + reg = <1>; + spi-max-frequency = <1600000>; + }; + }; + }; + + fragment@15 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3008_22: mcp3008@2 { + compatible = "mcp3008"; + reg = <2>; + spi-max-frequency = <1600000>; + }; + }; + }; + + __overrides__ { + spi0-0-present = <0>, "+0+8"; + spi0-1-present = <0>, "+1+9"; + spi1-0-present = <0>, "+2+10"; + spi1-1-present = <0>, "+3+11"; + spi1-2-present = <0>, "+4+12"; + spi2-0-present = <0>, "+5+13"; + spi2-1-present = <0>, "+6+14"; + spi2-2-present = <0>, "+7+15"; + spi0-0-speed = <&mcp3008_00>, "spi-max-frequency:0"; + spi0-1-speed = <&mcp3008_01>, "spi-max-frequency:0"; + spi1-0-speed = <&mcp3008_10>, "spi-max-frequency:0"; + spi1-1-speed = <&mcp3008_11>, "spi-max-frequency:0"; + spi1-2-speed = <&mcp3008_12>, "spi-max-frequency:0"; + spi2-0-speed = <&mcp3008_20>, "spi-max-frequency:0"; + spi2-1-speed = <&mcp3008_21>, "spi-max-frequency:0"; + spi2-2-speed = <&mcp3008_22>, "spi-max-frequency:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/mcp3202-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/mcp3202-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/mcp3202-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/mcp3202-overlay.dts 2018-10-29 19:31:20.529783699 +0100 @@ -0,0 +1,205 @@ +/* + * Device tree overlay for Microchip mcp3202 12-Bit A/D Converters + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spidev0>; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@1 { + target = <&spidev1>; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@2 { + target-path = "spi1/spidev@0"; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@3 { + target-path = "spi1/spidev@1"; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@4 { + target-path = "spi1/spidev@2"; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@5 { + target-path = "spi2/spidev@0"; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@6 { + target-path = "spi2/spidev@1"; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@7 { + target-path = "spi2/spidev@2"; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@8 { + target = <&spi0>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3202_00: mcp3202@0 { + compatible = "mcp3202"; + reg = <0>; + spi-max-frequency = <1600000>; + }; + }; + }; + + fragment@9 { + target = <&spi0>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3202_01: mcp3202@1 { + compatible = "mcp3202"; + reg = <1>; + spi-max-frequency = <1600000>; + }; + }; + }; + + fragment@10 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3202_10: mcp3202@0 { + compatible = "mcp3202"; + reg = <0>; + spi-max-frequency = <1600000>; + }; + }; + }; + + fragment@11 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3202_11: mcp3202@1 { + compatible = "mcp3202"; + reg = <1>; + spi-max-frequency = <1600000>; + }; + }; + }; + + fragment@12 { + target = <&spi1>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3202_12: mcp3202@2 { + compatible = "mcp3202"; + reg = <2>; + spi-max-frequency = <1600000>; + }; + }; + }; + + fragment@13 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3202_20: mcp3202@0 { + compatible = "mcp3202"; + reg = <0>; + spi-max-frequency = <1600000>; + }; + }; + }; + + fragment@14 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3202_21: mcp3202@1 { + compatible = "mcp3202"; + reg = <1>; + spi-max-frequency = <1600000>; + }; + }; + }; + + fragment@15 { + target = <&spi2>; + __dormant__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mcp3202_22: mcp3202@2 { + compatible = "mcp3202"; + reg = <2>; + spi-max-frequency = <1600000>; + }; + }; + }; + + __overrides__ { + spi0-0-present = <0>, "+0+8"; + spi0-1-present = <0>, "+1+9"; + spi1-0-present = <0>, "+2+10"; + spi1-1-present = <0>, "+3+11"; + spi1-2-present = <0>, "+4+12"; + spi2-0-present = <0>, "+5+13"; + spi2-1-present = <0>, "+6+14"; + spi2-2-present = <0>, "+7+15"; + spi0-0-speed = <&mcp3202_00>, "spi-max-frequency:0"; + spi0-1-speed = <&mcp3202_01>, "spi-max-frequency:0"; + spi1-0-speed = <&mcp3202_10>, "spi-max-frequency:0"; + spi1-1-speed = <&mcp3202_11>, "spi-max-frequency:0"; + spi1-2-speed = <&mcp3202_12>, "spi-max-frequency:0"; + spi2-0-speed = <&mcp3202_20>, "spi-max-frequency:0"; + spi2-1-speed = <&mcp3202_21>, "spi-max-frequency:0"; + spi2-2-speed = <&mcp3202_22>, "spi-max-frequency:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/media-center-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/media-center-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/media-center-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/media-center-overlay.dts 2018-10-29 19:31:20.529783699 +0100 @@ -0,0 +1,134 @@ +/* + * Device Tree overlay for Media Center HAT by Pi Supply + * + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + + spidev@0{ + status = "disabled"; + }; + + spidev@1{ + status = "disabled"; + }; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + rpi_display_pins: rpi_display_pins { + brcm,pins = <12 23 24 25>; + brcm,function = <1 1 1 0>; /* out out out in */ + brcm,pull = <0 0 0 2>; /* - - - up */ + }; + }; + }; + + fragment@2 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + rpidisplay: rpi-display@0{ + compatible = "ilitek,ili9341"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&rpi_display_pins>; + + spi-max-frequency = <32000000>; + rotate = <90>; + bgr; + fps = <30>; + buswidth = <8>; + reset-gpios = <&gpio 23 0>; + dc-gpios = <&gpio 24 0>; + led-gpios = <&gpio 12 1>; + debug = <0>; + }; + + rpidisplay_ts: rpi-display-ts@1 { + compatible = "ti,ads7846"; + reg = <1>; + + spi-max-frequency = <2000000>; + interrupts = <25 2>; /* high-to-low edge triggered */ + interrupt-parent = <&gpio>; + pendown-gpio = <&gpio 25 0>; + ti,x-plate-ohms = /bits/ 16 <60>; + ti,pressure-max = /bits/ 16 <255>; + }; + }; + }; + + fragment@3 { + target-path = "/"; + __overlay__ { + lirc_rpi: lirc_rpi { + compatible = "rpi,lirc-rpi"; + pinctrl-names = "default"; + pinctrl-0 = <&lirc_pins>; + status = "okay"; + + // Override autodetection of IR receiver circuit + // (0 = active high, 1 = active low, -1 = no override ) + rpi,sense = <0xffffffff>; + + // Software carrier + // (0 = off, 1 = on) + rpi,softcarrier = <1>; + + // Invert output + // (0 = off, 1 = on) + rpi,invert = <0>; + + // Enable debugging messages + // (0 = off, 1 = on) + rpi,debug = <0>; + }; + }; + }; + + fragment@4 { + target = <&gpio>; + __overlay__ { + lirc_pins: lirc_pins { + brcm,pins = <6 5>; + brcm,function = <1 0>; // out in + brcm,pull = <0 1>; // off down + }; + }; + }; + + __overrides__ { + speed = <&rpidisplay>,"spi-max-frequency:0"; + rotate = <&rpidisplay>,"rotate:0"; + fps = <&rpidisplay>,"fps:0"; + debug = <&rpidisplay>,"debug:0", + <&lirc_rpi>,"rpi,debug:0"; + xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; + swapxy = <&rpidisplay_ts>,"ti,swap-xy?"; + backlight = <&rpidisplay>,"led-gpios:4", + <&rpi_display_pins>,"brcm,pins:0"; + + gpio_out_pin = <&lirc_pins>,"brcm,pins:0"; + gpio_in_pin = <&lirc_pins>,"brcm,pins:4"; + gpio_in_pull = <&lirc_pins>,"brcm,pull:4"; + + sense = <&lirc_rpi>,"rpi,sense:0"; + softcarrier = <&lirc_rpi>,"rpi,softcarrier:0"; + invert = <&lirc_rpi>,"rpi,invert:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/midi-uart0-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/midi-uart0-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/midi-uart0-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/midi-uart0-overlay.dts 2018-10-29 19:31:20.529783699 +0100 @@ -0,0 +1,36 @@ +/dts-v1/; +/plugin/; + +#include + +/* + * Fake a higher clock rate to get a larger divisor, and thereby a lower + * baudrate. The real clock is 48MHz, which we scale so that requesting + * 38.4kHz results in an actual 31.25kHz. + * + * 48000000*38400/31250 = 58982400 + */ + +/{ + compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/clocks"; + __overlay__ { + midi_clk: midi_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "uart0_pclk"; + clock-frequency = <58982400>; + }; + }; + }; + + fragment@1 { + target = <&uart0>; + __overlay__ { + clocks = <&midi_clk>, + <&clocks BCM2835_CLOCK_VPU>; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/midi-uart1-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/midi-uart1-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/midi-uart1-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/midi-uart1-overlay.dts 2018-10-29 19:31:20.529783699 +0100 @@ -0,0 +1,43 @@ +/dts-v1/; +/plugin/; + +#include + +/* + * Fake a higher clock rate to get a larger divisor, and thereby a lower + * baudrate. The real clock is 48MHz, which we scale so that requesting + * 38.4kHz results in an actual 31.25kHz. + * + * 48000000*38400/31250 = 58982400 + */ + +/{ + compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/clocks"; + __overlay__ { + midi_clk: clock@5 { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + clocks = <&aux BCM2835_AUX_CLOCK_UART>; + clock-mult = <38400>; + clock-div = <31250>; + }; + }; + }; + + fragment@1 { + target = <&uart1>; + __overlay__ { + clocks = <&midi_clk>; + }; + }; + + fragment@2 { + target = <&aux>; + __overlay__ { + clock-output-names = "aux_uart", "aux_spi1", "aux_spi2"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/mmc-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/mmc-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/mmc-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/mmc-overlay.dts 2018-10-29 19:31:20.529783699 +0100 @@ -0,0 +1,39 @@ +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&mmc>; + frag0: __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&mmc_pins>; + bus-width = <4>; + brcm,overclock-50 = <0>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + mmc_pins: mmc_pins { + brcm,pins = <48 49 50 51 52 53>; + brcm,function = <7>; /* alt3 */ + brcm,pull = <0 2 2 2 2 2>; + }; + }; + }; + + fragment@2 { + target = <&sdhost>; + __overlay__ { + status = "disabled"; + }; + }; + + __overrides__ { + overclock_50 = <&frag0>,"brcm,overclock-50:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/mpu6050-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/mpu6050-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/mpu6050-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/mpu6050-overlay.dts 2018-10-29 19:31:20.529783699 +0100 @@ -0,0 +1,28 @@ +// Definitions for MPU6050 +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + clock-frequency = <400000>; + + mpu6050: mpu6050@68 { + compatible = "invensense,mpu6050"; + reg = <0x68>; + interrupt-parent = <&gpio>; + interrupts = <4 1>; + }; + }; + }; + + __overrides__ { + interrupt = <&mpu6050>,"interrupts:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/mz61581-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/mz61581-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/mz61581-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/mz61581-overlay.dts 2018-10-29 19:31:20.530783649 +0100 @@ -0,0 +1,117 @@ +/* + * Device Tree overlay for MZ61581-PI-EXT 2014.12.28 by Tontec + * + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&spidev1>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@3 { + target = <&gpio>; + __overlay__ { + mz61581_pins: mz61581_pins { + brcm,pins = <4 15 18 25>; + brcm,function = <0 1 1 1>; /* in out out out */ + }; + }; + }; + + fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + mz61581: mz61581@0{ + compatible = "samsung,s6d02a1"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&mz61581_pins>; + + spi-max-frequency = <128000000>; + spi-cpol; + spi-cpha; + + width = <320>; + height = <480>; + rotate = <270>; + bgr; + fps = <30>; + buswidth = <8>; + txbuflen = <32768>; + + reset-gpios = <&gpio 15 0>; + dc-gpios = <&gpio 25 0>; + led-gpios = <&gpio 18 0>; + + init = <0x10000b0 00 + 0x1000011 + 0x20000ff + 0x10000b3 0x02 0x00 0x00 0x00 + 0x10000c0 0x13 0x3b 0x00 0x02 0x00 0x01 0x00 0x43 + 0x10000c1 0x08 0x16 0x08 0x08 + 0x10000c4 0x11 0x07 0x03 0x03 + 0x10000c6 0x00 + 0x10000c8 0x03 0x03 0x13 0x5c 0x03 0x07 0x14 0x08 0x00 0x21 0x08 0x14 0x07 0x53 0x0c 0x13 0x03 0x03 0x21 0x00 + 0x1000035 0x00 + 0x1000036 0xa0 + 0x100003a 0x55 + 0x1000044 0x00 0x01 + 0x10000d0 0x07 0x07 0x1d 0x03 + 0x10000d1 0x03 0x30 0x10 + 0x10000d2 0x03 0x14 0x04 + 0x1000029 + 0x100002c>; + + /* This is a workaround to make sure the init sequence slows down and doesn't fail */ + debug = <3>; + }; + + mz61581_ts: mz61581_ts@1 { + compatible = "ti,ads7846"; + reg = <1>; + + spi-max-frequency = <2000000>; + interrupts = <4 2>; /* high-to-low edge triggered */ + interrupt-parent = <&gpio>; + pendown-gpio = <&gpio 4 0>; + + ti,x-plate-ohms = /bits/ 16 <60>; + ti,pressure-max = /bits/ 16 <255>; + }; + }; + }; + __overrides__ { + speed = <&mz61581>, "spi-max-frequency:0"; + rotate = <&mz61581>, "rotate:0"; + fps = <&mz61581>, "fps:0"; + txbuflen = <&mz61581>, "txbuflen:0"; + debug = <&mz61581>, "debug:0"; + xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/papirus-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/papirus-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/papirus-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/papirus-overlay.dts 2018-10-29 19:31:20.530783649 +0100 @@ -0,0 +1,89 @@ +/* PaPiRus ePaper Screen by Pi Supply */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2c_arm>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + display_temp: lm75@48 { + compatible = "lm75b"; + reg = <0x48>; + status = "okay"; + #thermal-sensor-cells = <0>; + }; + }; + }; + + fragment@1 { + target-path = "/"; + __overlay__ { + thermal-zones { + display { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&display_temp>; + }; + }; + }; + }; + + fragment@2 { + target = <&spi0>; + __overlay__ { + status = "okay"; + + spidev@0{ + status = "disabled"; + }; + }; + }; + + fragment@3 { + target = <&gpio>; + __overlay__ { + repaper_pins: repaper_pins { + brcm,pins = <14 15 23 24 25>; + brcm,function = <1 1 1 1 0>; /* out out out out in */ + }; + }; + }; + + fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + repaper: repaper@0{ + compatible = "not_set"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&repaper_pins>; + + spi-max-frequency = <8000000>; + + panel-on-gpios = <&gpio 23 0>; + border-gpios = <&gpio 14 0>; + discharge-gpios = <&gpio 15 0>; + reset-gpios = <&gpio 24 0>; + busy-gpios = <&gpio 25 0>; + + repaper-thermal-zone = "display"; + }; + }; + }; + + __overrides__ { + panel = <&repaper>, "compatible"; + speed = <&repaper>, "spi-max-frequency:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts 2018-10-29 19:31:20.530783649 +0100 @@ -0,0 +1,27 @@ +/dts-v1/; +/plugin/; + +/* Pi3 uses a GPIO expander to drive the LEDs which can only be accessed + from the VPU. There is a special driver for this with a separate DT node, + which has the unfortunate consequence of breaking the act_led_gpio and + act_led_activelow dtparams. + + This overlay changes the GPIO controller back to the standard one and + restores the dtparams. +*/ + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&act_led>; + frag0: __overlay__ { + gpios = <&gpio 0 0>; + }; + }; + + __overrides__ { + gpio = <&frag0>,"gpios:4"; + activelow = <&frag0>,"gpios:8"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts 2018-10-29 19:31:20.530783649 +0100 @@ -0,0 +1,46 @@ +/dts-v1/; +/plugin/; + +/* Disable Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15. + To disable the systemd service that initialises the modem so it doesn't use + the UART: + + sudo systemctl disable hciuart +*/ + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&uart1>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@1 { + target = <&uart0>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; + }; + }; + + fragment@2 { + target = <&uart0_pins>; + __overlay__ { + brcm,pins; + brcm,function; + brcm,pull; + }; + }; + + fragment@3 { + target-path = "/aliases"; + __overlay__ { + serial0 = "/soc/serial@7e201000"; + serial1 = "/soc/serial@7e215040"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts 2018-10-29 19:31:20.530783649 +0100 @@ -0,0 +1,13 @@ +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&mmc>; + __overlay__ { + status = "disabled"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts 2018-10-29 19:31:20.530783649 +0100 @@ -0,0 +1,74 @@ +/dts-v1/; +/plugin/; + +/* Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore + UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum + usable baudrate. + + It is also necessary to edit /lib/systemd/system/hciuart.service and + replace ttyAMA0 with ttyS0, unless you have a system with udev rules + that create /dev/serial0 and /dev/serial1, in which case use /dev/serial1 + instead because it will always be correct. + + If cmdline.txt uses the alias serial0 to refer to the user-accessable port + then the firmware will replace with the appropriate port whether or not + this overlay is used. +*/ + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&uart0>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&uart1>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins &bt_pins &fake_bt_cts>; + status = "okay"; + }; + }; + + fragment@2 { + target = <&uart0_pins>; + __overlay__ { + brcm,pins; + brcm,function; + brcm,pull; + }; + }; + + fragment@3 { + target = <&uart1_pins>; + __overlay__ { + brcm,pins = <32 33>; + brcm,function = <2>; /* alt5=UART1 */ + brcm,pull = <0 2>; + }; + }; + + fragment@4 { + target = <&gpio>; + __overlay__ { + fake_bt_cts: fake_bt_cts { + brcm,pins = <31>; + brcm,function = <1>; /* output */ + }; + }; + }; + + fragment@5 { + target-path = "/aliases"; + __overlay__ { + serial0 = "/soc/serial@7e201000"; + serial1 = "/soc/serial@7e215040"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/pibell-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/pibell-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/pibell-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/pibell-overlay.dts 2018-10-29 19:31:20.530783649 +0100 @@ -0,0 +1,81 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/"; + __overlay__ { + codec_out: spdif-transmitter { + #address-cells = <0>; + #size-cells = <0>; + #sound-dai-cells = <0>; + compatible = "linux,spdif-dit"; + status = "okay"; + }; + + codec_in: card-codec { + #sound-dai-cells = <0>; + compatible = "invensense,ics43432"; + status = "okay"; + }; + }; + }; + + fragment@1 { + target = <&i2s>; + __overlay__ { + #sound-dai-cells = <0>; + status = "okay"; + }; + }; + + fragment@2 { + target = <&sound>; + snd: __overlay__ { + compatible = "simple-audio-card"; + simple-audio-card,name = "PiBell"; + + status="okay"; + + capture_link: simple-audio-card,dai-link@0 { + format = "i2s"; + + r_cpu_dai: cpu { + sound-dai = <&i2s>; + +/* example TDM slot configuration + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; +*/ + }; + + r_codec_dai: codec { + sound-dai = <&codec_in>; + }; + }; + + playback_link: simple-audio-card,dai-link@1 { + format = "i2s"; + + p_cpu_dai: cpu { + sound-dai = <&i2s>; + +/* example TDM slot configuration + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; +*/ + }; + + p_codec_dai: codec { + sound-dai = <&codec_out>; + }; + }; + }; + }; + + __overrides__ { + alsaname = <&snd>, "simple-audio-card,name"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts 2018-10-29 19:31:20.539783201 +0100 @@ -0,0 +1,106 @@ + /* + * Device Tree overlay for PiScreen2 3.5" TFT with resistive touch by Ozzmaker.com + * + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&spidev1>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@3 { + target = <&gpio>; + __overlay__ { + piscreen2_pins: piscreen2_pins { + brcm,pins = <17 25 24 22>; + brcm,function = <0 1 1 1>; /* in out out out */ + }; + }; + }; + + fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + piscreen2: piscreen2@0{ + compatible = "ilitek,ili9486"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&piscreen2_pins>; + bgr; + spi-max-frequency = <64000000>; + rotate = <90>; + fps = <30>; + buswidth = <8>; + regwidth = <16>; + txbuflen = <32768>; + reset-gpios = <&gpio 25 0>; + dc-gpios = <&gpio 24 0>; + led-gpios = <&gpio 22 1>; + debug = <0>; + + init = <0x10000b0 0x00 + 0x1000011 + 0x20000ff + 0x100003a 0x55 + 0x1000036 0x28 + 0x10000c0 0x11 0x09 + 0x10000c1 0x41 + 0x10000c5 0x00 0x00 0x00 0x00 + 0x10000b6 0x00 0x02 + 0x10000f7 0xa9 0x51 0x2c 0x2 + 0x10000be 0x00 0x04 + 0x10000e9 0x00 + 0x1000011 + 0x1000029>; + + }; + + piscreen2_ts: piscreen2-ts@1 { + compatible = "ti,ads7846"; + reg = <1>; + + spi-max-frequency = <2000000>; + interrupts = <17 2>; /* high-to-low edge triggered */ + interrupt-parent = <&gpio>; + pendown-gpio = <&gpio 17 0>; + ti,swap-xy; + ti,x-plate-ohms = /bits/ 16 <100>; + ti,pressure-max = /bits/ 16 <255>; + }; + }; + }; + __overrides__ { + speed = <&piscreen2>,"spi-max-frequency:0"; + rotate = <&piscreen2>,"rotate:0"; + fps = <&piscreen2>,"fps:0"; + debug = <&piscreen2>,"debug:0"; + xohms = <&piscreen2_ts>,"ti,x-plate-ohms;0"; + }; +}; + diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/piscreen-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/piscreen-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/piscreen-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/piscreen-overlay.dts 2018-10-29 19:31:20.530783649 +0100 @@ -0,0 +1,102 @@ +/* + * Device Tree overlay for PiScreen 3.5" display shield by Ozzmaker + * + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&spidev1>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@3 { + target = <&gpio>; + __overlay__ { + piscreen_pins: piscreen_pins { + brcm,pins = <17 25 24 22>; + brcm,function = <0 1 1 1>; /* in out out out */ + }; + }; + }; + + fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + piscreen: piscreen@0{ + compatible = "ilitek,ili9486"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&piscreen_pins>; + + spi-max-frequency = <24000000>; + rotate = <270>; + bgr; + fps = <30>; + buswidth = <8>; + regwidth = <16>; + reset-gpios = <&gpio 25 0>; + dc-gpios = <&gpio 24 0>; + led-gpios = <&gpio 22 1>; + debug = <0>; + + init = <0x10000b0 0x00 + 0x1000011 + 0x20000ff + 0x100003a 0x55 + 0x1000036 0x28 + 0x10000c2 0x44 + 0x10000c5 0x00 0x00 0x00 0x00 + 0x10000e0 0x0f 0x1f 0x1c 0x0c 0x0f 0x08 0x48 0x98 0x37 0x0a 0x13 0x04 0x11 0x0d 0x00 + 0x10000e1 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 + 0x10000e2 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 + 0x1000011 + 0x1000029>; + }; + + piscreen_ts: piscreen-ts@1 { + compatible = "ti,ads7846"; + reg = <1>; + + spi-max-frequency = <2000000>; + interrupts = <17 2>; /* high-to-low edge triggered */ + interrupt-parent = <&gpio>; + pendown-gpio = <&gpio 17 0>; + ti,swap-xy; + ti,x-plate-ohms = /bits/ 16 <100>; + ti,pressure-max = /bits/ 16 <255>; + }; + }; + }; + __overrides__ { + speed = <&piscreen>,"spi-max-frequency:0"; + rotate = <&piscreen>,"rotate:0"; + fps = <&piscreen>,"fps:0"; + debug = <&piscreen>,"debug:0"; + xohms = <&piscreen_ts>,"ti,x-plate-ohms;0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/pisound-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/pisound-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/pisound-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/pisound-overlay.dts 2018-10-29 19:31:20.539783201 +0100 @@ -0,0 +1,120 @@ +/* + * Pisound Linux kernel module. + * Copyright (C) 2016-2017 Vilniaus Blokas UAB, https://blokas.io/pisound + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/dts-v1/; +/plugin/; + +#include + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&spidev1>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@3 { + target = <&spi0>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + pisound_spi: pisound_spi@0{ + compatible = "blokaslabs,pisound-spi"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + spi-max-frequency = <1000000>; + }; + }; + }; + + fragment@4 { + target-path = "/"; + __overlay__ { + pcm5102a-codec { + #sound-dai-cells = <0>; + compatible = "ti,pcm5102a"; + status = "okay"; + }; + }; + }; + + fragment@5 { + target = <&sound>; + __overlay__ { + compatible = "blokaslabs,pisound"; + i2s-controller = <&i2s>; + status = "okay"; + + pinctrl-0 = <&pisound_button_pins>; + + osr-gpios = + <&gpio 13 GPIO_ACTIVE_HIGH>, + <&gpio 26 GPIO_ACTIVE_HIGH>, + <&gpio 16 GPIO_ACTIVE_HIGH>; + + reset-gpios = + <&gpio 12 GPIO_ACTIVE_HIGH>, + <&gpio 24 GPIO_ACTIVE_HIGH>; + + data_available-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; + + button-gpios = <&gpio 17 GPIO_ACTIVE_LOW>; + }; + }; + + fragment@6 { + target = <&gpio>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&pisound_button_pins>; + + pisound_button_pins: pisound_button_pins { + brcm,pins = <17>; + brcm,function = <0>; // Input + brcm,pull = <2>; // Pull-Up + }; + }; + }; + + fragment@7 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/pitft22-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/pitft22-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/pitft22-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/pitft22-overlay.dts 2018-10-29 19:31:20.540783151 +0100 @@ -0,0 +1,69 @@ +/* + * Device Tree overlay for pitft by Adafruit + * + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + + spidev@0{ + status = "disabled"; + }; + + spidev@1{ + status = "disabled"; + }; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + pitft_pins: pitft_pins { + brcm,pins = <25>; + brcm,function = <1>; /* out */ + brcm,pull = <0>; /* none */ + }; + }; + }; + + fragment@2 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + pitft: pitft@0{ + compatible = "ilitek,ili9340"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pitft_pins>; + + spi-max-frequency = <32000000>; + rotate = <90>; + fps = <25>; + bgr; + buswidth = <8>; + dc-gpios = <&gpio 25 0>; + debug = <0>; + }; + + }; + }; + + __overrides__ { + speed = <&pitft>,"spi-max-frequency:0"; + rotate = <&pitft>,"rotate:0"; + fps = <&pitft>,"fps:0"; + debug = <&pitft>,"debug:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts 2018-10-29 19:31:20.541783101 +0100 @@ -0,0 +1,91 @@ +/* + * Device Tree overlay for Adafruit PiTFT 2.8" capacitive touch screen + * + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&gpio>; + __overlay__ { + pitft_pins: pitft_pins { + brcm,pins = <24 25>; + brcm,function = <0 1>; /* in out */ + brcm,pull = <2 0>; /* pullup none */ + }; + }; + }; + + fragment@3 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + pitft: pitft@0{ + compatible = "ilitek,ili9340"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pitft_pins>; + + spi-max-frequency = <32000000>; + rotate = <90>; + fps = <25>; + bgr; + buswidth = <8>; + dc-gpios = <&gpio 25 0>; + debug = <0>; + }; + }; + }; + + fragment@4 { + target = <&i2c1>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + ft6236: ft6236@38 { + compatible = "focaltech,ft6236"; + reg = <0x38>; + + interrupt-parent = <&gpio>; + interrupts = <24 2>; + touchscreen-size-x = <240>; + touchscreen-size-y = <320>; + }; + }; + }; + + __overrides__ { + speed = <&pitft>,"spi-max-frequency:0"; + rotate = <&pitft>,"rotate:0"; + fps = <&pitft>,"fps:0"; + debug = <&pitft>,"debug:0"; + touch-sizex = <&ft6236>,"touchscreen-size-x?"; + touch-sizey = <&ft6236>,"touchscreen-size-y?"; + touch-invx = <&ft6236>,"touchscreen-inverted-x?"; + touch-invy = <&ft6236>,"touchscreen-inverted-y?"; + touch-swapxy = <&ft6236>,"touchscreen-swapped-x-y?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts 2018-10-29 19:31:20.542783051 +0100 @@ -0,0 +1,119 @@ +/* + * Device Tree overlay for Adafruit PiTFT 2.8" resistive touch screen + * + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&spidev1>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@3 { + target = <&gpio>; + __overlay__ { + pitft_pins: pitft_pins { + brcm,pins = <24 25>; + brcm,function = <0 1>; /* in out */ + brcm,pull = <2 0>; /* pullup none */ + }; + }; + }; + + fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + pitft: pitft@0{ + compatible = "ilitek,ili9340"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pitft_pins>; + + spi-max-frequency = <32000000>; + rotate = <90>; + fps = <25>; + bgr; + buswidth = <8>; + dc-gpios = <&gpio 25 0>; + debug = <0>; + }; + + pitft_ts@1 { + compatible = "st,stmpe610"; + reg = <1>; + + spi-max-frequency = <500000>; + irq-gpio = <&gpio 24 0x2>; /* IRQF_TRIGGER_FALLING */ + interrupts = <24 2>; /* high-to-low edge triggered */ + interrupt-parent = <&gpio>; + interrupt-controller; + + stmpe_touchscreen { + compatible = "st,stmpe-ts"; + st,sample-time = <4>; + st,mod-12b = <1>; + st,ref-sel = <0>; + st,adc-freq = <2>; + st,ave-ctrl = <3>; + st,touch-det-delay = <4>; + st,settling = <2>; + st,fraction-z = <7>; + st,i-drive = <0>; + }; + + stmpe_gpio: stmpe_gpio { + #gpio-cells = <2>; + compatible = "st,stmpe-gpio"; + /* + * only GPIO2 is wired/available + * and it is wired to the backlight + */ + st,norequest-mask = <0x7b>; + }; + }; + }; + }; + + fragment@5 { + target-path = "/soc"; + __overlay__ { + backlight { + compatible = "gpio-backlight"; + gpios = <&stmpe_gpio 2 0>; + default-on; + }; + }; + }; + + __overrides__ { + speed = <&pitft>,"spi-max-frequency:0"; + rotate = <&pitft>,"rotate:0"; + fps = <&pitft>,"fps:0"; + debug = <&pitft>,"debug:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts 2018-10-29 19:31:20.542783051 +0100 @@ -0,0 +1,119 @@ +/* + * Device Tree overlay for Adafruit PiTFT 3.5" resistive touch screen + * + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&spidev1>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@3 { + target = <&gpio>; + __overlay__ { + pitft_pins: pitft_pins { + brcm,pins = <24 25>; + brcm,function = <0 1>; /* in out */ + brcm,pull = <2 0>; /* pullup none */ + }; + }; + }; + + fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + pitft: pitft@0{ + compatible = "himax,hx8357d"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pitft_pins>; + + spi-max-frequency = <32000000>; + rotate = <90>; + fps = <25>; + bgr; + buswidth = <8>; + dc-gpios = <&gpio 25 0>; + debug = <0>; + }; + + pitft_ts@1 { + compatible = "st,stmpe610"; + reg = <1>; + + spi-max-frequency = <500000>; + irq-gpio = <&gpio 24 0x2>; /* IRQF_TRIGGER_FALLING */ + interrupts = <24 2>; /* high-to-low edge triggered */ + interrupt-parent = <&gpio>; + interrupt-controller; + + stmpe_touchscreen { + compatible = "st,stmpe-ts"; + st,sample-time = <4>; + st,mod-12b = <1>; + st,ref-sel = <0>; + st,adc-freq = <2>; + st,ave-ctrl = <3>; + st,touch-det-delay = <4>; + st,settling = <2>; + st,fraction-z = <7>; + st,i-drive = <0>; + }; + + stmpe_gpio: stmpe_gpio { + #gpio-cells = <2>; + compatible = "st,stmpe-gpio"; + /* + * only GPIO2 is wired/available + * and it is wired to the backlight + */ + st,norequest-mask = <0x7b>; + }; + }; + }; + }; + + fragment@5 { + target-path = "/soc"; + __overlay__ { + backlight { + compatible = "gpio-backlight"; + gpios = <&stmpe_gpio 2 0>; + default-on; + }; + }; + }; + + __overrides__ { + speed = <&pitft>,"spi-max-frequency:0"; + rotate = <&pitft>,"rotate:0"; + fps = <&pitft>,"fps:0"; + debug = <&pitft>,"debug:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts 2018-10-29 19:31:20.542783051 +0100 @@ -0,0 +1,38 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + fragment@0 { + target-path = "/"; + __overlay__ { + pps: pps@12 { + compatible = "pps-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pps_pins>; + gpios = <&gpio 18 0>; + status = "okay"; + }; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + pps_pins: pps_pins@12 { + brcm,pins = <18>; + brcm,function = <0>; // in + brcm,pull = <0>; // off + }; + }; + }; + + __overrides__ { + gpiopin = <&pps>,"gpios:4", + <&pps>,"reg:0", + <&pps_pins>,"brcm,pins:0", + <&pps_pins>,"reg:0"; + assert_falling_edge = <&pps>,"assert-falling-edge?"; + capture_clear = <&pps>,"capture-clear?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts 2018-10-29 19:31:20.542783051 +0100 @@ -0,0 +1,47 @@ +/dts-v1/; +/plugin/; + +/* +This is the 2-channel overlay - only use it if you need both channels. + +Legal pin,function combinations for each channel: + PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) + PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) + +N.B.: + 1) Pin 18 is the only one available on all platforms, and + it is the one used by the I2S audio interface. + Pins 12 and 13 might be better choices on an A+, B+ or Pi2. + 2) The onboard analogue audio output uses both PWM channels. + 3) So be careful mixing audio and PWM. +*/ + +/ { + fragment@0 { + target = <&gpio>; + __overlay__ { + pwm_pins: pwm_pins { + brcm,pins = <18 19>; + brcm,function = <2 2>; /* Alt5 */ + }; + }; + }; + + fragment@1 { + target = <&pwm>; + frag1: __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins>; + assigned-clock-rates = <100000000>; + status = "okay"; + }; + }; + + __overrides__ { + pin = <&pwm_pins>,"brcm,pins:0"; + pin2 = <&pwm_pins>,"brcm,pins:4"; + func = <&pwm_pins>,"brcm,function:0"; + func2 = <&pwm_pins>,"brcm,function:4"; + clock = <&frag1>,"assigned-clock-rates:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/pwm-ir-tx-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/pwm-ir-tx-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/pwm-ir-tx-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/pwm-ir-tx-overlay.dts 2018-10-29 19:31:20.542783051 +0100 @@ -0,0 +1,40 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&gpio>; + __overlay__ { + pwm0_pins: pwm0_pins { + brcm,pins = <18>; + brcm,function = <2>; /* Alt5 */ + }; + }; + }; + + fragment@1 { + target = <&pwm>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pins>; + status = "okay"; + }; + }; + + fragment@2 { + target-path = "/"; + __overlay__ { + pwm-ir-transmitter { + compatible = "pwm-ir-tx"; + pwms = <&pwm 0 100>; + }; + }; + }; + + __overrides__ { + gpio_pin = <&pwm0_pins>, "brcm,pins:0"; + func = <&pwm0_pins>,"brcm,function:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/pwm-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/pwm-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/pwm-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/pwm-overlay.dts 2018-10-29 19:31:20.542783051 +0100 @@ -0,0 +1,43 @@ +/dts-v1/; +/plugin/; + +/* +Legal pin,function combinations for each channel: + PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) + PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) + +N.B.: + 1) Pin 18 is the only one available on all platforms, and + it is the one used by the I2S audio interface. + Pins 12 and 13 might be better choices on an A+, B+ or Pi2. + 2) The onboard analogue audio output uses both PWM channels. + 3) So be careful mixing audio and PWM. +*/ + +/ { + fragment@0 { + target = <&gpio>; + __overlay__ { + pwm_pins: pwm_pins { + brcm,pins = <18>; + brcm,function = <2>; /* Alt5 */ + }; + }; + }; + + fragment@1 { + target = <&pwm>; + frag1: __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins>; + assigned-clock-rates = <100000000>; + status = "okay"; + }; + }; + + __overrides__ { + pin = <&pwm_pins>,"brcm,pins:0"; + func = <&pwm_pins>,"brcm,function:0"; + clock = <&frag1>,"assigned-clock-rates:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/qca7000-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/qca7000-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/qca7000-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/qca7000-overlay.dts 2018-10-29 19:31:20.542783051 +0100 @@ -0,0 +1,55 @@ +// Overlay for the Qualcomm Atheros QCA7000 on I2SE's PLC Stamp micro EVK +// Visit: https://www.i2se.com/product/plc-stamp-micro-evk for details + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@1 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + eth1: qca7000@0 { + compatible = "qca,qca7000"; + reg = <0>; /* CE0 */ + pinctrl-names = "default"; + pinctrl-0 = <ð1_pins>; + interrupt-parent = <&gpio>; + interrupts = <23 0x1>; /* rising edge */ + spi-max-frequency = <12000000>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&gpio>; + __overlay__ { + eth1_pins: eth1_pins { + brcm,pins = <23>; + brcm,function = <0>; /* in */ + brcm,pull = <0>; /* none */ + }; + }; + }; + + __overrides__ { + int_pin = <ð1>, "interrupts:0", + <ð1_pins>, "brcm,pins:0"; + speed = <ð1>, "spi-max-frequency:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/README linux-vendor/arch/arm/boot/dts/overlays/README --- linux-4.18.16/arch/arm/boot/dts/overlays/README 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/README 2018-10-29 19:31:20.519784199 +0100 @@ -0,0 +1,1987 @@ +Introduction +============ + +This directory contains Device Tree overlays. Device Tree makes it possible +to support many hardware configurations with a single kernel and without the +need to explicitly load or blacklist kernel modules. Note that this isn't a +"pure" Device Tree configuration (c.f. MACH_BCM2835) - some on-board devices +are still configured by the board support code, but the intention is to +eventually reach that goal. + +On Raspberry Pi, Device Tree usage is controlled from /boot/config.txt. By +default, the Raspberry Pi kernel boots with device tree enabled. You can +completely disable DT usage (for now) by adding: + + device_tree= + +to your config.txt, which should cause your Pi to revert to the old way of +doing things after a reboot. + +In /boot you will find a .dtb for each base platform. This describes the +hardware that is part of the Raspberry Pi board. The loader (start.elf and its +siblings) selects the .dtb file appropriate for the platform by name, and reads +it into memory. At this point, all of the optional interfaces (i2c, i2s, spi) +are disabled, but they can be enabled using Device Tree parameters: + + dtparam=i2c=on,i2s=on,spi=on + +However, this shouldn't be necessary in many use cases because loading an +overlay that requires one of those interfaces will cause it to be enabled +automatically, and it is advisable to only enable interfaces if they are +needed. + +Configuring additional, optional hardware is done using Device Tree overlays +(see below). + +GPIO numbering uses the hardware pin numbering scheme (aka BCM scheme) and +not the physical pin numbers. + +raspi-config +============ + +The Advanced Options section of the raspi-config utility can enable and disable +Device Tree use, as well as toggling the I2C and SPI interfaces. Note that it +is possible to both enable an interface and blacklist the driver, if for some +reason you should want to defer the loading. + +Modules +======= + +As well as describing the hardware, Device Tree also gives enough information +to allow suitable driver modules to be located and loaded, with the corollary +that unneeded modules are not loaded. As a result it should be possible to +remove lines from /etc/modules, and /etc/modprobe.d/raspi-blacklist.conf can +have its contents deleted (or commented out). + +Using Overlays +============== + +Overlays are loaded using the "dtoverlay" directive. As an example, consider +the popular lirc-rpi module, the Linux Infrared Remote Control driver. In the +pre-DT world this would be loaded from /etc/modules, with an explicit +"modprobe lirc-rpi" command, or programmatically by lircd. With DT enabled, +this becomes a line in config.txt: + + dtoverlay=lirc-rpi + +This causes the file /boot/overlays/lirc-rpi.dtbo to be loaded. By +default it will use GPIOs 17 (out) and 18 (in), but this can be modified using +DT parameters: + + dtoverlay=lirc-rpi,gpio_out_pin=17,gpio_in_pin=13 + +Parameters always have default values, although in some cases (e.g. "w1-gpio") +it is necessary to provided multiple overlays in order to get the desired +behaviour. See the list of overlays below for a description of the parameters +and their defaults. + +The Overlay and Parameter Reference +=================================== + +N.B. When editing this file, please preserve the indentation levels to make it +simple to parse programmatically. NO HARD TABS. + + +Name: +Info: Configures the base Raspberry Pi hardware +Load: +Params: + audio Set to "on" to enable the onboard ALSA audio + interface (default "off") + + eee Enable Energy Efficient Ethernet support for + compatible devices (default "on"). See also + "tx_lpi_timer". + + eth_led0 Set mode of LED0 (usually orange) (default + "1"). The legal values are: + 0=link/activity 1=link1000/activity + 2=link100/activity 3=link10/activity + 4=link100/1000/activity 5=link10/1000/activity + 6=link10/100/activity 14=off 15=on + + eth_led1 Set mode of LED1 (usually green) (default + "6"). See eth_led0 for legal values. + + i2c_arm Set to "on" to enable the ARM's i2c interface + (default "off") + + i2c_vc Set to "on" to enable the i2c interface + usually reserved for the VideoCore processor + (default "off") + + i2c An alias for i2c_arm + + i2c_arm_baudrate Set the baudrate of the ARM's i2c interface + (default "100000") + + i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface + (default "100000") + + i2c_baudrate An alias for i2c_arm_baudrate + + i2s Set to "on" to enable the i2s interface + (default "off") + + spi Set to "on" to enable the spi interfaces + (default "off") + + random Set to "on" to enable the hardware random + number generator (default "on") + + sd_overclock Clock (in MHz) to use when the MMC framework + requests 50MHz + + sd_force_pio Disable DMA support for SD driver (default off) + + sd_pio_limit Number of blocks above which to use DMA for + SD card (default 1) + + sd_debug Enable debug output from SD driver (default off) + + sdio_overclock Clock (in MHz) to use when the MMC framework + requests 50MHz for the SDIO/WiFi interface. + + tx_lpi_timer Set the delay in microseconds between going idle + and entering the low power state (default 600). + Requires EEE to be enabled - see "eee". + + uart0 Set to "off" to disable uart0 (default "on") + + uart1 Set to "on" or "off" to enable or disable uart1 + (default varies) + + watchdog Set to "on" to enable the hardware watchdog + (default "off") + + act_led_trigger Choose which activity the LED tracks. + Use "heartbeat" for a nice load indicator. + (default "mmc") + + act_led_activelow Set to "on" to invert the sense of the LED + (default "off") + N.B. For Pi3 see pi3-act-led overlay. + + act_led_gpio Set which GPIO to use for the activity LED + (in case you want to connect it to an external + device) + (default "16" on a non-Plus board, "47" on a + Plus or Pi 2) + N.B. For Pi3 see pi3-act-led overlay. + + pwr_led_trigger + pwr_led_activelow + pwr_led_gpio + As for act_led_*, but using the PWR LED. + Not available on Model A/B boards. + + N.B. It is recommended to only enable those interfaces that are needed. + Leaving all interfaces enabled can lead to unwanted behaviour (i2c_vc + interfering with Pi Camera, I2S and SPI hogging GPIO pins, etc.) + Note also that i2c, i2c_arm and i2c_vc are aliases for the physical + interfaces i2c0 and i2c1. Use of the numeric variants is still possible + but deprecated because the ARM/VC assignments differ between board + revisions. The same board-specific mapping applies to i2c_baudrate, + and the other i2c baudrate parameters. + + +Name: adau1977-adc +Info: Overlay for activation of ADAU1977 ADC codec over I2C for control + and I2S for data. +Load: dtoverlay=adau1977-adc +Params: + + +Name: adau7002-simple +Info: Overlay for the activation of ADAU7002 stereo PDM to I2S converter. +Load: dtoverlay=adau7002-simple,= +Params: card-name Override the default, "adau7002", card name. + + +Name: ads1015 +Info: Overlay for activation of Texas Instruments ADS1015 ADC over I2C +Load: dtoverlay=ads1015,= +Params: addr I2C bus address of device. Set based on how the + addr pin is wired. (default=0x48 assumes addr + is pulled to GND) + cha_enable Enable virtual channel a. (default=true) + cha_cfg Set the configuration for virtual channel a. + (default=4 configures this channel for the + voltage at A0 with respect to GND) + cha_datarate Set the datarate (samples/sec) for this channel. + (default=4 sets 1600 sps) + cha_gain Set the gain of the Programmable Gain + Amplifier for this channel. (default=2 sets the + full scale of the channel to 2.048 Volts) + + Channel (ch) parameters can be set for each enabled channel. + A maximum of 4 channels can be enabled (letters a thru d). + For more information refer to the device datasheet at: + http://www.ti.com/lit/ds/symlink/ads1015.pdf + + +Name: ads1115 +Info: Texas Instruments ADS1115 ADC +Load: dtoverlay=ads1115,[=] +Params: addr I2C bus address of device. Set based on how the + addr pin is wired. (default=0x48 assumes addr + is pulled to GND) + cha_enable Enable virtual channel a. + cha_cfg Set the configuration for virtual channel a. + (default=4 configures this channel for the + voltage at A0 with respect to GND) + cha_datarate Set the datarate (samples/sec) for this channel. + (default=7 sets 860 sps) + cha_gain Set the gain of the Programmable Gain + Amplifier for this channel. (Default 1 sets the + full scale of the channel to 4.096 Volts) + + Channel parameters can be set for each enabled channel. + A maximum of 4 channels can be enabled (letters a thru d). + For more information refer to the device datasheet at: + http://www.ti.com/lit/ds/symlink/ads1115.pdf + + +Name: ads7846 +Info: ADS7846 Touch controller +Load: dtoverlay=ads7846,= +Params: cs SPI bus Chip Select (default 1) + speed SPI bus speed (default 2MHz, max 3.25MHz) + penirq GPIO used for PENIRQ. REQUIRED + penirq_pull Set GPIO pull (default 0=none, 2=pullup) + swapxy Swap x and y axis + xmin Minimum value on the X axis (default 0) + ymin Minimum value on the Y axis (default 0) + xmax Maximum value on the X axis (default 4095) + ymax Maximum value on the Y axis (default 4095) + pmin Minimum reported pressure value (default 0) + pmax Maximum reported pressure value (default 65535) + xohms Touchpanel sensitivity (X-plate resistance) + (default 400) + + penirq is required and usually xohms (60-100) has to be set as well. + Apart from that, pmax (255) and swapxy are also common. + The rest of the calibration can be done with xinput-calibrator. + See: github.com/notro/fbtft/wiki/FBTFT-on-Raspian + Device Tree binding document: + www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt + + +Name: akkordion-iqdacplus +Info: Configures the Digital Dreamtime Akkordion Music Player (based on the + OEM IQAudIO DAC+ or DAC Zero module). +Load: dtoverlay=akkordion-iqdacplus,= +Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec + Digital volume control. Enable with + dtoverlay=akkordion-iqdacplus,24db_digital_gain + (The default behaviour is that the Digital + volume control is limited to a maximum of + 0dB. ie. it can attenuate but not provide + gain. For most users, this will be desired + as it will prevent clipping. By appending + the 24db_digital_gain parameter, the Digital + volume control will allow up to 24dB of + gain. If this parameter is enabled, it is the + responsibility of the user to ensure that + the Digital volume control is set to a value + that does not result in clipping/distortion!) + + +Name: allo-boss-dac-pcm512x-audio +Info: Configures the Allo Boss DAC audio cards. +Load: dtoverlay=allo-boss-dac-pcm512x-audio, +Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec + Digital volume control. Enable with + "dtoverlay=allo-boss-dac-pcm512x-audio, + 24db_digital_gain" + (The default behaviour is that the Digital + volume control is limited to a maximum of + 0dB. ie. it can attenuate but not provide + gain. For most users, this will be desired + as it will prevent clipping. By appending + the 24db_digital_gain parameter, the Digital + volume control will allow up to 24dB of + gain. If this parameter is enabled, it is the + responsibility of the user to ensure that + the Digital volume control is set to a value + that does not result in clipping/distortion!) + slave Force Boss DAC into slave mode, using Pi a + master for bit clock and frame clock. Enable + with "dtoverlay=allo-boss-dac-pcm512x-audio, + slave" + + +Name: allo-digione +Info: Configures the Allo Digione audio card +Load: dtoverlay=allo-digione +Params: + + +Name: allo-katana-dac-audio +Info: Configures the Allo Katana DAC audio card +Load: dtoverlay=allo-katana-dac-audio +Params: + + +Name: allo-piano-dac-pcm512x-audio +Info: Configures the Allo Piano DAC (2.0/2.1) audio cards. + (NB. This initial support is for 2.0 channel audio ONLY! ie. stereo. + The subwoofer outputs on the Piano 2.1 are not currently supported!) +Load: dtoverlay=allo-piano-dac-pcm512x-audio, +Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec + Digital volume control. + (The default behaviour is that the Digital + volume control is limited to a maximum of + 0dB. ie. it can attenuate but not provide + gain. For most users, this will be desired + as it will prevent clipping. By appending + the 24db_digital_gain parameter, the Digital + volume control will allow up to 24dB of + gain. If this parameter is enabled, it is the + responsibility of the user to ensure that + the Digital volume control is set to a value + that does not result in clipping/distortion!) + + +Name: allo-piano-dac-plus-pcm512x-audio +Info: Configures the Allo Piano DAC (2.1) audio cards. +Load: dtoverlay=allo-piano-dac-plus-pcm512x-audio, +Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec + Digital volume control. + (The default behaviour is that the Digital + volume control is limited to a maximum of + 0dB. ie. it can attenuate but not provide + gain. For most users, this will be desired + as it will prevent clipping. By appending + the 24db_digital_gain parameter, the Digital + volume control will allow up to 24dB of + gain. If this parameter is enabled, it is the + responsibility of the user to ensure that + the Digital volume control is set to a value + that does not result in clipping/distortion!) + glb_mclk This option is only with Kali board. If enabled, + MCLK for Kali is used and PLL is disabled for + better voice quality. (default Off) + + +Name: applepi-dac +Info: Configures the Orchard Audio ApplePi-DAC audio card +Load: dtoverlay=applepi-dac +Params: + + +Name: at86rf233 +Info: Configures the Atmel AT86RF233 802.15.4 low-power WPAN transceiver, + connected to spi0.0 +Load: dtoverlay=at86rf233,= +Params: interrupt GPIO used for INT (default 23) + reset GPIO used for Reset (default 24) + sleep GPIO used for Sleep (default 25) + speed SPI bus speed in Hz (default 3000000) + trim Fine tuning of the internal capacitance + arrays (0=+0pF, 15=+4.5pF, default 15) + + +Name: audioinjector-addons +Info: Configures the audioinjector.net audio add on soundcards +Load: dtoverlay=audioinjector-addons,= +Params: non-stop-clocks Keeps the clocks running even when the stream + is paused or stopped (default off) + + +Name: audioinjector-wm8731-audio +Info: Configures the audioinjector.net audio add on soundcard +Load: dtoverlay=audioinjector-wm8731-audio +Params: + + +Name: audremap +Info: Switches PWM sound output to pins 12 (Right) & 13 (Left) +Load: dtoverlay=audremap,= +Params: swap_lr Reverse the channel allocation, which will also + swap the audio jack outputs (default off) + enable_jack Don't switch off the audio jack output + (default off) + + +Name: balena-fin +Info: Overlay that enables WiFi, Bluetooth and the GPIO expander on the + Balena Fin board. +Load: dtoverlay=balena-fin +Params: + + +Name: bmp085_i2c-sensor +Info: This overlay is now deprecated - see i2c-sensor +Load: dtoverlay=bmp085_i2c-sensor +Params: + + +Name: dht11 +Info: Overlay for the DHT11/DHT21/DHT22 humidity/temperature sensors + Also sometimes found with the part number(s) AM230x. +Load: dtoverlay=dht11,= +Params: gpiopin GPIO connected to the sensor's DATA output. + (default 4) + + +Name: dionaudio-loco +Info: Configures the Dion Audio LOCO DAC-AMP +Load: dtoverlay=dionaudio-loco +Params: + + +Name: dionaudio-loco-v2 +Info: Configures the Dion Audio LOCO-V2 DAC-AMP +Load: dtoverlay=dionaudio-loco-v2,= +Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec + Digital volume control. Enable with + "dtoverlay=hifiberry-dacplus,24db_digital_gain" + (The default behaviour is that the Digital + volume control is limited to a maximum of + 0dB. ie. it can attenuate but not provide + gain. For most users, this will be desired + as it will prevent clipping. By appending + the 24dB_digital_gain parameter, the Digital + volume control will allow up to 24dB of + gain. If this parameter is enabled, it is the + responsibility of the user to ensure that + the Digital volume control is set to a value + that does not result in clipping/distortion!) + + +Name: dpi18 +Info: Overlay for a generic 18-bit DPI display + This uses GPIOs 0-21 (so no I2C, uart etc.), and activates the output + 2-3 seconds after the kernel has started. +Load: dtoverlay=dpi18 +Params: + + +Name: dpi24 +Info: Overlay for a generic 24-bit DPI display + This uses GPIOs 0-27 (so no I2C, uart etc.), and activates the output + 2-3 seconds after the kernel has started. +Load: dtoverlay=dpi24 +Params: + + +Name: dwc-otg +Info: Selects the dwc_otg USB controller driver which has fiq support. This + is the default on all except the Pi Zero which defaults to dwc2. +Load: dtoverlay=dwc-otg +Params: + + +Name: dwc2 +Info: Selects the dwc2 USB controller driver +Load: dtoverlay=dwc2,= +Params: dr_mode Dual role mode: "host", "peripheral" or "otg" + + g-rx-fifo-size Size of rx fifo size in gadget mode + + g-np-tx-fifo-size Size of non-periodic tx fifo size in gadget + mode + + +[ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] + + +Name: enc28j60 +Info: Overlay for the Microchip ENC28J60 Ethernet Controller on SPI0 +Load: dtoverlay=enc28j60,= +Params: int_pin GPIO used for INT (default 25) + + speed SPI bus speed (default 12000000) + + +Name: enc28j60-spi2 +Info: Overlay for the Microchip ENC28J60 Ethernet Controller on SPI2 +Load: dtoverlay=enc28j60-spi2,= +Params: int_pin GPIO used for INT (default 39) + + speed SPI bus speed (default 12000000) + + +Name: exc3000 +Info: Enables I2C connected EETI EXC3000 multiple touch controller using + GPIO 4 (pin 7 on GPIO header) for interrupt. +Load: dtoverlay=exc3000,= +Params: interrupt GPIO used for interrupt (default 4) + sizex Touchscreen size x (default 4096) + sizey Touchscreen size y (default 4096) + invx Touchscreen inverted x axis + invy Touchscreen inverted y axis + swapxy Touchscreen swapped x y axis + + +Name: fe-pi-audio +Info: Configures the Fe-Pi Audio Sound Card +Load: dtoverlay=fe-pi-audio +Params: + + +Name: goodix +Info: Enables I2C connected Goodix gt9271 multiple touch controller using + GPIOs 4 and 17 (pins 7 and 11 on GPIO header) for interrupt and reset. +Load: dtoverlay=goodix,= +Params: interrupt GPIO used for interrupt (default 4) + reset GPIO used for reset (default 17) + + +Name: googlevoicehat-soundcard +Info: Configures the Google voiceHAT soundcard +Load: dtoverlay=googlevoicehat-soundcard +Params: + + +Name: gpio-ir +Info: Use GPIO pin as rc-core style infrared receiver input. The rc-core- + based gpio_ir_recv driver maps received keys directly to a + /dev/input/event* device, all decoding is done by the kernel - LIRC is + not required! The key mapping and other decoding parameters can be + configured by "ir-keytable" tool. +Load: dtoverlay=gpio-ir,= +Params: gpio_pin Input pin number. Default is 18. + + gpio_pull Desired pull-up/down state (off, down, up) + Default is "down". + + rc-map-name Default rc keymap (can also be changed by + ir-keytable), defaults to "rc-rc6-mce" + + +Name: gpio-ir-tx +Info: Use GPIO pin as bit-banged infrared transmitter output. + This is an alternative to "pwm-ir-tx". gpio-ir-tx doesn't require + a PWM so it can be used together with onboard analog audio. +Load: dtoverlay=gpio-ir-tx,= +Params: gpio_pin Output GPIO (default 18) + + invert "1" = invert the output (make it active-low). + Default is "0" (active-high). + + +Name: gpio-key +Info: This is a generic overlay for activating GPIO keypresses using + the gpio-keys library and this dtoverlay. Multiple keys can be + set up using multiple calls to the overlay for configuring + additional buttons or joysticks. You can see available keycodes + at https://github.com/torvalds/linux/blob/v4.12/include/uapi/ + linux/input-event-codes.h#L64 +Load: dtoverlay=gpio-key,= +Params: gpio GPIO pin to trigger on (default 3) + active_low When this is 1 (active low), a falling + edge generates a key down event and a + rising edge generates a key up event. + When this is 0 (active high), this is + reversed. The default is 1 (active low) + gpio_pull Desired pull-up/down state (off, down, up) + Default is "up". Note that the default pin + (GPIO3) has an external pullup + label Set a label for the key + keycode Set the key code for the button + + +Name: gpio-no-irq +Info: Use this overlay to disable all GPIO interrupts, which can be useful + for user-space GPIO edge detection systems. +Load: dtoverlay=gpio-no-irq +Params: + + +Name: gpio-poweroff +Info: Drives a GPIO high or low on poweroff (including halt). Enabling this + overlay will prevent the ability to boot by driving GPIO3 low. +Load: dtoverlay=gpio-poweroff,= +Params: gpiopin GPIO for signalling (default 26) + + active_low Set if the power control device requires a + high->low transition to trigger a power-down. + Note that this will require the support of a + custom dt-blob.bin to prevent a power-down + during the boot process, and that a reboot + will also cause the pin to go low. + input Set if the gpio pin should be configured as + an input. + export Set to export the configured pin to sysfs + + +Name: gpio-shutdown +Info: Initiates a shutdown when GPIO pin changes. The given GPIO pin + is configured as an input key that generates KEY_POWER events. + This event is handled by systemd-logind by initiating a + shutdown. Systemd versions older than 225 need an udev rule + enable listening to the input device: + + ACTION!="REMOVE", SUBSYSTEM=="input", KERNEL=="event*", \ + SUBSYSTEMS=="platform", DRIVERS=="gpio-keys", \ + ATTRS{keys}=="116", TAG+="power-switch" + + This overlay only handles shutdown. After shutdown, the system + can be powered up again by driving GPIO3 low. The default + configuration uses GPIO3 with a pullup, so if you connect a + button between GPIO3 and GND (pin 5 and 6 on the 40-pin header), + you get a shutdown and power-up button. +Load: dtoverlay=gpio-shutdown,= +Params: gpio_pin GPIO pin to trigger on (default 3) + + active_low When this is 1 (active low), a falling + edge generates a key down event and a + rising edge generates a key up event. + When this is 0 (active high), this is + reversed. The default is 1 (active low). + + gpio_pull Desired pull-up/down state (off, down, up) + Default is "up". + + Note that the default pin (GPIO3) has an + external pullup. + + +Name: hifiberry-amp +Info: Configures the HifiBerry Amp and Amp+ audio cards +Load: dtoverlay=hifiberry-amp +Params: + + +Name: hifiberry-dac +Info: Configures the HifiBerry DAC audio card +Load: dtoverlay=hifiberry-dac +Params: + + +Name: hifiberry-dacplus +Info: Configures the HifiBerry DAC+ audio card +Load: dtoverlay=hifiberry-dacplus,= +Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec + Digital volume control. Enable with + "dtoverlay=hifiberry-dacplus,24db_digital_gain" + (The default behaviour is that the Digital + volume control is limited to a maximum of + 0dB. ie. it can attenuate but not provide + gain. For most users, this will be desired + as it will prevent clipping. By appending + the 24dB_digital_gain parameter, the Digital + volume control will allow up to 24dB of + gain. If this parameter is enabled, it is the + responsibility of the user to ensure that + the Digital volume control is set to a value + that does not result in clipping/distortion!) + slave Force DAC+ Pro into slave mode, using Pi as + master for bit clock and frame clock. + + +Name: hifiberry-dacplusadc +Info: Configures the HifiBerry DAC+ADC audio card +Load: dtoverlay=hifiberry-dacplusadc,= +Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec + Digital volume control. Enable with + "dtoverlay=hifiberry-dacplus,24db_digital_gain" + (The default behaviour is that the Digital + volume control is limited to a maximum of + 0dB. ie. it can attenuate but not provide + gain. For most users, this will be desired + as it will prevent clipping. By appending + the 24dB_digital_gain parameter, the Digital + volume control will allow up to 24dB of + gain. If this parameter is enabled, it is the + responsibility of the user to ensure that + the Digital volume control is set to a value + that does not result in clipping/distortion!) + slave Force DAC+ Pro into slave mode, using Pi as + master for bit clock and frame clock. + + +Name: hifiberry-digi +Info: Configures the HifiBerry Digi and Digi+ audio card +Load: dtoverlay=hifiberry-digi +Params: + + +Name: hifiberry-digi-pro +Info: Configures the HifiBerry Digi+ Pro audio card +Load: dtoverlay=hifiberry-digi-pro +Params: + + +Name: hy28a +Info: HY28A - 2.8" TFT LCD Display Module by HAOYU Electronics + Default values match Texy's display shield +Load: dtoverlay=hy28a,= +Params: speed Display SPI bus speed + + rotate Display rotation {0,90,180,270} + + fps Delay between frame updates + + debug Debug output level {0-7} + + xohms Touchpanel sensitivity (X-plate resistance) + + resetgpio GPIO used to reset controller + + ledgpio GPIO used to control backlight + + +Name: hy28b +Info: HY28B - 2.8" TFT LCD Display Module by HAOYU Electronics + Default values match Texy's display shield +Load: dtoverlay=hy28b,= +Params: speed Display SPI bus speed + + rotate Display rotation {0,90,180,270} + + fps Delay between frame updates + + debug Debug output level {0-7} + + xohms Touchpanel sensitivity (X-plate resistance) + + resetgpio GPIO used to reset controller + + ledgpio GPIO used to control backlight + + +Name: i2c-bcm2708 +Info: Fall back to the i2c_bcm2708 driver for the i2c_arm bus. +Load: dtoverlay=i2c-bcm2708 +Params: + + +Name: i2c-gpio +Info: Adds support for software i2c controller on gpio pins +Load: dtoverlay=i2c-gpio,= +Params: i2c_gpio_sda GPIO used for I2C data (default "23") + + i2c_gpio_scl GPIO used for I2C clock (default "24") + + i2c_gpio_delay_us Clock delay in microseconds + (default "2" = ~100kHz) + + bus Set to a unique, non-zero value if wanting + multiple i2c-gpio busses. If set, will be used + as the preferred bus number (/dev/i2c-). If + not set, the default value is 0, but the bus + number will be dynamically assigned - probably + 3. + + +Name: i2c-mux +Info: Adds support for a number of I2C bus multiplexers on i2c_arm +Load: dtoverlay=i2c-mux,= +Params: pca9542 Select the NXP PCA9542 device + + pca9545 Select the NXP PCA9545 device + + pca9548 Select the NXP PCA9548 device + + addr Change I2C address of the device (default 0x70) + + +[ The i2c-mux-pca9548a overlay has been deleted. See i2c-mux. ] + + +Name: i2c-pwm-pca9685a +Info: Adds support for an NXP PCA9685A I2C PWM controller on i2c_arm +Load: dtoverlay=i2c-pwm-pca9685a,= +Params: addr I2C address of PCA9685A (default 0x40) + + +Name: i2c-rtc +Info: Adds support for a number of I2C Real Time Clock devices +Load: dtoverlay=i2c-rtc,= +Params: abx80x Select one of the ABx80x family: + AB0801, AB0803, AB0804, AB0805, + AB1801, AB1803, AB1804, AB1805 + + ds1307 Select the DS1307 device + + ds1339 Select the DS1339 device + + ds3231 Select the DS3231 device + + m41t62 Select the M41T62 device + + mcp7940x Select the MCP7940x device + + mcp7941x Select the MCP7941x device + + pcf2127 Select the PCF2127 device + + pcf8523 Select the PCF8523 device + + pcf8563 Select the PCF8563 device + + trickle-diode-type Diode type for trickle charge - "standard" or + "schottky" (ABx80x only) + + trickle-resistor-ohms Resistor value for trickle charge (DS1339, + ABx80x) + + wakeup-source Specify that the RTC can be used as a wakeup + source + + +Name: i2c-rtc-gpio +Info: Adds support for a number of I2C Real Time Clock devices + using the software i2c controller +Load: dtoverlay=i2c-rtc-gpio,= +Params: abx80x Select one of the ABx80x family: + AB0801, AB0803, AB0804, AB0805, + AB1801, AB1803, AB1804, AB1805 + + ds1307 Select the DS1307 device + + ds1339 Select the DS1339 device + + ds3231 Select the DS3231 device + + mcp7940x Select the MCP7940x device + + mcp7941x Select the MCP7941x device + + pcf2127 Select the PCF2127 device + + pcf8523 Select the PCF8523 device + + pcf8563 Select the PCF8563 device + + trickle-diode-type Diode type for trickle charge - "standard" or + "schottky" (ABx80x only) + + trickle-resistor-ohms Resistor value for trickle charge (DS1339, + ABx80x) + + wakeup-source Specify that the RTC can be used as a wakeup + source + + i2c_gpio_sda GPIO used for I2C data (default "23") + + i2c_gpio_scl GPIO used for I2C clock (default "24") + + i2c_gpio_delay_us Clock delay in microseconds + (default "2" = ~100kHz) + + +Name: i2c-sensor +Info: Adds support for a number of I2C barometric pressure and temperature + sensors on i2c_arm +Load: dtoverlay=i2c-sensor,= +Params: addr Set the address for the BME280, BMP280, DS1621, + HDC100X, LM75, SHT3x or TMP102 + + bme280 Select the Bosch Sensortronic BME280 + Valid addresses 0x76-0x77, default 0x76 + + bmp085 Select the Bosch Sensortronic BMP085 + + bmp180 Select the Bosch Sensortronic BMP180 + + bmp280 Select the Bosch Sensortronic BMP280 + Valid addresses 0x76-0x77, default 0x76 + + ds1621 Select the Dallas Semiconductors DS1621 temp + sensor. Valid addresses 0x48-0x4f, default 0x48 + + hdc100x Select the Texas Instruments HDC100x temp sensor + Valid addresses 0x40-0x43, default 0x40 + + htu21 Select the HTU21 temperature and humidity sensor + + lm75 Select the Maxim LM75 temperature sensor + Valid addresses 0x48-0x4f, default 0x4f + + lm75addr Deprecated - use addr parameter instead + + sht3x Select the Sensiron SHT3x temperature and + humidity sensor. Valid addresses 0x44-0x45, + default 0x44 + + si7020 Select the Silicon Labs Si7013/20/21 humidity/ + temperature sensor + + tmp102 Select the Texas Instruments TMP102 temp sensor + Valid addresses 0x48-0x4b, default 0x48 + + tsl4531 Select the AMS TSL4531 digital ambient light + sensor + + veml6070 Select the Vishay VEML6070 ultraviolet light + sensor + + +Name: i2c0-bcm2708 +Info: Change i2c0 pin usage. Not all pin combinations are usable on all + platforms - platforms other then Compute Modules can only use this + to disable transaction combining. +Load: dtoverlay=i2c0-bcm2708,= +Params: sda0_pin GPIO pin for SDA0 (deprecated - use pins_*) + scl0_pin GPIO pin for SCL0 (deprecated - use pins_*) + pins_0_1 Use pins 0 and 1 (default) + pins_28_29 Use pins 28 and 29 + pins_44_45 Use pins 44 and 45 + pins_46_47 Use pins 46 and 47 + combine Allow transactions to be combined (default + "yes") + + +Name: i2c1-bcm2708 +Info: Change i2c1 pin usage. Not all pin combinations are usable on all + platforms - platforms other then Compute Modules can only use this + to disable transaction combining. +Info: Enable the i2c_bcm2708 driver for the i2c1 bus +Load: dtoverlay=i2c1-bcm2708,= +Params: sda1_pin GPIO pin for SDA1 (2 or 44 - default 2) + scl1_pin GPIO pin for SCL1 (3 or 45 - default 3) + pin_func Alternative pin function (4 (alt0), 6 (alt2) - + default 4) + combine Allow transactions to be combined (default + "yes") + + +Name: i2s-gpio28-31 +Info: move I2S function block to GPIO 28 to 31 +Load: dtoverlay=i2s-gpio28-31 +Params: + + +Name: iqaudio-dac +Info: Configures the IQaudio DAC audio card +Load: dtoverlay=iqaudio-dac, +Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec + Digital volume control. Enable with + "dtoverlay=iqaudio-dac,24db_digital_gain" + (The default behaviour is that the Digital + volume control is limited to a maximum of + 0dB. ie. it can attenuate but not provide + gain. For most users, this will be desired + as it will prevent clipping. By appending + the 24db_digital_gain parameter, the Digital + volume control will allow up to 24dB of + gain. If this parameter is enabled, it is the + responsibility of the user to ensure that + the Digital volume control is set to a value + that does not result in clipping/distortion!) + + +Name: iqaudio-dacplus +Info: Configures the IQaudio DAC+ audio card +Load: dtoverlay=iqaudio-dacplus,= +Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec + Digital volume control. Enable with + "dtoverlay=iqaudio-dacplus,24db_digital_gain" + (The default behaviour is that the Digital + volume control is limited to a maximum of + 0dB. ie. it can attenuate but not provide + gain. For most users, this will be desired + as it will prevent clipping. By appending + the 24db_digital_gain parameter, the Digital + volume control will allow up to 24dB of + gain. If this parameter is enabled, it is the + responsibility of the user to ensure that + the Digital volume control is set to a value + that does not result in clipping/distortion!) + auto_mute_amp If specified, unmute/mute the IQaudIO amp when + starting/stopping audio playback. + unmute_amp If specified, unmute the IQaudIO amp once when + the DAC driver module loads. + + +Name: iqaudio-digi-wm8804-audio +Info: Configures the IQAudIO Digi WM8804 audio card +Load: dtoverlay=iqaudio-digi-wm8804-audio,= +Params: card_name Override the default, "IQAudIODigi", card name. + dai_name Override the default, "IQAudIO Digi", dai name. + dai_stream_name Override the default, "IQAudIO Digi HiFi", + dai stream name. + + +Name: jedec-spi-nor +Info: Adds support for JEDEC-compliant SPI NOR flash devices. (Note: The + "jedec,spi-nor" kernel driver was formerly known as "m25p80".) +Load: dtoverlay=jedec-spi-nor,= +Params: flash-spi- Enables flash device on SPI, CS#. + flash-fastr-spi- Enables flash device with fast read capability + on SPI, CS#. + + +Name: justboom-dac +Info: Configures the JustBoom DAC HAT, Amp HAT, DAC Zero and Amp Zero audio + cards +Load: dtoverlay=justboom-dac,= +Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec + Digital volume control. Enable with + "dtoverlay=justboom-dac,24db_digital_gain" + (The default behaviour is that the Digital + volume control is limited to a maximum of + 0dB. ie. it can attenuate but not provide + gain. For most users, this will be desired + as it will prevent clipping. By appending + the 24dB_digital_gain parameter, the Digital + volume control will allow up to 24dB of + gain. If this parameter is enabled, it is the + responsibility of the user to ensure that + the Digital volume control is set to a value + that does not result in clipping/distortion!) + + +Name: justboom-digi +Info: Configures the JustBoom Digi HAT and Digi Zero audio cards +Load: dtoverlay=justboom-digi +Params: + + +Name: lirc-rpi +Info: Configures lirc-rpi (Linux Infrared Remote Control for Raspberry Pi) + Consult the module documentation for more details. +Load: dtoverlay=lirc-rpi,= +Params: gpio_out_pin GPIO for output (default "17") + + gpio_in_pin GPIO for input (default "18") + + gpio_in_pull Pull up/down/off on the input pin + (default "down") + + sense Override the IR receive auto-detection logic: + "0" = force active-high + "1" = force active-low + "-1" = use auto-detection + (default "-1") + + softcarrier Turn the software carrier "on" or "off" + (default "on") + + invert "on" = invert the output pin (default "off") + + debug "on" = enable additional debug messages + (default "off") + + +Name: ltc294x +Info: Adds support for the ltc294x family of battery gauges +Load: dtoverlay=ltc294x,= +Params: ltc2941 Select the ltc2941 device + + ltc2942 Select the ltc2942 device + + ltc2943 Select the ltc2943 device + + ltc2944 Select the ltc2944 device + + resistor-sense The sense resistor value in milli-ohms. + Can be a 32-bit negative value when the battery + has been connected to the wrong end of the + resistor. + + prescaler-exponent Range and accuracy of the gauge. The value is + programmed into the chip only if it differs + from the current setting. + For LTC2941 only: + - Default value is 128 + - the exponent is in the range 0-7 (default 7) + See the datasheet for more information. + + +Name: mbed-dac +Info: Configures the mbed AudioCODEC (TLV320AIC23B) +Load: dtoverlay=mbed-dac +Params: + + +Name: mcp23017 +Info: Configures the MCP23017 I2C GPIO expander +Load: dtoverlay=mcp23017,= +Params: gpiopin Gpio pin connected to the INTA output of the + MCP23017 (default: 4) + + addr I2C address of the MCP23017 (default: 0x20) + + +Name: mcp23s17 +Info: Configures the MCP23S08/17 SPI GPIO expanders. + If devices are present on SPI1 or SPI2, those interfaces must be enabled + with one of the spi1-1/2/3cs and/or spi2-1/2/3cs overlays. + If interrupts are enabled for a device on a given CS# on a SPI bus, that + device must be the only one present on that SPI bus/CS#. +Load: dtoverlay=mcp23s17,= +Params: s08-spi--present 4-bit integer, bitmap indicating MCP23S08 + devices present on SPI, CS# + + s17-spi--present 8-bit integer, bitmap indicating MCP23S17 + devices present on SPI, CS# + + s08-spi--int-gpio integer, enables interrupts on a single + MCP23S08 device on SPI, CS#, specifies + the GPIO pin to which INT output of MCP23S08 + is connected. + + s17-spi--int-gpio integer, enables mirrored interrupts on a + single MCP23S17 device on SPI, CS#, + specifies the GPIO pin to which either INTA + or INTB output of MCP23S17 is connected. + + +Name: mcp2515-can0 +Info: Configures the MCP2515 CAN controller on spi0.0 +Load: dtoverlay=mcp2515-can0,= +Params: oscillator Clock frequency for the CAN controller (Hz) + + spimaxfrequency Maximum SPI frequence (Hz) + + interrupt GPIO for interrupt signal + + +Name: mcp2515-can1 +Info: Configures the MCP2515 CAN controller on spi0.1 +Load: dtoverlay=mcp2515-can1,= +Params: oscillator Clock frequency for the CAN controller (Hz) + + spimaxfrequency Maximum SPI frequence (Hz) + + interrupt GPIO for interrupt signal + + +Name: mcp3008 +Info: Configures MCP3008 A/D converters + For devices on spi1 or spi2, the interfaces should be enabled + with one of the spi1-1/2/3cs and/or spi2-1/2/3cs overlays. +Load: dtoverlay=mcp3008,[=] +Params: spi--present boolean, configure device at spi, cs + spi--speed integer, set the spi bus speed for this device + + +Name: mcp3202 +Info: Configures MCP3202 A/D converters + For devices on spi1 or spi2, the interfaces should be enabled + with one of the spi1-1/2/3cs and/or spi2-1/2/3cs overlays. +Load: dtoverlay=mcp3202,[=] +Params: spi--present boolean, configure device at spi, cs + spi--speed integer, set the spi bus speed for this device + + +Name: media-center +Info: Media Center HAT - 2.83" Touch Display + extras by Pi Supply +Load: dtoverlay=media-center,= +Params: speed Display SPI bus speed + rotate Display rotation {0,90,180,270} + fps Delay between frame updates + xohms Touchpanel sensitivity (X-plate resistance) + swapxy Swap x and y axis + backlight Change backlight GPIO pin {e.g. 12, 18} + gpio_out_pin GPIO for output (default "17") + gpio_in_pin GPIO for input (default "18") + gpio_in_pull Pull up/down/off on the input pin + (default "down") + sense Override the IR receive auto-detection logic: + "0" = force active-high + "1" = force active-low + "-1" = use auto-detection + (default "-1") + softcarrier Turn the software carrier "on" or "off" + (default "on") + invert "on" = invert the output pin (default "off") + debug "on" = enable additional debug messages + (default "off") + + +Name: midi-uart0 +Info: Configures UART0 (ttyAMA0) so that a requested 38.4kbaud actually gets + 31.25kbaud, the frequency required for MIDI +Load: dtoverlay=midi-uart0 +Params: + + +Name: midi-uart1 +Info: Configures UART1 (ttyS0) so that a requested 38.4kbaud actually gets + 31.25kbaud, the frequency required for MIDI +Load: dtoverlay=midi-uart1 +Params: + + +Name: mmc +Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock +Load: dtoverlay=mmc,= +Params: overclock_50 Clock (in MHz) to use when the MMC framework + requests 50MHz + + +Name: mpu6050 +Info: Overlay for i2c connected mpu6050 imu +Load: dtoverlay=mpu6050,= +Params: interrupt GPIO pin for interrupt (default 4) + + +Name: mz61581 +Info: MZ61581 display by Tontec +Load: dtoverlay=mz61581,= +Params: speed Display SPI bus speed + + rotate Display rotation {0,90,180,270} + + fps Delay between frame updates + + txbuflen Transmit buffer length (default 32768) + + debug Debug output level {0-7} + + xohms Touchpanel sensitivity (X-plate resistance) + + +Name: papirus +Info: PaPiRus ePaper Screen by Pi Supply (both HAT and pHAT) +Load: dtoverlay=papirus,= +Params: panel Display panel (required): + 1.44": e1144cs021 + 2.0": e2200cs021 + 2.7": e2271cs021 + + speed Display SPI bus speed + + +[ The pcf2127-rtc overlay has been deleted. See i2c-rtc. ] + + +[ The pcf8523-rtc overlay has been deleted. See i2c-rtc. ] + + +[ The pcf8563-rtc overlay has been deleted. See i2c-rtc. ] + + +Name: pi3-act-led +Info: Pi3 uses a GPIO expander to drive the LEDs which can only be accessed + from the VPU. There is a special driver for this with a separate DT + node, which has the unfortunate consequence of breaking the + act_led_gpio and act_led_activelow dtparams. + This overlay changes the GPIO controller back to the standard one and + restores the dtparams. +Load: dtoverlay=pi3-act-led,= +Params: activelow Set to "on" to invert the sense of the LED + (default "off") + + gpio Set which GPIO to use for the activity LED + (in case you want to connect it to an external + device) + REQUIRED + + +Name: pi3-disable-bt +Info: Disable Pi3 Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15 + N.B. To disable the systemd service that initialises the modem so it + doesn't use the UART, use 'sudo systemctl disable hciuart'. +Load: dtoverlay=pi3-disable-bt +Params: + + +Name: pi3-disable-wifi +Info: Disable Pi3 onboard WiFi +Load: dtoverlay=pi3-disable-wifi +Params: + + +Name: pi3-miniuart-bt +Info: Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore + UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum + usable baudrate. + N.B. It is also necessary to edit /lib/systemd/system/hciuart.service + and replace ttyAMA0 with ttyS0, unless you have a system with udev rules + that create /dev/serial0 and /dev/serial1, in which case use + /dev/serial1 instead because it will always be correct. Furthermore, + you must also set core_freq=250 in config.txt or the miniuart will not + work. +Load: dtoverlay=pi3-miniuart-bt +Params: + + +Name: pibell +Info: Configures the pibell audio card. +Load: dtoverlay=pibell,= +Params: alsaname Set the name as it appears in ALSA (default + "PiBell") + + +Name: piscreen +Info: PiScreen display by OzzMaker.com +Load: dtoverlay=piscreen,= +Params: speed Display SPI bus speed + + rotate Display rotation {0,90,180,270} + + fps Delay between frame updates + + debug Debug output level {0-7} + + xohms Touchpanel sensitivity (X-plate resistance) + + +Name: piscreen2r +Info: PiScreen 2 with resistive TP display by OzzMaker.com +Load: dtoverlay=piscreen2r,= +Params: speed Display SPI bus speed + + rotate Display rotation {0,90,180,270} + + fps Delay between frame updates + + debug Debug output level {0-7} + + xohms Touchpanel sensitivity (X-plate resistance) + + +Name: pisound +Info: Configures the Blokas Labs pisound card +Load: dtoverlay=pisound +Params: + + +Name: pitft22 +Info: Adafruit PiTFT 2.2" screen +Load: dtoverlay=pitft22,= +Params: speed Display SPI bus speed + + rotate Display rotation {0,90,180,270} + + fps Delay between frame updates + + debug Debug output level {0-7} + + +Name: pitft28-capacitive +Info: Adafruit PiTFT 2.8" capacitive touch screen +Load: dtoverlay=pitft28-capacitive,= +Params: speed Display SPI bus speed + + rotate Display rotation {0,90,180,270} + + fps Delay between frame updates + + debug Debug output level {0-7} + + touch-sizex Touchscreen size x (default 240) + + touch-sizey Touchscreen size y (default 320) + + touch-invx Touchscreen inverted x axis + + touch-invy Touchscreen inverted y axis + + touch-swapxy Touchscreen swapped x y axis + + +Name: pitft28-resistive +Info: Adafruit PiTFT 2.8" resistive touch screen +Load: dtoverlay=pitft28-resistive,= +Params: speed Display SPI bus speed + + rotate Display rotation {0,90,180,270} + + fps Delay between frame updates + + debug Debug output level {0-7} + + +Name: pitft35-resistive +Info: Adafruit PiTFT 3.5" resistive touch screen +Load: dtoverlay=pitft35-resistive,= +Params: speed Display SPI bus speed + + rotate Display rotation {0,90,180,270} + + fps Delay between frame updates + + debug Debug output level {0-7} + + +Name: pps-gpio +Info: Configures the pps-gpio (pulse-per-second time signal via GPIO). +Load: dtoverlay=pps-gpio,= +Params: gpiopin Input GPIO (default "18") + assert_falling_edge When present, assert is indicated by a falling + edge, rather than by a rising edge (default + off) + capture_clear Generate clear events on the trailing edge + (default off) + + +Name: pwm +Info: Configures a single PWM channel + Legal pin,function combinations for each channel: + PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) + PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) + N.B.: + 1) Pin 18 is the only one available on all platforms, and + it is the one used by the I2S audio interface. + Pins 12 and 13 might be better choices on an A+, B+ or Pi2. + 2) The onboard analogue audio output uses both PWM channels. + 3) So be careful mixing audio and PWM. + 4) Currently the clock must have been enabled and configured + by other means. +Load: dtoverlay=pwm,= +Params: pin Output pin (default 18) - see table + func Pin function (default 2 = Alt5) - see above + clock PWM clock frequency (informational) + + +Name: pwm-2chan +Info: Configures both PWM channels + Legal pin,function combinations for each channel: + PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) + PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1) + N.B.: + 1) Pin 18 is the only one available on all platforms, and + it is the one used by the I2S audio interface. + Pins 12 and 13 might be better choices on an A+, B+ or Pi2. + 2) The onboard analogue audio output uses both PWM channels. + 3) So be careful mixing audio and PWM. + 4) Currently the clock must have been enabled and configured + by other means. +Load: dtoverlay=pwm-2chan,= +Params: pin Output pin (default 18) - see table + pin2 Output pin for other channel (default 19) + func Pin function (default 2 = Alt5) - see above + func2 Function for pin2 (default 2 = Alt5) + clock PWM clock frequency (informational) + + +Name: pwm-ir-tx +Info: Use GPIO pin as pwm-assisted infrared transmitter output. + This is an alternative to "gpio-ir-tx". pwm-ir-tx makes use + of PWM0 to reduce the CPU load during transmission compared to + gpio-ir-tx which uses bit-banging. + Legal pin,function combinations are: + 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1) +Load: dtoverlay=pwm-ir-tx,= +Params: gpio_pin Output GPIO (default 18) + + func Pin function (default 2 = Alt5) + + +Name: qca7000 +Info: I2SE's Evaluation Board for PLC Stamp micro +Load: dtoverlay=qca7000,= +Params: int_pin GPIO pin for interrupt signal (default 23) + + speed SPI bus speed (default 12 MHz) + + +Name: rotary-encoder +Info: Overlay for GPIO connected rotary encoder. +Load: dtoverlay=rotary-encoder,= +Params: pin_a GPIO connected to rotary encoder channel A + (default 4). + pin_b GPIO connected to rotary encoder channel B + (default 17). + relative_axis register a relative axis rather than an + absolute one. Relative axis will only + generate +1/-1 events on the input device, + hence no steps need to be passed. + linux_axis the input subsystem axis to map to this + rotary encoder. Defaults to 0 (ABS_X / REL_X) + rollover Automatic rollover when the rotary value + becomes greater than the specified steps or + smaller than 0. For absolute axis only. + steps-per-period Number of steps (stable states) per period. + The values have the following meaning: + 1: Full-period mode (default) + 2: Half-period mode + 4: Quarter-period mode + steps Number of steps in a full turnaround of the + encoder. Only relevant for absolute axis. + Defaults to 24 which is a typical value for + such devices. + wakeup Boolean, rotary encoder can wake up the + system. + encoding String, the method used to encode steps. + Supported are "gray" (the default and more + common) and "binary". + + +Name: rpi-backlight +Info: Raspberry Pi official display backlight driver +Load: dtoverlay=rpi-backlight +Params: + + +Name: rpi-cirrus-wm5102 +Info: Configures the Cirrus Logic Audio Card +Load: dtoverlay=rpi-cirrus-wm5102 +Params: + + +Name: rpi-dac +Info: Configures the RPi DAC audio card +Load: dtoverlay=rpi-dac +Params: + + +Name: rpi-display +Info: RPi-Display - 2.8" Touch Display by Watterott +Load: dtoverlay=rpi-display,= +Params: speed Display SPI bus speed + rotate Display rotation {0,90,180,270} + fps Delay between frame updates + debug Debug output level {0-7} + xohms Touchpanel sensitivity (X-plate resistance) + swapxy Swap x and y axis + backlight Change backlight GPIO pin {e.g. 12, 18} + + +Name: rpi-ft5406 +Info: Official Raspberry Pi display touchscreen +Load: dtoverlay=rpi-ft5406,= +Params: touchscreen-size-x Touchscreen X resolution (default 800) + touchscreen-size-y Touchscreen Y resolution (default 600); + touchscreen-inverted-x Invert touchscreen X coordinates (default 0); + touchscreen-inverted-y Invert touchscreen Y coordinates (default 0); + touchscreen-swapped-x-y Swap X and Y cordinates (default 0); + + +Name: rpi-poe +Info: Raspberry Pi POE HAT +Load: dtoverlay=rpi-poe +Params: + + +Name: rpi-proto +Info: Configures the RPi Proto audio card +Load: dtoverlay=rpi-proto +Params: + + +Name: rpi-sense +Info: Raspberry Pi Sense HAT +Load: dtoverlay=rpi-sense +Params: + + +Name: rpi-tv +Info: Raspberry Pi TV HAT +Load: dtoverlay=rpi-tv +Params: + + +Name: rra-digidac1-wm8741-audio +Info: Configures the Red Rocks Audio DigiDAC1 soundcard +Load: dtoverlay=rra-digidac1-wm8741-audio +Params: + + +Name: sc16is750-i2c +Info: Overlay for the NXP SC16IS750 UART with I2C Interface + Enables the chip on I2C1 at 0x48 (or the "addr" parameter value). To + select another address, please refer to table 10 in reference manual. +Load: dtoverlay=sc16is750-i2c,= +Params: int_pin GPIO used for IRQ (default 24) + addr Address (default 0x48) + + +Name: sc16is752-i2c +Info: Overlay for the NXP SC16IS752 dual UART with I2C Interface + Enables the chip on I2C1 at 0x48 (or the "addr" parameter value). To + select another address, please refer to table 10 in reference manual. +Load: dtoverlay=sc16is752-i2c,= +Params: int_pin GPIO used for IRQ (default 24) + addr Address (default 0x48) + xtal On-board crystal frequency (default 14745600) + + +Name: sc16is752-spi1 +Info: Overlay for the NXP SC16IS752 Dual UART with SPI Interface + Enables the chip on SPI1. + N.B.: spi1 is only accessible on devices with a 40pin header, eg: + A+, B+, Zero and PI2 B; as well as the Compute Module. + +Load: dtoverlay=sc16is752-spi1,= +Params: int_pin GPIO used for IRQ (default 24) + + +Name: sdhost +Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock. + N.B. This overlay is designed for situations where the mmc driver is + the default, so it disables the other (mmc) interface - this will kill + WiFi on a Pi3. If this isn't what you want, either use the sdtweak + overlay or the new sd_* dtparams of the base DTBs. +Load: dtoverlay=sdhost,= +Params: overclock_50 Clock (in MHz) to use when the MMC framework + requests 50MHz + + force_pio Disable DMA support (default off) + + pio_limit Number of blocks above which to use DMA + (default 1) + + debug Enable debug output (default off) + + +Name: sdio +Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, + and enables SDIO via GPIOs 22-27. +Load: dtoverlay=sdio,= +Params: sdio_overclock SDIO Clock (in MHz) to use when the MMC + framework requests 50MHz + + poll_once Disable SDIO-device polling every second + (default on: polling once at boot-time) + + bus_width Set the SDIO host bus width (default 4 bits) + + +Name: sdio-1bit +Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, + and enables 1-bit SDIO via GPIOs 22-25. +Load: dtoverlay=sdio-1bit,= +Params: sdio_overclock SDIO Clock (in MHz) to use when the MMC + framework requests 50MHz + + poll_once Disable SDIO-device polling every second + (default on: polling once at boot-time) + + +Name: sdtweak +Info: Tunes the bcm2835-sdhost SD/MMC driver + N.B. This functionality is now available via the sd_* dtparams in the + base DTB. +Load: dtoverlay=sdtweak,= +Params: overclock_50 Clock (in MHz) to use when the MMC framework + requests 50MHz + + force_pio Disable DMA support (default off) + + pio_limit Number of blocks above which to use DMA + (default 1) + + debug Enable debug output (default off) + + poll_once Looks for a card once after booting. Useful + for network booting scenarios to avoid the + overhead of continuous polling. N.B. Using + this option restricts the system to using a + single card per boot (or none at all). + (default off) + + enable Set to off to completely disable the interface + (default on) + + +Name: smi +Info: Enables the Secondary Memory Interface peripheral. Uses GPIOs 2-25! +Load: dtoverlay=smi +Params: + + +Name: smi-dev +Info: Enables the userspace interface for the SMI driver +Load: dtoverlay=smi-dev +Params: + + +Name: smi-nand +Info: Enables access to NAND flash via the SMI interface +Load: dtoverlay=smi-nand +Params: + + +Name: spi-gpio35-39 +Info: Move SPI function block to GPIO 35 to 39 +Load: dtoverlay=spi-gpio35-39 +Params: + + +Name: spi-rtc +Info: Adds support for a number of SPI Real Time Clock devices +Load: dtoverlay=spi-rtc,= +Params: pcf2123 Select the PCF2123 device + + +Name: spi0-cs +Info: Allows the (software) CS pins for SPI0 to be changed +Load: dtoverlay=spi0-cs,= +Params: cs0_pin GPIO pin for CS0 (default 8) + cs1_pin GPIO pin for CS1 (default 7) + + +Name: spi0-hw-cs +Info: Re-enables hardware CS/CE (chip selects) for SPI0 +Load: dtoverlay=spi0-hw-cs +Params: + + +Name: spi1-1cs +Info: Enables spi1 with a single chip select (CS) line and associated spidev + dev node. The gpio pin number for the CS line and spidev device node + creation are configurable. + N.B.: spi1 is only accessible on devices with a 40pin header, eg: + A+, B+, Zero and PI2 B; as well as the Compute Module. +Load: dtoverlay=spi1-1cs,= +Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). + cs0_spidev Set to 'disabled' to stop the creation of a + userspace device node /dev/spidev1.0 (default + is 'okay' or enabled). + + +Name: spi1-2cs +Info: Enables spi1 with two chip select (CS) lines and associated spidev + dev nodes. The gpio pin numbers for the CS lines and spidev device node + creation are configurable. + N.B.: spi1 is only accessible on devices with a 40pin header, eg: + A+, B+, Zero and PI2 B; as well as the Compute Module. +Load: dtoverlay=spi1-2cs,= +Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). + cs1_pin GPIO pin for CS1 (default 17 - BCM SPI1_CE1). + cs0_spidev Set to 'disabled' to stop the creation of a + userspace device node /dev/spidev1.0 (default + is 'okay' or enabled). + cs1_spidev Set to 'disabled' to stop the creation of a + userspace device node /dev/spidev1.1 (default + is 'okay' or enabled). + + +Name: spi1-3cs +Info: Enables spi1 with three chip select (CS) lines and associated spidev + dev nodes. The gpio pin numbers for the CS lines and spidev device node + creation are configurable. + N.B.: spi1 is only accessible on devices with a 40pin header, eg: + A+, B+, Zero and PI2 B; as well as the Compute Module. +Load: dtoverlay=spi1-3cs,= +Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). + cs1_pin GPIO pin for CS1 (default 17 - BCM SPI1_CE1). + cs2_pin GPIO pin for CS2 (default 16 - BCM SPI1_CE2). + cs0_spidev Set to 'disabled' to stop the creation of a + userspace device node /dev/spidev1.0 (default + is 'okay' or enabled). + cs1_spidev Set to 'disabled' to stop the creation of a + userspace device node /dev/spidev1.1 (default + is 'okay' or enabled). + cs2_spidev Set to 'disabled' to stop the creation of a + userspace device node /dev/spidev1.2 (default + is 'okay' or enabled). + + +Name: spi2-1cs +Info: Enables spi2 with a single chip select (CS) line and associated spidev + dev node. The gpio pin number for the CS line and spidev device node + creation are configurable. + N.B.: spi2 is only accessible with the Compute Module. +Load: dtoverlay=spi2-1cs,= +Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). + cs0_spidev Set to 'disabled' to stop the creation of a + userspace device node /dev/spidev2.0 (default + is 'okay' or enabled). + + +Name: spi2-2cs +Info: Enables spi2 with two chip select (CS) lines and associated spidev + dev nodes. The gpio pin numbers for the CS lines and spidev device node + creation are configurable. + N.B.: spi2 is only accessible with the Compute Module. +Load: dtoverlay=spi2-2cs,= +Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). + cs1_pin GPIO pin for CS1 (default 44 - BCM SPI2_CE1). + cs0_spidev Set to 'disabled' to stop the creation of a + userspace device node /dev/spidev2.0 (default + is 'okay' or enabled). + cs1_spidev Set to 'disabled' to stop the creation of a + userspace device node /dev/spidev2.1 (default + is 'okay' or enabled). + + +Name: spi2-3cs +Info: Enables spi2 with three chip select (CS) lines and associated spidev + dev nodes. The gpio pin numbers for the CS lines and spidev device node + creation are configurable. + N.B.: spi2 is only accessible with the Compute Module. +Load: dtoverlay=spi2-3cs,= +Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). + cs1_pin GPIO pin for CS1 (default 44 - BCM SPI2_CE1). + cs2_pin GPIO pin for CS2 (default 45 - BCM SPI2_CE2). + cs0_spidev Set to 'disabled' to stop the creation of a + userspace device node /dev/spidev2.0 (default + is 'okay' or enabled). + cs1_spidev Set to 'disabled' to stop the creation of a + userspace device node /dev/spidev2.1 (default + is 'okay' or enabled). + cs2_spidev Set to 'disabled' to stop the creation of a + userspace device node /dev/spidev2.2 (default + is 'okay' or enabled). + + +Name: superaudioboard +Info: Configures the SuperAudioBoard sound card +Load: dtoverlay=superaudioboard,= +Params: gpiopin GPIO pin for codec reset + + +Name: sx150x +Info: Configures the Semtech SX150X I2C GPIO expanders. +Load: dtoverlay=sx150x,= +Params: sx150-- Enables SX150X device on I2C# with slave + address . may be 1-9. may be 0 or 1. + Permissible values of (which is denoted in + hex) depend on the device variant. For SX1501, + SX1502, SX1504 and SX1505, may be 20 or 21. + For SX1503 and SX1506, may be 20. For + SX1507 and SX1509, may be 3E, 3F, 70 or 71. + For SX1508, may be 20, 21, 22 or 23. + + sx150---int-gpio + Integer, enables interrupts on SX150X device on + I2C# with slave address , specifies + the GPIO pin to which NINT output of SX150X is + connected. + + +Name: tinylcd35 +Info: 3.5" Color TFT Display by www.tinylcd.com + Options: Touch, RTC, keypad +Load: dtoverlay=tinylcd35,= +Params: speed Display SPI bus speed + + rotate Display rotation {0,90,180,270} + + fps Delay between frame updates + + debug Debug output level {0-7} + + touch Enable touch panel + + touchgpio Touch controller IRQ GPIO + + xohms Touchpanel: Resistance of X-plate in ohms + + rtc-pcf PCF8563 Real Time Clock + + rtc-ds DS1307 Real Time Clock + + keypad Enable keypad + + Examples: + Display with touchpanel, PCF8563 RTC and keypad: + dtoverlay=tinylcd35,touch,rtc-pcf,keypad + Old touch display: + dtoverlay=tinylcd35,touch,touchgpio=3 + + +Name: tpm-slb9670 +Info: Enables support for Infineon SLB9670 Trusted Platform Module add-on + boards, which can be used as a secure key storage and hwrng, + available as "Iridium SLB9670" by Infineon and "LetsTrust TPM" by pi3g. +Load: dtoverlay=tpm-slb9670 +Params: + + +Name: uart0 +Info: Change the pin usage of uart0 +Load: dtoverlay=uart0,= +Params: txd0_pin GPIO pin for TXD0 (14, 32 or 36 - default 14) + + rxd0_pin GPIO pin for RXD0 (15, 33 or 37 - default 15) + + pin_func Alternative pin function - 4(Alt0) for 14&15, + 7(Alt3) for 32&33, 6(Alt2) for 36&37 + + +Name: uart1 +Info: Change the pin usage of uart1 +Load: dtoverlay=uart1,= +Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) + + rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) + + +Name: upstream +Info: Allow usage of downstream .dtb with upstream kernel. Comprises + vc4-kms-v3d, dwc2 and upstream-aux-interrupt overlays. +Load: dtoverlay=upstream +Params: + + +Name: upstream-aux-interrupt +Info: Allow usage of downstream .dtb with upstream kernel by binding AUX + devices directly to the shared AUX interrupt line. One of the parts + of the 'upstream' overlay +Load: dtoverlay=upstream-aux-interrupt +Params: + + +Name: vc4-fkms-v3d +Info: Enable Eric Anholt's DRM VC4 V3D driver on top of the dispmanx + display stack. +Load: dtoverlay=vc4-fkms-v3d, +Params: cma-256 CMA is 256MB, 256MB-aligned (needs 1GB) + cma-192 CMA is 192MB, 256MB-aligned (needs 1GB) + cma-128 CMA is 128MB, 128MB-aligned + cma-96 CMA is 96MB, 128MB-aligned + cma-64 CMA is 64MB, 64MB-aligned + + +Name: vc4-kms-v3d +Info: Enable Eric Anholt's DRM VC4 HDMI/HVS/V3D driver. Running startx or + booting to GUI while this overlay is in use will cause interesting + lockups. +Load: dtoverlay=vc4-kms-v3d, +Params: cma-256 CMA is 256MB, 256MB-aligned (needs 1GB) + cma-192 CMA is 192MB, 256MB-aligned (needs 1GB) + cma-128 CMA is 128MB, 128MB-aligned + cma-96 CMA is 96MB, 128MB-aligned + cma-64 CMA is 64MB, 64MB-aligned + + +Name: vga666 +Info: Overlay for the Fen Logic VGA666 board + This uses GPIOs 2-21 (so no I2C), and activates the output 2-3 seconds + after the kernel has started. +Load: dtoverlay=vga666 +Params: + + +Name: w1-gpio +Info: Configures the w1-gpio Onewire interface module. + Use this overlay if you *don't* need a GPIO to drive an external pullup. +Load: dtoverlay=w1-gpio,= +Params: gpiopin GPIO for I/O (default "4") + + pullup Non-zero, "on", or "y" to enable the parasitic + power (2-wire, power-on-data) feature + + +Name: w1-gpio-pullup +Info: Configures the w1-gpio Onewire interface module. + Use this overlay if you *do* need a GPIO to drive an external pullup. +Load: dtoverlay=w1-gpio-pullup,= +Params: gpiopin GPIO for I/O (default "4") + + pullup Non-zero, "on", or "y" to enable the parasitic + power (2-wire, power-on-data) feature + + extpullup GPIO for external pullup (default "5") + + +Name: wittypi +Info: Configures the wittypi RTC module. +Load: dtoverlay=wittypi,= +Params: led_gpio GPIO for LED (default "17") + led_trigger Choose which activity the LED tracks (default + "default-on") + + +Troubleshooting +=============== + +If you are experiencing problems that you think are DT-related, enable DT +diagnostic output by adding this to /boot/config.txt: + + dtdebug=on + +and rebooting. Then run: + + sudo vcdbg log msg + +and look for relevant messages. + +Further reading +=============== + +This is only meant to be a quick introduction to the subject of Device Tree on +Raspberry Pi. There is a more complete explanation here: + +http://www.raspberrypi.org/documentation/configuration/device-tree.md diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/rotary-encoder-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/rotary-encoder-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/rotary-encoder-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/rotary-encoder-overlay.dts 2018-10-29 19:31:20.542783051 +0100 @@ -0,0 +1,59 @@ +// Device tree overlay for GPIO connected rotary encoder. +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&gpio>; + __overlay__ { + rotary_pins: rotary_pins@4 { + brcm,pins = <4 17>; /* gpio 4 17 */ + brcm,function = <0 0>; /* input */ + brcm,pull = <2 2>; /* pull-up */ + }; + + }; + }; + + fragment@1 { + target-path = "/"; + __overlay__ { + rotary: rotary@4 { + compatible = "rotary-encoder"; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&rotary_pins>; + gpios = <&gpio 4 0>, <&gpio 17 0>; + linux,axis = <0>; /* REL_X */ + rotary-encoder,encoding = "gray"; + rotary-encoder,steps = <24>; /* 24 default */ + rotary-encoder,steps-per-period = <1>; /* corresponds to full period mode. See README */ + }; + }; + + }; + + __overrides__ { + pin_a = <&rotary>,"gpios:4", + <&rotary_pins>,"brcm,pins:0", + /* modify reg values to allow multiple instantiation */ + <&rotary>,"reg:0", + <&rotary_pins>,"reg:0"; + pin_b = <&rotary>,"gpios:16", + <&rotary_pins>,"brcm,pins:4"; + relative_axis = <&rotary>,"rotary-encoder,relative-axis?"; + linux_axis = <&rotary>,"linux,axis:0"; + rollover = <&rotary>,"rotary-encoder,rollover?"; + steps-per-period = <&rotary>,"rotary-encoder,steps-per-period:0"; + steps = <&rotary>,"rotary-encoder,steps:0"; + wakeup = <&rotary>,"wakeup-source?"; + encoding = <&rotary>,"rotary-encoder,encoding"; + /* legacy parameters*/ + rotary0_pin_a = <&rotary>,"gpios:4", + <&rotary_pins>,"brcm,pins:0"; + rotary0_pin_b = <&rotary>,"gpios:16", + <&rotary_pins>,"brcm,pins:4"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts 2018-10-29 19:31:20.543783001 +0100 @@ -0,0 +1,21 @@ +/* + * Devicetree overlay for mailbox-driven Raspberry Pi DSI Display + * backlight controller + */ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/"; + __overlay__ { + rpi_backlight: rpi_backlight { + compatible = "raspberrypi,rpi-backlight"; + firmware = <&firmware>; + status = "okay"; + }; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/rpi-cirrus-wm5102-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/rpi-cirrus-wm5102-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/rpi-cirrus-wm5102-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/rpi-cirrus-wm5102-overlay.dts 2018-10-29 19:31:20.543783001 +0100 @@ -0,0 +1,152 @@ +// Definitions for the Cirrus Logic Audio Card +/dts-v1/; +/plugin/; +#include +#include +#include + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + wlf_pins: wlf_pins { + brcm,pins = <17 22 27 8>; + brcm,function = < + BCM2835_FSEL_GPIO_OUT + BCM2835_FSEL_GPIO_OUT + BCM2835_FSEL_GPIO_IN + BCM2835_FSEL_GPIO_OUT + >; + }; + }; + }; + + fragment@2 { + target-path = "/"; + __overlay__ { + rpi_cirrus_reg_1v8: rpi_cirrus_reg_1v8 { + compatible = "regulator-fixed"; + regulator-name = "RPi-Cirrus 1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + }; + }; + + fragment@3 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@4 { + target = <&spidev1>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@5 { + target = <&spi0>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + wm5102@1{ + compatible = "wlf,wm5102"; + reg = <1>; + + spi-max-frequency = <500000>; + + interrupt-parent = <&gpio>; + interrupts = <27 8>; + interrupt-controller; + #interrupt-cells = <2>; + + gpio-controller; + #gpio-cells = <2>; + + LDOVDD-supply = <&rpi_cirrus_reg_1v8>; + AVDD-supply = <&rpi_cirrus_reg_1v8>; + DBVDD1-supply = <&rpi_cirrus_reg_1v8>; + DBVDD2-supply = <&vdd_3v3_reg>; + DBVDD3-supply = <&vdd_3v3_reg>; + CPVDD-supply = <&rpi_cirrus_reg_1v8>; + SPKVDDL-supply = <&vdd_5v0_reg>; + SPKVDDR-supply = <&vdd_5v0_reg>; + DCVDD-supply = <&arizona_ldo1>; + + wlf,reset = <&gpio 17 GPIO_ACTIVE_HIGH>; + wlf,ldoena = <&gpio 22 GPIO_ACTIVE_HIGH>; + wlf,gpio-defaults = < + ARIZONA_GP_DEFAULT + ARIZONA_GP_DEFAULT + ARIZONA_GP_DEFAULT + ARIZONA_GP_DEFAULT + ARIZONA_GP_DEFAULT + >; + wlf,micd-configs = <0 1 0>; + wlf,dmic-ref = < + ARIZONA_DMIC_MICVDD + ARIZONA_DMIC_MICBIAS2 + ARIZONA_DMIC_MICVDD + ARIZONA_DMIC_MICVDD + >; + wlf,inmode = < + ARIZONA_INMODE_DIFF + ARIZONA_INMODE_DMIC + ARIZONA_INMODE_SE + ARIZONA_INMODE_DIFF + >; + status = "okay"; + + arizona_ldo1: ldo1 { + regulator-name = "LDO1"; + // default constraints as in + // arizona-ldo1.c + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1800000>; + }; + }; + }; + }; + + fragment@6 { + target = <&i2c1>; + __overlay__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + wm8804@3b { + compatible = "wlf,wm8804"; + reg = <0x3b>; + status = "okay"; + PVDD-supply = <&vdd_3v3_reg>; + DVDD-supply = <&vdd_3v3_reg>; + wlf,reset-gpio = <&gpio 8 GPIO_ACTIVE_HIGH>; + }; + }; + }; + + fragment@7 { + target = <&sound>; + __overlay__ { + compatible = "wlf,rpi-cirrus"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts 2018-10-29 19:31:20.543783001 +0100 @@ -0,0 +1,34 @@ +// Definitions for RPi DAC +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target-path = "/"; + __overlay__ { + pcm1794a-codec { + #sound-dai-cells = <0>; + compatible = "ti,pcm1794a"; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "rpi,rpi-dac"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/rpi-display-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/rpi-display-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/rpi-display-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/rpi-display-overlay.dts 2018-10-29 19:31:20.543783001 +0100 @@ -0,0 +1,91 @@ +/* + * Device Tree overlay for rpi-display by Watterott + * + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&spidev1>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@3 { + target = <&gpio>; + __overlay__ { + rpi_display_pins: rpi_display_pins { + brcm,pins = <18 23 24 25>; + brcm,function = <1 1 1 0>; /* out out out in */ + brcm,pull = <0 0 0 2>; /* - - - up */ + }; + }; + }; + + fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + rpidisplay: rpi-display@0{ + compatible = "ilitek,ili9341"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&rpi_display_pins>; + + spi-max-frequency = <32000000>; + rotate = <270>; + bgr; + fps = <30>; + buswidth = <8>; + reset-gpios = <&gpio 23 0>; + dc-gpios = <&gpio 24 0>; + led-gpios = <&gpio 18 1>; + debug = <0>; + }; + + rpidisplay_ts: rpi-display-ts@1 { + compatible = "ti,ads7846"; + reg = <1>; + + spi-max-frequency = <2000000>; + interrupts = <25 2>; /* high-to-low edge triggered */ + interrupt-parent = <&gpio>; + pendown-gpio = <&gpio 25 0>; + ti,x-plate-ohms = /bits/ 16 <60>; + ti,pressure-max = /bits/ 16 <255>; + }; + }; + }; + __overrides__ { + speed = <&rpidisplay>,"spi-max-frequency:0"; + rotate = <&rpidisplay>,"rotate:0"; + fps = <&rpidisplay>,"fps:0"; + debug = <&rpidisplay>,"debug:0"; + xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; + swapxy = <&rpidisplay_ts>,"ti,swap-xy?"; + backlight = <&rpidisplay>,"led-gpios:4", + <&rpi_display_pins>,"brcm,pins:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts 2018-10-29 19:31:20.543783001 +0100 @@ -0,0 +1,30 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/"; + __overlay__ { + rpi_ft5406: rpi_ft5406 { + compatible = "rpi,rpi-ft5406"; + firmware = <&firmware>; + status = "okay"; + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + touchscreen-inverted-x = <0>; + touchscreen-inverted-y = <0>; + touchscreen-swapped-x-y = <0>; + }; + }; + }; + + __overrides__ { + touchscreen-size-x = <&rpi_ft5406>,"touchscreen-size-x:0"; + touchscreen-size-y = <&rpi_ft5406>,"touchscreen-size-y:0"; + touchscreen-inverted-x = <&rpi_ft5406>,"touchscreen-inverted-x:0"; + touchscreen-inverted-y = <&rpi_ft5406>,"touchscreen-inverted-y:0"; + touchscreen-swapped-x-y = <&rpi_ft5406>,"touchscreen-swapped-x-y:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts 2018-10-29 19:31:20.543783001 +0100 @@ -0,0 +1,61 @@ +/* + * Overlay for the Raspberry Pi POE HAT. + */ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/"; + __overlay__ { + fan0: rpi-poe-fan@0 { + compatible = "raspberrypi,rpi-poe-fan"; + firmware = <&firmware>; + cooling-min-state = <0>; + cooling-max-state = <3>; + #cooling-cells = <2>; + cooling-levels = <0 50 150 255>; + status = "okay"; + }; + }; + }; + + fragment@1 { + target = <&cpu_thermal>; + __overlay__ { + trips { + threshold: trip-point@0 { + temperature = <45000>; + hysteresis = <5000>; + type = "active"; + }; + target: trip-point@1 { + temperature = <50000>; + hysteresis = <2000>; + type = "active"; + }; + cpu_hot: cpu_hot@0 { + temperature = <55000>; + hysteresis = <2000>; + type = "active"; + }; + }; + cooling-maps { + map0 { + trip = <&threshold>; + cooling-device = <&fan0 0 1>; + }; + map1 { + trip = <&target>; + cooling-device = <&fan0 1 2>; + }; + map2 { + trip = <&cpu_hot>; + cooling-device = <&fan0 2 3>; + }; + }; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts 2018-10-29 19:31:20.543783001 +0100 @@ -0,0 +1,39 @@ +// Definitions for Rpi-Proto +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + wm8731@1a { + #sound-dai-cells = <0>; + compatible = "wlf,wm8731"; + reg = <0x1a>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "rpi,rpi-proto"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts 2018-10-29 19:31:20.544782951 +0100 @@ -0,0 +1,47 @@ +// rpi-sense HAT +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + rpi-sense@46 { + compatible = "rpi,rpi-sense"; + reg = <0x46>; + keys-int-gpios = <&gpio 23 1>; + status = "okay"; + }; + + lsm9ds1-magn@1c { + compatible = "st,lsm9ds1-magn"; + reg = <0x1c>; + status = "okay"; + }; + + lsm9ds1-accel6a { + compatible = "st,lsm9ds1-accel"; + reg = <0x6a>; + status = "okay"; + }; + + lps25h-press@5c { + compatible = "st,lps25h-press"; + reg = <0x5c>; + status = "okay"; + }; + + hts221-humid@5f { + compatible = "st,hts221-humid"; + reg = <0x5f>; + status = "okay"; + }; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/rpi-tv-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/rpi-tv-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/rpi-tv-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/rpi-tv-overlay.dts 2018-10-29 19:31:20.544782951 +0100 @@ -0,0 +1,34 @@ +// rpi-tv HAT + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@1 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + cxd2880@0 { + compatible = "sony,cxd2880"; + reg = <0>; /* CE0 */ + spi-max-frequency = <50000000>; + status = "okay"; + }; + }; + }; + +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/rra-digidac1-wm8741-audio-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/rra-digidac1-wm8741-audio-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/rra-digidac1-wm8741-audio-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/rra-digidac1-wm8741-audio-overlay.dts 2018-10-29 19:31:20.544782951 +0100 @@ -0,0 +1,49 @@ +// Definitions for RRA DigiDAC1 Audio card +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + wm8804@3b { + #sound-dai-cells = <0>; + compatible = "wlf,wm8804"; + reg = <0x3b>; + status = "okay"; + PVDD-supply = <&vdd_3v3_reg>; + DVDD-supply = <&vdd_3v3_reg>; + }; + + wm8742: wm8741@1a { + compatible = "wlf,wm8741"; + reg = <0x1a>; + status = "okay"; + AVDD-supply = <&vdd_5v0_reg>; + DVDD-supply = <&vdd_3v3_reg>; + }; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "rra,digidac1-soundcard"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts 2018-10-29 19:31:20.544782951 +0100 @@ -0,0 +1,37 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&i2c_arm>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + sc16is750: sc16is750@48 { + compatible = "nxp,sc16is750"; + reg = <0x48>; /* address */ + clocks = <&sc16is750_clk>; + interrupt-parent = <&gpio>; + interrupts = <24 2>; /* IRQ_TYPE_EDGE_FALLING */ + #gpio-cells = <2>; + + sc16is750_clk: sc16is750_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <14745600>; + }; + }; + }; + }; + + + __overrides__ { + int_pin = <&sc16is750>,"interrupts:0"; + addr = <&sc16is750>,"reg:0"; + }; + +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts 2018-10-29 19:31:20.544782951 +0100 @@ -0,0 +1,40 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c1>; + + frag1: __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + sc16is752: sc16is752@48 { + compatible = "nxp,sc16is752"; + reg = <0x48>; // i2c address + clocks = <&sc16is752_clk>; + interrupt-parent = <&gpio>; + interrupts = <24 0x2>; /* IRQ_TYPE_EDGE_FALLING */ + gpio-controller; + #gpio-cells = <0>; + i2c-max-frequency = <400000>; + status = "okay"; + + sc16is752_clk: sc16is752_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <14745600>; + }; + }; + }; + }; + + __overrides__ { + int_pin = <&sc16is752>,"interrupts:0"; + addr = <&sc16is752>,"reg:0"; + xtal = <&sc16is752>,"clock-frequency:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts 2018-10-29 19:31:20.544782951 +0100 @@ -0,0 +1,61 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&gpio>; + __overlay__ { + spi1_pins: spi1_pins { + brcm,pins = <19 20 21>; + brcm,function = <3>; /* alt4 */ + }; + + spi1_cs_pins: spi1_cs_pins { + brcm,pins = <18>; + brcm,function = <1>; /* output */ + }; + }; + }; + + fragment@1 { + target = <&spi1>; + frag1: __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi1_pins &spi1_cs_pins>; + cs-gpios = <&gpio 18 1>; + status = "okay"; + + sc16is752: sc16is752@0 { + compatible = "nxp,sc16is752"; + reg = <0>; /* CE0 */ + clocks = <&sc16is752_clk>; + interrupt-parent = <&gpio>; + interrupts = <24 2>; /* IRQ_TYPE_EDGE_FALLING */ + #gpio-controller; + #gpio-cells = <2>; + spi-max-frequency = <4000000>; + + sc16is752_clk: sc16is752_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <14745600>; + }; + }; + }; + }; + + fragment@2 { + target = <&aux>; + __overlay__ { + status = "okay"; + }; + }; + + __overrides__ { + int_pin = <&sc16is752>,"interrupts:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/sdhost-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/sdhost-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/sdhost-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/sdhost-overlay.dts 2018-10-29 19:31:20.544782951 +0100 @@ -0,0 +1,31 @@ +/dts-v1/; +/plugin/; + +/* Provide backwards compatible aliases for the old sdhost dtparams. */ + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&sdhost>; + frag0: __overlay__ { + brcm,overclock-50 = <0>; + brcm,pio-limit = <1>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&mmc>; + __overlay__ { + status = "disabled"; + }; + }; + + __overrides__ { + overclock_50 = <&frag0>,"brcm,overclock-50:0"; + force_pio = <&frag0>,"brcm,force-pio?"; + pio_limit = <&frag0>,"brcm,pio-limit:0"; + debug = <&frag0>,"brcm,debug?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts 2018-10-29 19:31:20.544782951 +0100 @@ -0,0 +1,63 @@ +/dts-v1/; +/plugin/; + +/* Enable 1-bit SDIO from MMC interface via GPIOs 22-25. Includes sdhost overlay. */ + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&mmc>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@1 { + target = <&soc>; + __overlay__ { + #address-cells = <1>; + #size-cells = <1>; + + sdio_1bit: sdio@7e300000 { + compatible = "brcm,bcm2835-mmc", + "brcm,bcm2835-sdhci"; + reg = <0x7e300000 0x100>; + interrupts = <2 30>; + clocks = <&clocks 28/*BCM2835_CLOCK_EMMC*/>; + dmas = <&dma 11>; + dma-names = "rx-tx"; + brcm,overclock-50 = <0>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&sdio_1bit_pins>; + non-removable; + bus-width = <1>; + }; + }; + }; + + fragment@2 { + target = <&gpio>; + __overlay__ { + sdio_1bit_pins: sdio_1bit_pins { + brcm,pins = <22 23 24 25>; + brcm,function = <7>; /* ALT3 = SD1 */ + brcm,pull = <0 2 2 2>; + }; + }; + }; + + fragment@3 { + target-path = "/aliases"; + __overlay__ { + mmc1 = "/soc/sdio@7e300000"; + }; + }; + + + __overrides__ { + poll_once = <&sdio_1bit>,"non-removable?"; + sdio_overclock = <&sdio_1bit>,"brcm,overclock-50:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/sdio-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/sdio-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/sdio-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/sdio-overlay.dts 2018-10-29 19:31:20.544782951 +0100 @@ -0,0 +1,63 @@ +/dts-v1/; +/plugin/; + +/* Enable SDIO from MMC interface via GPIOs 22-27. Includes sdhost overlay. */ + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&mmc>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@1 { + target = <&soc>; + __overlay__ { + #address-cells = <1>; + #size-cells = <1>; + + sdio_ovl: sdio@7e300000 { + compatible = "brcm,bcm2835-mmc", + "brcm,bcm2835-sdhci"; + reg = <0x7e300000 0x100>; + interrupts = <2 30>; + clocks = <&clocks 28/*BCM2835_CLOCK_EMMC*/>; + dmas = <&dma 11>; + dma-names = "rx-tx"; + brcm,overclock-50 = <0>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&sdio_ovl_pins>; + non-removable; + bus-width = <1>; + }; + }; + }; + + fragment@2 { + target = <&gpio>; + __overlay__ { + sdio_ovl_pins: sdio_ovl_pins { + brcm,pins = <22 23 24 25 26 27>; + brcm,function = <7>; /* ALT3 = SD1 */ + brcm,pull = <0 2 2 2 2 2>; + }; + }; + }; + + fragment@3 { + target-path = "/aliases"; + __overlay__ { + mmc1 = "/soc/sdio@7e300000"; + }; + }; + + __overrides__ { + poll_once = <&sdio_ovl>,"non-removable?"; + bus_width = <&sdio_ovl>,"bus-width:0"; + sdio_overclock = <&sdio_ovl>,"brcm,overclock-50:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/sdtweak-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/sdtweak-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/sdtweak-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/sdtweak-overlay.dts 2018-10-29 19:31:20.545782901 +0100 @@ -0,0 +1,25 @@ +/dts-v1/; +/plugin/; + +/* Provide backwards compatible aliases for the old sdhost dtparams. */ + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&sdhost>; + frag0: __overlay__ { + brcm,overclock-50 = <0>; + brcm,pio-limit = <1>; + }; + }; + + __overrides__ { + overclock_50 = <&frag0>,"brcm,overclock-50:0"; + force_pio = <&frag0>,"brcm,force-pio?"; + pio_limit = <&frag0>,"brcm,pio-limit:0"; + debug = <&frag0>,"brcm,debug?"; + enable = <&frag0>,"status"; + poll_once = <&frag0>,"non-removable?"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/smi-dev-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/smi-dev-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/smi-dev-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/smi-dev-overlay.dts 2018-10-29 19:31:20.545782901 +0100 @@ -0,0 +1,18 @@ +// Description: Overlay to enable character device interface for SMI. +// Author: Luke Wren + +/dts-v1/; +/plugin/; + +/{ + fragment@0 { + target = <&soc>; + __overlay__ { + smi_dev { + compatible = "brcm,bcm2835-smi-dev"; + smi_handle = <&smi>; + status = "okay"; + }; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/smi-nand-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/smi-nand-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/smi-nand-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/smi-nand-overlay.dts 2018-10-29 19:31:20.545782901 +0100 @@ -0,0 +1,66 @@ +// Description: Overlay to enable NAND flash through +// the secondary memory interface +// Author: Luke Wren + +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&smi>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&smi_pins>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&soc>; + __overlay__ { + nand: flash@0 { + compatible = "brcm,bcm2835-smi-nand"; + smi_handle = <&smi>; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + + partition@0 { + label = "stage2"; + // 128k + reg = <0 0x20000>; + read-only; + }; + partition@1 { + label = "firmware"; + // 16M + reg = <0x20000 0x1000000>; + read-only; + }; + partition@2 { + label = "root"; + // 2G (will need to use 64 bit for >=4G) + reg = <0x1020000 0x80000000>; + }; + }; + }; + }; + + fragment@2 { + target = <&gpio>; + __overlay__ { + smi_pins: smi_pins { + brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 + 12 13 14 15>; + /* Alt 1: SMI */ + brcm,function = <5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5>; + /* /CS, /WE and /OE are pulled high, as they are + generally active low signals */ + brcm,pull = <2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0>; + }; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/smi-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/smi-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/smi-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/smi-overlay.dts 2018-10-29 19:31:20.545782901 +0100 @@ -0,0 +1,37 @@ +// Description: Overlay to enable the secondary memory interface peripheral +// Author: Luke Wren + +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&smi>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&smi_pins>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + smi_pins: smi_pins { + /* Don't configure the top two address bits, as + these are already used as ID_SD and ID_SC */ + brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 24 25>; + /* Alt 0: SMI */ + brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5>; + /* /CS, /WE and /OE are pulled high, as they are + generally active low signals */ + brcm,pull = <2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0>; + }; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/spi0-cs-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/spi0-cs-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/spi0-cs-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/spi0-cs-overlay.dts 2018-10-29 19:31:20.545782901 +0100 @@ -0,0 +1,29 @@ +/dts-v1/; +/plugin/; + + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0_cs_pins>; + frag0: __overlay__ { + brcm,pins = <8 7>; + }; + }; + + fragment@1 { + target = <&spi0>; + frag1: __overlay__ { + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + status = "okay"; + }; + }; + + __overrides__ { + cs0_pin = <&frag0>,"brcm,pins:0", + <&frag1>,"cs-gpios:4"; + cs1_pin = <&frag0>,"brcm,pins:4", + <&frag1>,"cs-gpios:16"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/spi0-hw-cs-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/spi0-hw-cs-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/spi0-hw-cs-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/spi0-hw-cs-overlay.dts 2018-10-29 19:31:20.545782901 +0100 @@ -0,0 +1,26 @@ +/* + * Device tree overlay to re-enable hardware CS for SPI0 + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + cs-gpios = <0>, <0>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&spi0_cs_pins>; + __overlay__ { + brcm,pins = <8 7>; + brcm,function = <4>; /* alt0 */ + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts 2018-10-29 19:31:20.546782851 +0100 @@ -0,0 +1,57 @@ +/dts-v1/; +/plugin/; + + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&gpio>; + __overlay__ { + spi1_pins: spi1_pins { + brcm,pins = <19 20 21>; + brcm,function = <3>; /* alt4 */ + }; + + spi1_cs_pins: spi1_cs_pins { + brcm,pins = <18>; + brcm,function = <1>; /* output */ + }; + }; + }; + + fragment@1 { + target = <&spi1>; + frag1: __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi1_pins &spi1_cs_pins>; + cs-gpios = <&gpio 18 1>; + status = "okay"; + + spidev1_0: spidev@0 { + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&aux>; + __overlay__ { + status = "okay"; + }; + }; + + __overrides__ { + cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", + <&frag1>,"cs-gpios:4"; + cs0_spidev = <&spidev1_0>,"status"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts 2018-10-29 19:31:20.546782851 +0100 @@ -0,0 +1,69 @@ +/dts-v1/; +/plugin/; + + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&gpio>; + __overlay__ { + spi1_pins: spi1_pins { + brcm,pins = <19 20 21>; + brcm,function = <3>; /* alt4 */ + }; + + spi1_cs_pins: spi1_cs_pins { + brcm,pins = <18 17>; + brcm,function = <1>; /* output */ + }; + }; + }; + + fragment@1 { + target = <&spi1>; + frag1: __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi1_pins &spi1_cs_pins>; + cs-gpios = <&gpio 18 1>, <&gpio 17 1>; + status = "okay"; + + spidev1_0: spidev@0 { + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + status = "okay"; + }; + + spidev1_1: spidev@1 { + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&aux>; + __overlay__ { + status = "okay"; + }; + }; + + __overrides__ { + cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", + <&frag1>,"cs-gpios:4"; + cs1_pin = <&spi1_cs_pins>,"brcm,pins:4", + <&frag1>,"cs-gpios:16"; + cs0_spidev = <&spidev1_0>,"status"; + cs1_spidev = <&spidev1_1>,"status"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts 2018-10-29 19:31:20.546782851 +0100 @@ -0,0 +1,81 @@ +/dts-v1/; +/plugin/; + + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&gpio>; + __overlay__ { + spi1_pins: spi1_pins { + brcm,pins = <19 20 21>; + brcm,function = <3>; /* alt4 */ + }; + + spi1_cs_pins: spi1_cs_pins { + brcm,pins = <18 17 16>; + brcm,function = <1>; /* output */ + }; + }; + }; + + fragment@1 { + target = <&spi1>; + frag1: __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi1_pins &spi1_cs_pins>; + cs-gpios = <&gpio 18 1>, <&gpio 17 1>, <&gpio 16 1>; + status = "okay"; + + spidev1_0: spidev@0 { + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + status = "okay"; + }; + + spidev1_1: spidev@1 { + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + status = "okay"; + }; + + spidev1_2: spidev@2 { + compatible = "spidev"; + reg = <2>; /* CE2 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&aux>; + __overlay__ { + status = "okay"; + }; + }; + + __overrides__ { + cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", + <&frag1>,"cs-gpios:4"; + cs1_pin = <&spi1_cs_pins>,"brcm,pins:4", + <&frag1>,"cs-gpios:16"; + cs2_pin = <&spi1_cs_pins>,"brcm,pins:8", + <&frag1>,"cs-gpios:28"; + cs0_spidev = <&spidev1_0>,"status"; + cs1_spidev = <&spidev1_1>,"status"; + cs2_spidev = <&spidev1_2>,"status"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts 2018-10-29 19:31:20.546782851 +0100 @@ -0,0 +1,57 @@ +/dts-v1/; +/plugin/; + + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&gpio>; + __overlay__ { + spi2_pins: spi2_pins { + brcm,pins = <40 41 42>; + brcm,function = <3>; /* alt4 */ + }; + + spi2_cs_pins: spi2_cs_pins { + brcm,pins = <43>; + brcm,function = <1>; /* output */ + }; + }; + }; + + fragment@1 { + target = <&spi2>; + frag1: __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi2_pins &spi2_cs_pins>; + cs-gpios = <&gpio 43 1>; + status = "okay"; + + spidev2_0: spidev@0 { + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&aux>; + __overlay__ { + status = "okay"; + }; + }; + + __overrides__ { + cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", + <&frag1>,"cs-gpios:4"; + cs0_spidev = <&spidev2_0>,"status"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts 2018-10-29 19:31:20.546782851 +0100 @@ -0,0 +1,69 @@ +/dts-v1/; +/plugin/; + + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&gpio>; + __overlay__ { + spi2_pins: spi2_pins { + brcm,pins = <40 41 42>; + brcm,function = <3>; /* alt4 */ + }; + + spi2_cs_pins: spi2_cs_pins { + brcm,pins = <43 44>; + brcm,function = <1>; /* output */ + }; + }; + }; + + fragment@1 { + target = <&spi2>; + frag1: __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi2_pins &spi2_cs_pins>; + cs-gpios = <&gpio 43 1>, <&gpio 44 1>; + status = "okay"; + + spidev2_0: spidev@0 { + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + status = "okay"; + }; + + spidev2_1: spidev@1 { + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&aux>; + __overlay__ { + status = "okay"; + }; + }; + + __overrides__ { + cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", + <&frag1>,"cs-gpios:4"; + cs1_pin = <&spi2_cs_pins>,"brcm,pins:4", + <&frag1>,"cs-gpios:16"; + cs0_spidev = <&spidev2_0>,"status"; + cs1_spidev = <&spidev2_1>,"status"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts 2018-10-29 19:31:20.546782851 +0100 @@ -0,0 +1,81 @@ +/dts-v1/; +/plugin/; + + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&gpio>; + __overlay__ { + spi2_pins: spi2_pins { + brcm,pins = <40 41 42>; + brcm,function = <3>; /* alt4 */ + }; + + spi2_cs_pins: spi2_cs_pins { + brcm,pins = <43 44 45>; + brcm,function = <1>; /* output */ + }; + }; + }; + + fragment@1 { + target = <&spi2>; + frag1: __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi2_pins &spi2_cs_pins>; + cs-gpios = <&gpio 43 1>, <&gpio 44 1>, <&gpio 45 1>; + status = "okay"; + + spidev2_0: spidev@0 { + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + status = "okay"; + }; + + spidev2_1: spidev@1 { + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + status = "okay"; + }; + + spidev2_2: spidev@2 { + compatible = "spidev"; + reg = <2>; /* CE2 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <125000000>; + status = "okay"; + }; + }; + }; + + fragment@2 { + target = <&aux>; + __overlay__ { + status = "okay"; + }; + }; + + __overrides__ { + cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", + <&frag1>,"cs-gpios:4"; + cs1_pin = <&spi2_cs_pins>,"brcm,pins:4", + <&frag1>,"cs-gpios:16"; + cs2_pin = <&spi2_cs_pins>,"brcm,pins:8", + <&frag1>,"cs-gpios:28"; + cs0_spidev = <&spidev2_0>,"status"; + cs1_spidev = <&spidev2_1>,"status"; + cs2_spidev = <&spidev2_2>,"status"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts 2018-10-29 19:31:20.545782901 +0100 @@ -0,0 +1,31 @@ +/* + * Device tree overlay to move spi0 to gpio 35 to 39 on CM + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + cs-gpios = <&gpio 36 1>, <&gpio 35 1>; + }; + }; + + fragment@1 { + target = <&spi0_cs_pins>; + __overlay__ { + brcm,pins = <36 35>; + }; + }; + + fragment@2 { + target = <&spi0_pins>; + __overlay__ { + brcm,pins = <37 38 39>; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/spi-rtc-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/spi-rtc-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/spi-rtc-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/spi-rtc-overlay.dts 2018-10-29 19:31:20.545782901 +0100 @@ -0,0 +1,33 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&spidev0>; + __dormant__ { + status = "disabled"; + }; + }; + + fragment@1 { + target = <&spi0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + rtc-pcf2123@0 { + compatible = "nxp,rtc-pcf2123"; + spi-max-frequency = <5000000>; + spi-cs-high = <1>; + reg = <0>; + }; + }; + }; + + __overrides__ { + pcf2123 = <0>, "=0=1"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/superaudioboard-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/superaudioboard-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/superaudioboard-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/superaudioboard-overlay.dts 2018-10-29 19:31:20.546782851 +0100 @@ -0,0 +1,73 @@ +// Definitions for SuperAudioBoard +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&sound>; + __overlay__ { + compatible = "simple-audio-card"; + i2s-controller = <&i2s>; + status = "okay"; + + simple-audio-card,name = "SuperAudioBoard"; + + simple-audio-card,widgets = + "Line", "Line In", + "Line", "Line Out"; + + simple-audio-card,routing = + "Line Out","AOUTA+", + "Line Out","AOUTA-", + "Line Out","AOUTB+", + "Line Out","AOUTB-", + "AINA","Line In", + "AINB","Line In"; + + simple-audio-card,format = "i2s"; + + simple-audio-card,bitclock-master = <&sound_master>; + simple-audio-card,frame-master = <&sound_master>; + + simple-audio-card,cpu { + sound-dai = <&i2s>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + }; + + sound_master: simple-audio-card,codec { + sound-dai = <&cs4271>; + system-clock-frequency = <24576000>; + }; + }; + }; + + fragment@1 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + cs4271: cs4271@10 { + #sound-dai-cells = <0>; + compatible = "cirrus,cs4271"; + reg = <0x10>; + status = "okay"; + reset-gpio = <&gpio 26 0>; /* Pin 26, active high */ + }; + }; + }; + __overrides__ { + gpiopin = <&cs4271>,"reset-gpio:4"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/sx150x-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/sx150x-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/sx150x-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/sx150x-overlay.dts 2018-10-29 19:31:20.547782801 +0100 @@ -0,0 +1,1706 @@ +// Definitions for SX150x I2C GPIO Expanders from Semtech + +// dtparams: +// sx150-- - Enables SX150X device on I2C# with slave address . may be 1-9. +// may be 0 or 1. Permissible values of (which is denoted in hex) +// depend on the device variant. +// For SX1501, SX1502, SX1504 and SX1505, may be 20 or 21. +// For SX1503 and SX1506, may be 20. +// For SX1507 and SX1509, may be 3E, 3F, 70 or 71. +// For SX1508, may be 20, 21, 22 or 23. +// sx150---int-gpio - Integer, enables interrupts on SX150X device on I2C# with slave address , +// specifies the GPIO pin to which NINT output of SX150X is connected. +// +// +// Example 1: A single SX1505 device on I2C#1 with its slave address set to 0x20 and NINT output connected to GPIO25: +// dtoverlay=sx150x:sx1505-1-20,sx1505-1-20-int-gpio=25 +// +// Example 2: Two SX1507 devices on I2C#0 with their slave addresses set to 0x3E and 0x70 (interrupts not used): +// dtoverlay=sx150x:sx1507-0-3E,sx1507-0-70 + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + // Enable I2C#0 interface + fragment@0 { + target = <&i2c0>; + __dormant__ { + status = "okay"; + }; + }; + + // Enable I2C#1 interface + fragment@1 { + target = <&i2c1>; + __dormant__ { + status = "okay"; + }; + }; + + // Enable a SX1501 on I2C#0 at slave addr 0x20 + fragment@2 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1501_0_20: sx150x@20 { + compatible = "semtech,sx1501q"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1501-0-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1501 on I2C#1 at slave addr 0x20 + fragment@3 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1501_1_20: sx150x@20 { + compatible = "semtech,sx1501q"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1501-1-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1501 on I2C#0 at slave addr 0x21 + fragment@4 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1501_0_21: sx150x@21 { + compatible = "semtech,sx1501q"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1501-0-21-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1501 on I2C#1 at slave addr 0x21 + fragment@5 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1501_1_21: sx150x@21 { + compatible = "semtech,sx1501q"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1501-1-21-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1502 on I2C#0 at slave addr 0x20 + fragment@6 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1502_0_20: sx150x@20 { + compatible = "semtech,sx1502q"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1502-0-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1502 on I2C#1 at slave addr 0x20 + fragment@7 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1502_1_20: sx150x@20 { + compatible = "semtech,sx1502q"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1502-1-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1502 on I2C#0 at slave addr 0x21 + fragment@8 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1502_0_21: sx150x@21 { + compatible = "semtech,sx1502q"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1502-0-21-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1502 on I2C#1 at slave addr 0x21 + fragment@9 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1502_1_21: sx150x@21 { + compatible = "semtech,sx1502q"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1501-1-21-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1503 on I2C#0 at slave addr 0x20 + fragment@10 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1503_0_20: sx150x@20 { + compatible = "semtech,sx1503q"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1503-0-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1503 on I2C#1 at slave addr 0x20 + fragment@11 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1503_1_20: sx150x@20 { + compatible = "semtech,sx1503q"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1503-1-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1504 on I2C#0 at slave addr 0x20 + fragment@12 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1504_0_20: sx150x@20 { + compatible = "semtech,sx1504q"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1504-0-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1504 on I2C#1 at slave addr 0x20 + fragment@13 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1504_1_20: sx150x@20 { + compatible = "semtech,sx1504q"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1504-1-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1504 on I2C#0 at slave addr 0x21 + fragment@14 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1504_0_21: sx150x@21 { + compatible = "semtech,sx1504q"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1504-0-21-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1504 on I2C#1 at slave addr 0x21 + fragment@15 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1504_1_21: sx150x@21 { + compatible = "semtech,sx1504q"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1504-1-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1505 on I2C#0 at slave addr 0x20 + fragment@16 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1505_0_20: sx150x@20 { + compatible = "semtech,sx1505q"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1505-0-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1505 on I2C#1 at slave addr 0x20 + fragment@17 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1505_1_20: sx150x@20 { + compatible = "semtech,sx1505q"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1505-1-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1505 on I2C#0 at slave addr 0x21 + fragment@18 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1505_0_21: sx150x@21 { + compatible = "semtech,sx1505q"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1505-0-21-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1505 on I2C#1 at slave addr 0x21 + fragment@19 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1505_1_21: sx150x@21 { + compatible = "semtech,sx1505q"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1505-1-21-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1506 on I2C#0 at slave addr 0x20 + fragment@20 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1506_0_20: sx150x@20 { + compatible = "semtech,sx1506q"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1506-0-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1506 on I2C#1 at slave addr 0x20 + fragment@21 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1506_1_20: sx150x@20 { + compatible = "semtech,sx1506q"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1506-1-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1507 on I2C#0 at slave addr 0x3E + fragment@22 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1507_0_3E: sx150x@3E { + compatible = "semtech,sx1507q"; + reg = <0x3E>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1507_0_3E-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1507 on I2C#1 at slave addr 0x3E + fragment@23 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1507_1_3E: sx150x@3E { + compatible = "semtech,sx1507q"; + reg = <0x3E>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1507_1_3E-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1507 on I2C#0 at slave addr 0x3F + fragment@24 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1507_0_3F: sx150x@3F { + compatible = "semtech,sx1507q"; + reg = <0x3F>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1507_0_3F-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1507 on I2C#1 at slave addr 0x3F + fragment@25 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1507_1_3F: sx150x@3F { + compatible = "semtech,sx1507q"; + reg = <0x3F>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1507_1_3F-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1507 on I2C#0 at slave addr 0x70 + fragment@26 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1507_0_70: sx150x@70 { + compatible = "semtech,sx1507q"; + reg = <0x70>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1507-0-70-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1507 on I2C#1 at slave addr 0x70 + fragment@27 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1507_1_70: sx150x@70 { + compatible = "semtech,sx1507q"; + reg = <0x70>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1507-1-70-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1507 on I2C#0 at slave addr 0x71 + fragment@28 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1507_0_71: sx150x@71 { + compatible = "semtech,sx1507q"; + reg = <0x71>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1507-0-71-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1507 on I2C#1 at slave addr 0x71 + fragment@29 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1507_1_71: sx150x@71 { + compatible = "semtech,sx1507q"; + reg = <0x71>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1507-1-71-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1508 on I2C#0 at slave addr 0x20 + fragment@30 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1508_0_20: sx150x@20 { + compatible = "semtech,sx1508q"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1508-0-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1508 on I2C#1 at slave addr 0x20 + fragment@31 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1508_1_20: sx150x@20 { + compatible = "semtech,sx1508q"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1508-1-20-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1508 on I2C#0 at slave addr 0x21 + fragment@32 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1508_0_21: sx150x@21 { + compatible = "semtech,sx1508q"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1508-0-21-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1508 on I2C#1 at slave addr 0x21 + fragment@33 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1508_1_21: sx150x@21 { + compatible = "semtech,sx1508q"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1508-1-21-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1508 on I2C#0 at slave addr 0x22 + fragment@34 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1508_0_22: sx150x@22 { + compatible = "semtech,sx1508q"; + reg = <0x22>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1508-0-22-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1508 on I2C#1 at slave addr 0x22 + fragment@35 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1508_1_22: sx150x@22 { + compatible = "semtech,sx1508q"; + reg = <0x22>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1508-1-22-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1508 on I2C#0 at slave addr 0x23 + fragment@36 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1508_0_23: sx150x@23 { + compatible = "semtech,sx1508q"; + reg = <0x23>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1508-0-23-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1508 on I2C#1 at slave addr 0x23 + fragment@37 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1508_1_23: sx150x@23 { + compatible = "semtech,sx1508q"; + reg = <0x23>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1508-1-23-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1509 on I2C#0 at slave addr 0x3E + fragment@38 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1509_0_3E: sx150x@3E { + compatible = "semtech,sx1509q"; + reg = <0x3E>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1509_0_3E-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1509 on I2C#1 at slave addr 0x3E + fragment@39 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1509_1_3E: sx150x@3E { + compatible = "semtech,sx1509q"; + reg = <0x3E>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1509_1_3E-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1509 on I2C#0 at slave addr 0x3F + fragment@40 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1509_0_3F: sx150x@3F { + compatible = "semtech,sx1509q"; + reg = <0x3F>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1509_0_3F-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1509 on I2C#1 at slave addr 0x3F + fragment@41 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1509_1_3F: sx150x@3F { + compatible = "semtech,sx1509q"; + reg = <0x3F>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1509_1_3F-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1509 on I2C#0 at slave addr 0x70 + fragment@42 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1509_0_70: sx150x@70 { + compatible = "semtech,sx1509q"; + reg = <0x70>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1509-0-70-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1509 on I2C#1 at slave addr 0x70 + fragment@43 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1509_1_70: sx150x@70 { + compatible = "semtech,sx1509q"; + reg = <0x70>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1509-1-70-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1509 on I2C#0 at slave addr 0x71 + fragment@44 { + target = <&i2c0>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1509_0_71: sx150x@71 { + compatible = "semtech,sx1509q"; + reg = <0x71>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1509-0-71-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable a SX1509 on I2C#1 at slave addr 0x71 + fragment@45 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + sx1509_1_71: sx150x@71 { + compatible = "semtech,sx1509q"; + reg = <0x71>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = <25 2>; /* 1st word overwritten by sx1509-1-71-int-gpio parameter + 2nd word is 2 for falling-edge triggered */ + status = "okay"; + }; + }; + }; + + // Enable interrupts for a SX1501 on I2C#0 at slave addr 0x20 + fragment@46 { + target = <&sx1501_0_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_20_pins>; + }; + }; + + // Enable interrupts for a SX1501 on I2C#1 at slave addr 0x20 + fragment@47 { + target = <&sx1501_1_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_20_pins>; + }; + }; + + // Enable interrupts for a SX1501 on I2C#0 at slave addr 0x21 + fragment@48 { + target = <&sx1501_0_21>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_21_pins>; + }; + }; + + // Enable interrupts for a SX1501 on I2C#1 at slave addr 0x21 + fragment@49 { + target = <&sx1501_1_21>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_21_pins>; + }; + }; + + // Enable interrupts for a SX1502 on I2C#0 at slave addr 0x20 + fragment@50 { + target = <&sx1502_0_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_20_pins>; + }; + }; + + // Enable interrupts for a SX1502 on I2C#1 at slave addr 0x20 + fragment@51 { + target = <&sx1502_1_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_20_pins>; + }; + }; + + // Enable interrupts for a SX1502 on I2C#0 at slave addr 0x21 + fragment@52 { + target = <&sx1502_0_21>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_21_pins>; + }; + }; + + // Enable interrupts for a SX1502 on I2C#1 at slave addr 0x21 + fragment@53 { + target = <&sx1502_1_21>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_21_pins>; + }; + }; + + // Enable interrupts for a SX1503 on I2C#0 at slave addr 0x20 + fragment@54 { + target = <&sx1503_0_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_20_pins>; + }; + }; + + // Enable interrupts for a SX1503 on I2C#1 at slave addr 0x20 + fragment@55 { + target = <&sx1503_1_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_20_pins>; + }; + }; + + // Enable interrupts for a SX1504 on I2C#0 at slave addr 0x20 + fragment@56 { + target = <&sx1504_0_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_20_pins>; + }; + }; + + // Enable interrupts for a SX1504 on I2C#1 at slave addr 0x20 + fragment@57 { + target = <&sx1504_1_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_20_pins>; + }; + }; + + // Enable interrupts for a SX1504 on I2C#0 at slave addr 0x21 + fragment@58 { + target = <&sx1504_0_21>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_21_pins>; + }; + }; + + // Enable interrupts for a SX1504 on I2C#1 at slave addr 0x21 + fragment@59 { + target = <&sx1504_1_21>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_21_pins>; + }; + }; + + // Enable interrupts for a SX1505 on I2C#0 at slave addr 0x20 + fragment@60 { + target = <&sx1505_0_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_20_pins>; + }; + }; + + // Enable interrupts for a SX1505 on I2C#1 at slave addr 0x20 + fragment@61 { + target = <&sx1505_1_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_20_pins>; + }; + }; + + // Enable interrupts for a SX1505 on I2C#0 at slave addr 0x21 + fragment@62 { + target = <&sx1505_0_21>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_21_pins>; + }; + }; + + // Enable interrupts for a SX1505 on I2C#1 at slave addr 0x21 + fragment@63 { + target = <&sx1505_1_21>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_21_pins>; + }; + }; + + // Enable interrupts for a SX1506 on I2C#0 at slave addr 0x20 + fragment@64 { + target = <&sx1506_0_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_20_pins>; + }; + }; + + // Enable interrupts for a SX1506 on I2C#1 at slave addr 0x20 + fragment@65 { + target = <&sx1506_1_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_20_pins>; + }; + }; + + // Enable interrupts for a SX1507 on I2C#0 at slave addr 0x3E + fragment@66 { + target = <&sx1507_0_3E>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_3E_pins>; + }; + }; + + // Enable interrupts for a SX1507 on I2C#1 at slave addr 0x3E + fragment@67 { + target = <&sx1507_1_3E>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_3E_pins>; + }; + }; + + // Enable interrupts for a SX1507 on I2C#0 at slave addr 0x3F + fragment@68 { + target = <&sx1507_0_3F>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_3F_pins>; + }; + }; + + // Enable interrupts for a SX1507 on I2C#1 at slave addr 0x3F + fragment@69 { + target = <&sx1507_1_3F>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_3F_pins>; + }; + }; + + // Enable interrupts for a SX1507 on I2C#0 at slave addr 0x70 + fragment@70 { + target = <&sx1507_0_70>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_70_pins>; + }; + }; + + // Enable interrupts for a SX1507 on I2C#1 at slave addr 0x70 + fragment@71 { + target = <&sx1507_1_70>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_70_pins>; + }; + }; + + // Enable interrupts for a SX1507 on I2C#0 at slave addr 0x71 + fragment@72 { + target = <&sx1507_0_71>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_71_pins>; + }; + }; + + // Enable interrupts for a SX1507 on I2C#1 at slave addr 0x71 + fragment@73 { + target = <&sx1507_1_71>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_71_pins>; + }; + }; + + // Enable interrupts for a SX1508 on I2C#0 at slave addr 0x20 + fragment@74 { + target = <&sx1508_0_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_20_pins>; + }; + }; + + // Enable interrupts for a SX1508 on I2C#1 at slave addr 0x20 + fragment@75 { + target = <&sx1508_1_20>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_20_pins>; + }; + }; + + // Enable interrupts for a SX1508 on I2C#0 at slave addr 0x21 + fragment@76 { + target = <&sx1508_0_21>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_21_pins>; + }; + }; + + // Enable interrupts for a SX1508 on I2C#1 at slave addr 0x21 + fragment@77 { + target = <&sx1508_1_21>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_21_pins>; + }; + }; + + // Enable interrupts for a SX1508 on I2C#0 at slave addr 0x22 + fragment@78 { + target = <&sx1508_0_22>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_22_pins>; + }; + }; + + // Enable interrupts for a SX1508 on I2C#1 at slave addr 0x22 + fragment@79 { + target = <&sx1508_1_22>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_22_pins>; + }; + }; + + // Enable interrupts for a SX1508 on I2C#0 at slave addr 0x23 + fragment@80 { + target = <&sx1508_0_23>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_23_pins>; + }; + }; + + // Enable interrupts for a SX1508 on I2C#1 at slave addr 0x23 + fragment@81 { + target = <&sx1508_1_23>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_23_pins>; + }; + }; + + // Enable interrupts for a SX1509 on I2C#0 at slave addr 0x3E + fragment@82 { + target = <&sx1509_0_3E>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_3E_pins>; + }; + }; + + // Enable interrupts for a SX1509 on I2C#1 at slave addr 0x3E + fragment@83 { + target = <&sx1509_1_3E>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_3E_pins>; + }; + }; + + // Enable interrupts for a SX1509 on I2C#0 at slave addr 0x3F + fragment@84 { + target = <&sx1509_0_3F>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_3F_pins>; + }; + }; + + // Enable interrupts for a SX1509 on I2C#1 at slave addr 0x3F + fragment@85 { + target = <&sx1509_1_3F>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_3F_pins>; + }; + }; + + // Enable interrupts for a SX1509 on I2C#0 at slave addr 0x70 + fragment@86 { + target = <&sx1509_0_70>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_70_pins>; + }; + }; + + // Enable interrupts for a SX1509 on I2C#1 at slave addr 0x70 + fragment@87 { + target = <&sx1509_1_70>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_70_pins>; + }; + }; + + // Enable interrupts for a SX1509 on I2C#0 at slave addr 0x71 + fragment@88 { + target = <&sx1509_0_71>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_0_71_pins>; + }; + }; + + // Enable interrupts for a SX1509 on I2C#1 at slave addr 0x71 + fragment@89 { + target = <&sx1509_1_71>; + __dormant__ { + interrupt-parent = <&gpio>; + interrupt-controller; + pinctrl-names = "default"; + pinctrl-0 = <&sx150x_1_71_pins>; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#0 interface at slave addr 0x20 + // Configure as a input with no pull-up/down + fragment@90 { + target = <&gpio>; + __dormant__ { + sx150x_0_20_pins: sx150x_0_20_pins { + brcm,pins = <0>; /* overwritten by sx150x-0-20-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#1 interface at slave addr 0x20 + // Configure as a input with no pull-up/down + fragment@91 { + target = <&gpio>; + __dormant__ { + sx150x_1_20_pins: sx150x_1_20_pins { + brcm,pins = <0>; /* overwritten by sx150x-1-20-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#0 interface at slave addr 0x21 + // Configure as a input with no pull-up/down + fragment@92 { + target = <&gpio>; + __dormant__ { + sx150x_0_21_pins: sx150x_0_21_pins { + brcm,pins = <0>; /* overwritten by sx150x-0-21-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#1 interface at slave addr 0x21 + // Configure as a input with no pull-up/down + fragment@93 { + target = <&gpio>; + __dormant__ { + sx150x_1_21_pins: sx150x_1_21_pins { + brcm,pins = <0>; /* overwritten by sx150x-1-21-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#0 interface at slave addr 0x22 + // Configure as a input with no pull-up/down + fragment@94 { + target = <&gpio>; + __dormant__ { + sx150x_0_22_pins: sx150x_0_22_pins { + brcm,pins = <0>; /* overwritten by sx150x-0-22-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#1 interface at slave addr 0x22 + // Configure as a input with no pull-up/down + fragment@95 { + target = <&gpio>; + __dormant__ { + sx150x_1_22_pins: sx150x_1_22_pins { + brcm,pins = <0>; /* overwritten by sx150x-1-22-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#0 interface at slave addr 0x23 + // Configure as a input with no pull-up/down + fragment@96 { + target = <&gpio>; + __dormant__ { + sx150x_0_23_pins: sx150x_0_23_pins { + brcm,pins = <0>; /* overwritten by sx150x-0-23-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#1 interface at slave addr 0x23 + // Configure as a input with no pull-up/down + fragment@97 { + target = <&gpio>; + __dormant__ { + sx150x_1_23_pins: sx150x_1_23_pins { + brcm,pins = <0>; /* overwritten by sx150x-1-23-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#0 interface at slave addr 0x3E + // Configure as a input with no pull-up/down + fragment@98 { + target = <&gpio>; + __dormant__ { + sx150x_0_3E_pins: sx150x_0_3E_pins { + brcm,pins = <0>; /* overwritten by sx150x-0-3E-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#1 interface at slave addr 0x3E + // Configure as a input with no pull-up/down + fragment@99 { + target = <&gpio>; + __dormant__ { + sx150x_1_3E_pins: sx150x_1_3E_pins { + brcm,pins = <0>; /* overwritten by sx150x-1-3E-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#0 interface at slave addr 0x3F + // Configure as a input with no pull-up/down + fragment@100 { + target = <&gpio>; + __dormant__ { + sx150x_0_3F_pins: sx150x_0_3F_pins { + brcm,pins = <0>; /* overwritten by sx150x-0-3F-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#1 interface at slave addr 0x3F + // Configure as a input with no pull-up/down + fragment@101 { + target = <&gpio>; + __dormant__ { + sx150x_1_3F_pins: sx150x_1_3F_pins { + brcm,pins = <0>; /* overwritten by sx150x-1-3F-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#0 interface at slave addr 0x70 + // Configure as a input with no pull-up/down + fragment@102 { + target = <&gpio>; + __dormant__ { + sx150x_0_70_pins: sx150x_0_70_pins { + brcm,pins = <0>; /* overwritten by sx150x-0-70-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#1 interface at slave addr 0x70 + // Configure as a input with no pull-up/down + fragment@103 { + target = <&gpio>; + __dormant__ { + sx150x_1_70_pins: sx150x_1_70_pins { + brcm,pins = <0>; /* overwritten by sx150x-1-70-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#0 interface at slave addr 0x71 + // Configure as a input with no pull-up/down + fragment@104 { + target = <&gpio>; + __dormant__ { + sx150x_0_71_pins: sx150x_0_71_pins { + brcm,pins = <0>; /* overwritten by sx150x-0-71-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + // Configure GPIO pin connected to NINT output of a SX150x on I2C#1 interface at slave addr 0x71 + // Configure as a input with no pull-up/down + fragment@105 { + target = <&gpio>; + __dormant__ { + sx150x_1_71_pins: sx150x_1_71_pins { + brcm,pins = <0>; /* overwritten by sx150x-1-71-int-gpio parameter */ + brcm,function = <0>; + brcm,pull = <0>; + }; + }; + }; + + __overrides__ { + sx1501-0-20 = <0>,"+0+2"; + sx1501-1-20 = <0>,"+1+3"; + sx1501-0-21 = <0>,"+0+4"; + sx1501-1-21 = <0>,"+1+5"; + sx1502-0-20 = <0>,"+0+6"; + sx1502-1-20 = <0>,"+1+7"; + sx1502-0-21 = <0>,"+0+8"; + sx1502-1-21 = <0>,"+1+9"; + sx1503-0-20 = <0>,"+0+10"; + sx1503-1-20 = <0>,"+1+11"; + sx1504-0-20 = <0>,"+0+12"; + sx1504-1-20 = <0>,"+1+13"; + sx1504-0-21 = <0>,"+0+14"; + sx1504-1-21 = <0>,"+1+15"; + sx1505-0-20 = <0>,"+0+16"; + sx1505-1-20 = <0>,"+1+17"; + sx1505-0-21 = <0>,"+0+18"; + sx1505-1-21 = <0>,"+1+19"; + sx1506-0-20 = <0>,"+0+20"; + sx1506-1-20 = <0>,"+1+21"; + sx1507-0-3E = <0>,"+0+22"; + sx1507-1-3E = <0>,"+1+23"; + sx1507-0-3F = <0>,"+0+24"; + sx1507-1-3F = <0>,"+1+25"; + sx1507-0-70 = <0>,"+0+26"; + sx1507-1-70 = <0>,"+1+27"; + sx1507-0-71 = <0>,"+0+28"; + sx1507-1-71 = <0>,"+1+29"; + sx1508-0-20 = <0>,"+0+30"; + sx1508-1-20 = <0>,"+1+31"; + sx1508-0-21 = <0>,"+0+32"; + sx1508-1-21 = <0>,"+1+33"; + sx1508-0-22 = <0>,"+0+34"; + sx1508-1-22 = <0>,"+1+35"; + sx1508-0-23 = <0>,"+0+36"; + sx1508-1-23 = <0>,"+1+37"; + sx1509-0-3E = <0>,"+0+38"; + sx1509-1-3E = <0>,"+1+39"; + sx1509-0-3F = <0>,"+0+40"; + sx1509-1-3F = <0>,"+1+41"; + sx1509-0-70 = <0>,"+0+42"; + sx1509-1-70 = <0>,"+1+43"; + sx1509-0-71 = <0>,"+0+44"; + sx1509-1-71 = <0>,"+1+45"; + sx1501-0-20-int-gpio = <0>,"+46+90", <&sx150x_0_20_pins>,"brcm,pins:0", <&sx1501_0_20>,"interrupts:0"; + sx1501-1-20-int-gpio = <0>,"+47+91", <&sx150x_1_20_pins>,"brcm,pins:0", <&sx1501_1_20>,"interrupts:0"; + sx1501-0-21-int-gpio = <0>,"+48+92", <&sx150x_0_21_pins>,"brcm,pins:0", <&sx1501_0_21>,"interrupts:0"; + sx1501-1-21-int-gpio = <0>,"+49+93", <&sx150x_1_21_pins>,"brcm,pins:0", <&sx1501_1_21>,"interrupts:0"; + sx1502-0-20-int-gpio = <0>,"+50+90", <&sx150x_0_20_pins>,"brcm,pins:0", <&sx1502_0_20>,"interrupts:0"; + sx1502-1-20-int-gpio = <0>,"+51+91", <&sx150x_1_20_pins>,"brcm,pins:0", <&sx1502_1_20>,"interrupts:0"; + sx1502-0-21-int-gpio = <0>,"+52+92", <&sx150x_0_21_pins>,"brcm,pins:0", <&sx1502_0_21>,"interrupts:0"; + sx1502-1-21-int-gpio = <0>,"+53+93", <&sx150x_1_21_pins>,"brcm,pins:0", <&sx1502_1_21>,"interrupts:0"; + sx1503-0-20-int-gpio = <0>,"+54+90", <&sx150x_0_20_pins>,"brcm,pins:0", <&sx1503_0_20>,"interrupts:0"; + sx1503-1-20-int-gpio = <0>,"+55+91", <&sx150x_1_20_pins>,"brcm,pins:0", <&sx1503_1_20>,"interrupts:0"; + sx1504-0-20-int-gpio = <0>,"+56+90", <&sx150x_0_20_pins>,"brcm,pins:0", <&sx1504_0_20>,"interrupts:0"; + sx1504-1-20-int-gpio = <0>,"+57+91", <&sx150x_1_20_pins>,"brcm,pins:0", <&sx1504_1_20>,"interrupts:0"; + sx1504-0-21-int-gpio = <0>,"+58+92", <&sx150x_0_21_pins>,"brcm,pins:0", <&sx1504_0_21>,"interrupts:0"; + sx1504-1-21-int-gpio = <0>,"+59+93", <&sx150x_1_21_pins>,"brcm,pins:0", <&sx1504_1_21>,"interrupts:0"; + sx1505-0-20-int-gpio = <0>,"+60+90", <&sx150x_0_20_pins>,"brcm,pins:0", <&sx1505_0_20>,"interrupts:0"; + sx1505-1-20-int-gpio = <0>,"+61+91", <&sx150x_1_20_pins>,"brcm,pins:0", <&sx1505_1_20>,"interrupts:0"; + sx1505-0-21-int-gpio = <0>,"+62+92", <&sx150x_0_21_pins>,"brcm,pins:0", <&sx1505_0_21>,"interrupts:0"; + sx1505-1-21-int-gpio = <0>,"+63+93", <&sx150x_1_21_pins>,"brcm,pins:0", <&sx1505_1_21>,"interrupts:0"; + sx1506-0-20-int-gpio = <0>,"+64+90", <&sx150x_0_20_pins>,"brcm,pins:0", <&sx1506_0_20>,"interrupts:0"; + sx1506-1-20-int-gpio = <0>,"+65+91", <&sx150x_1_20_pins>,"brcm,pins:0", <&sx1506_1_20>,"interrupts:0"; + sx1507-0-3E-int-gpio = <0>,"+66+98", <&sx150x_0_3E_pins>,"brcm,pins:0", <&sx1507_0_3E>,"interrupts:0"; + sx1507-1-3E-int-gpio = <0>,"+67+99", <&sx150x_1_3E_pins>,"brcm,pins:0", <&sx1507_1_3E>,"interrupts:0"; + sx1507-0-3F-int-gpio = <0>,"+68+100", <&sx150x_0_3F_pins>,"brcm,pins:0", <&sx1507_0_3F>,"interrupts:0"; + sx1507-1-3F-int-gpio = <0>,"+69+101", <&sx150x_1_3F_pins>,"brcm,pins:0", <&sx1507_1_3F>,"interrupts:0"; + sx1507-0-70-int-gpio = <0>,"+60+102", <&sx150x_0_70_pins>,"brcm,pins:0", <&sx1507_0_70>,"interrupts:0"; + sx1507-1-70-int-gpio = <0>,"+71+103", <&sx150x_1_70_pins>,"brcm,pins:0", <&sx1507_1_70>,"interrupts:0"; + sx1507-0-71-int-gpio = <0>,"+72+104", <&sx150x_0_71_pins>,"brcm,pins:0", <&sx1507_0_71>,"interrupts:0"; + sx1507-1-71-int-gpio = <0>,"+73+105", <&sx150x_1_71_pins>,"brcm,pins:0", <&sx1507_1_71>,"interrupts:0"; + sx1508-0-20-int-gpio = <0>,"+74+90", <&sx150x_0_20_pins>,"brcm,pins:0", <&sx1508_0_20>,"interrupts:0"; + sx1508-1-20-int-gpio = <0>,"+75+91", <&sx150x_1_20_pins>,"brcm,pins:0", <&sx1508_1_20>,"interrupts:0"; + sx1508-0-21-int-gpio = <0>,"+76+92", <&sx150x_0_21_pins>,"brcm,pins:0", <&sx1508_0_21>,"interrupts:0"; + sx1508-1-21-int-gpio = <0>,"+77+93", <&sx150x_1_21_pins>,"brcm,pins:0", <&sx1508_1_21>,"interrupts:0"; + sx1508-0-22-int-gpio = <0>,"+78+94", <&sx150x_0_22_pins>,"brcm,pins:0", <&sx1508_0_22>,"interrupts:0"; + sx1508-1-22-int-gpio = <0>,"+79+95", <&sx150x_1_22_pins>,"brcm,pins:0", <&sx1508_1_22>,"interrupts:0"; + sx1508-0-23-int-gpio = <0>,"+80+96", <&sx150x_0_23_pins>,"brcm,pins:0", <&sx1508_0_23>,"interrupts:0"; + sx1508-1-23-int-gpio = <0>,"+81+97", <&sx150x_1_23_pins>,"brcm,pins:0", <&sx1508_1_23>,"interrupts:0"; + sx1509-0-3E-int-gpio = <0>,"+82+98", <&sx150x_0_3E_pins>,"brcm,pins:0", <&sx1509_0_3E>,"interrupts:0"; + sx1509-1-3E-int-gpio = <0>,"+83+99", <&sx150x_1_3E_pins>,"brcm,pins:0", <&sx1509_1_3E>,"interrupts:0"; + sx1509-0-3F-int-gpio = <0>,"+84+100", <&sx150x_0_3F_pins>,"brcm,pins:0", <&sx1509_0_3F>,"interrupts:0"; + sx1509-1-3F-int-gpio = <0>,"+85+101", <&sx150x_1_3F_pins>,"brcm,pins:0", <&sx1509_1_3F>,"interrupts:0"; + sx1509-0-70-int-gpio = <0>,"+86+102", <&sx150x_0_70_pins>,"brcm,pins:0", <&sx1509_0_70>,"interrupts:0"; + sx1509-1-70-int-gpio = <0>,"+87+103", <&sx150x_1_70_pins>,"brcm,pins:0", <&sx1509_1_70>,"interrupts:0"; + sx1509-0-71-int-gpio = <0>,"+88+104", <&sx150x_0_71_pins>,"brcm,pins:0", <&sx1509_0_71>,"interrupts:0"; + sx1509-1-71-int-gpio = <0>,"+89+105", <&sx150x_1_71_pins>,"brcm,pins:0", <&sx1509_1_71>,"interrupts:0"; + }; +}; + diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts 2018-10-29 19:31:20.547782801 +0100 @@ -0,0 +1,222 @@ +/* + * tinylcd35-overlay.dts + * + * ------------------------------------------------- + * www.tinlylcd.com + * ------------------------------------------------- + * Device---Driver-----BUS GPIO's + * display tinylcd35 spi0.0 25 24 18 + * touch ads7846 spi0.1 5 + * rtc ds1307 i2c1-0068 + * rtc pcf8563 i2c1-0051 + * keypad gpio-keys --------- 17 22 27 23 28 + * + * + * TinyLCD.com 3.5 inch TFT + * + * Version 001 + * 5/3/2015 -- Noralf Trønnes Initial Device tree framework + * 10/3/2015 -- tinylcd@gmail.com added ds1307 support. + * + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev0>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&spidev1>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@3 { + target = <&gpio>; + __overlay__ { + tinylcd35_pins: tinylcd35_pins { + brcm,pins = <25 24 18>; + brcm,function = <1>; /* out */ + }; + tinylcd35_ts_pins: tinylcd35_ts_pins { + brcm,pins = <5>; + brcm,function = <0>; /* in */ + }; + keypad_pins: keypad_pins { + brcm,pins = <4 17 22 23 27>; + brcm,function = <0>; /* in */ + brcm,pull = <1>; /* down */ + }; + }; + }; + + fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + + tinylcd35: tinylcd35@0{ + compatible = "neosec,tinylcd"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&tinylcd35_pins>, + <&tinylcd35_ts_pins>; + + spi-max-frequency = <48000000>; + rotate = <270>; + fps = <20>; + bgr; + buswidth = <8>; + reset-gpios = <&gpio 25 0>; + dc-gpios = <&gpio 24 0>; + led-gpios = <&gpio 18 1>; + debug = <0>; + + init = <0x10000B0 0x80 + 0x10000C0 0x0A 0x0A + 0x10000C1 0x01 0x01 + 0x10000C2 0x33 + 0x10000C5 0x00 0x42 0x80 + 0x10000B1 0xD0 0x11 + 0x10000B4 0x02 + 0x10000B6 0x00 0x22 0x3B + 0x10000B7 0x07 + 0x1000036 0x58 + 0x10000F0 0x36 0xA5 0xD3 + 0x10000E5 0x80 + 0x10000E5 0x01 + 0x10000B3 0x00 + 0x10000E5 0x00 + 0x10000F0 0x36 0xA5 0x53 + 0x10000E0 0x00 0x35 0x33 0x00 0x00 0x00 0x00 0x35 0x33 0x00 0x00 0x00 + 0x100003A 0x55 + 0x1000011 + 0x2000001 + 0x1000029>; + }; + + tinylcd35_ts: tinylcd35_ts@1 { + compatible = "ti,ads7846"; + reg = <1>; + status = "disabled"; + + spi-max-frequency = <2000000>; + interrupts = <5 2>; /* high-to-low edge triggered */ + interrupt-parent = <&gpio>; + pendown-gpio = <&gpio 5 0>; + ti,x-plate-ohms = /bits/ 16 <100>; + ti,pressure-max = /bits/ 16 <255>; + }; + }; + }; + + /* RTC */ + + fragment@5 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + pcf8563: pcf8563@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + status = "okay"; + }; + }; + }; + + fragment@6 { + target = <&i2c1>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + ds1307: ds1307@68 { + compatible = "maxim,ds1307"; + reg = <0x68>; + status = "okay"; + }; + }; + }; + + /* + * Values for input event code is found under the + * 'Keys and buttons' heading in include/uapi/linux/input.h + */ + fragment@7 { + target-path = "/soc"; + __overlay__ { + keypad: keypad { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&keypad_pins>; + status = "disabled"; + autorepeat; + + button@17 { + label = "GPIO KEY_UP"; + linux,code = <103>; + gpios = <&gpio 17 0>; + }; + button@22 { + label = "GPIO KEY_DOWN"; + linux,code = <108>; + gpios = <&gpio 22 0>; + }; + button@27 { + label = "GPIO KEY_LEFT"; + linux,code = <105>; + gpios = <&gpio 27 0>; + }; + button@23 { + label = "GPIO KEY_RIGHT"; + linux,code = <106>; + gpios = <&gpio 23 0>; + }; + button@4 { + label = "GPIO KEY_ENTER"; + linux,code = <28>; + gpios = <&gpio 4 0>; + }; + }; + }; + }; + + __overrides__ { + speed = <&tinylcd35>,"spi-max-frequency:0"; + rotate = <&tinylcd35>,"rotate:0"; + fps = <&tinylcd35>,"fps:0"; + debug = <&tinylcd35>,"debug:0"; + touch = <&tinylcd35_ts>,"status"; + touchgpio = <&tinylcd35_ts_pins>,"brcm,pins:0", + <&tinylcd35_ts>,"interrupts:0", + <&tinylcd35_ts>,"pendown-gpio:4"; + xohms = <&tinylcd35_ts>,"ti,x-plate-ohms;0"; + rtc-pcf = <0>,"=5"; + rtc-ds = <0>,"=6"; + keypad = <&keypad>,"status"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts 2018-10-29 19:31:20.547782801 +0100 @@ -0,0 +1,44 @@ +/* + * Device Tree overlay for the Infineon SLB9670 Trusted Platform Module add-on + * boards, which can be used as a secure key storage and hwrng. + * available as "Iridium SLB9670" by Infineon and "LetsTrust TPM" by pi3g. + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&spidev1>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@2 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ + #address-cells = <1>; + #size-cells = <0>; + slb9670: slb9670@1 { + compatible = "infineon,slb9670"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <32000000>; + status = "okay"; + }; + + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/uart0-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/uart0-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/uart0-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/uart0-overlay.dts 2018-10-29 19:31:20.547782801 +0100 @@ -0,0 +1,32 @@ +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&uart0>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + uart0_pins: uart0_pins { + brcm,pins = <14 15>; + brcm,function = <4>; /* alt0 */ + brcm,pull = <0 2>; + }; + }; + }; + + __overrides__ { + txd0_pin = <&uart0_pins>,"brcm,pins:0"; + rxd0_pin = <&uart0_pins>,"brcm,pins:4"; + pin_func = <&uart0_pins>,"brcm,function:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/uart1-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/uart1-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/uart1-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/uart1-overlay.dts 2018-10-29 19:31:20.547782801 +0100 @@ -0,0 +1,38 @@ +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&uart1>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + uart1_pins: uart1_pins { + brcm,pins = <14 15>; + brcm,function = <2>; /* alt5 */ + brcm,pull = <0 2>; + }; + }; + }; + + fragment@2 { + target-path = "/chosen"; + __overlay__ { + bootargs = "8250.nr_uarts=1"; + }; + }; + + __overrides__ { + txd1_pin = <&uart1_pins>,"brcm,pins:0"; + rxd1_pin = <&uart1_pins>,"brcm,pins:4"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/upstream-aux-interrupt-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/upstream-aux-interrupt-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/upstream-aux-interrupt-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/upstream-aux-interrupt-overlay.dts 2018-10-29 19:31:20.548782751 +0100 @@ -0,0 +1,33 @@ +// Overlay for missing AUX interrupt controller +// Instead we bind all AUX devices to the generic AUX interrupt line +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&uart1>; + __overlay__ { + interrupt-parent = <&intc>; + interrupts = <0x1 0x1d>; + }; + }; + + fragment@1 { + target = <&spi1>; + __overlay__ { + interrupt-parent = <&intc>; + interrupts = <0x1 0x1d>; + }; + }; + + fragment@2 { + target = <&spi2>; + __overlay__ { + interrupt-parent = <&intc>; + interrupts = <0x1 0x1d>; + }; + }; +}; + diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/upstream-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/upstream-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/upstream-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/upstream-overlay.dts 2018-10-29 19:31:20.548782751 +0100 @@ -0,0 +1,154 @@ +// redo: ovmerge -c vc4-kms-v3d-overlay.dts,cma-96 dwc2-overlay.dts,dr_mode=otg upstream-aux-interrupt-overlay.dts, + +/dts-v1/; +/plugin/; + +#include + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + fragment@0 { + target-path = "/chosen"; + __dormant__ { + bootargs = "cma=256M"; + }; + }; + fragment@1 { + target-path = "/chosen"; + __dormant__ { + bootargs = "cma=192M"; + }; + }; + fragment@2 { + target-path = "/chosen"; + __dormant__ { + bootargs = "cma=128M"; + }; + }; + fragment@3 { + target-path = "/chosen"; + __overlay__ { + bootargs = "cma=96M"; + }; + }; + fragment@4 { + target-path = "/chosen"; + __dormant__ { + bootargs = "cma=64M"; + }; + }; + fragment@5 { + target = <&i2c2>; + __overlay__ { + status = "okay"; + }; + }; + fragment@6 { + target = <&fb>; + __overlay__ { + status = "disabled"; + }; + }; + fragment@7 { + target = <&pixelvalve0>; + __overlay__ { + interrupts = <2 13>; + status = "okay"; + }; + }; + fragment@8 { + target = <&pixelvalve1>; + __overlay__ { + interrupts = <2 14>; + status = "okay"; + }; + }; + fragment@9 { + target = <&pixelvalve2>; + __overlay__ { + interrupts = <2 10>; + status = "okay"; + }; + }; + fragment@10 { + target = <&hvs>; + __overlay__ { + interrupts = <2 1>; + status = "okay"; + }; + }; + fragment@11 { + target = <&hdmi>; + __overlay__ { + interrupts = <2 8>, <2 9>; + status = "okay"; + }; + }; + fragment@12 { + target = <&v3d>; + __overlay__ { + interrupts = <1 10>; + status = "okay"; + }; + }; + fragment@13 { + target = <&vc4>; + __overlay__ { + status = "okay"; + }; + }; + fragment@14 { + target-path = "/soc/dma"; + __overlay__ { + brcm,dma-channel-mask = <0x7f35>; + }; + }; + fragment@15 { + target = <&clocks>; + __overlay__ { + claim-clocks = ; + }; + }; + fragment@16 { + target = <&vec>; + __overlay__ { + status = "okay"; + }; + }; + fragment@17 { + target = <&usb>; + #address-cells = <1>; + #size-cells = <1>; + dwc2_usb: __overlay__ { + compatible = "brcm,bcm2835-usb"; + reg = <0x7e980000 0x10000>; + interrupts = <1 9>; + dr_mode = "otg"; + g-np-tx-fifo-size = <32>; + g-rx-fifo-size = <256>; + g-tx-fifo-size = <512 512 512 512 512 256 256>; + status = "okay"; + }; + }; + fragment@18 { + target = <&uart1>; + __overlay__ { + interrupt-parent = <&intc>; + interrupts = <0x1 0x1d>; + }; + }; + fragment@19 { + target = <&spi1>; + __overlay__ { + interrupt-parent = <&intc>; + interrupts = <0x1 0x1d>; + }; + }; + fragment@20 { + target = <&spi2>; + __overlay__ { + interrupt-parent = <&intc>; + interrupts = <0x1 0x1d>; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts 2018-10-29 19:31:20.548782751 +0100 @@ -0,0 +1,89 @@ +/* + * vc4-fkms-v3d-overlay.dts + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target-path = "/chosen"; + __overlay__ { + bootargs = "cma=256M"; + }; + }; + + fragment@1 { + target-path = "/chosen"; + __dormant__ { + bootargs = "cma=192M"; + }; + }; + + fragment@2 { + target-path = "/chosen"; + __dormant__ { + bootargs = "cma=128M"; + }; + }; + + fragment@3 { + target-path = "/chosen"; + __dormant__ { + bootargs = "cma=96M"; + }; + }; + + fragment@4 { + target-path = "/chosen"; + __dormant__ { + bootargs = "cma=64M"; + }; + }; + + fragment@5 { + target = <&fb>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@6 { + target = <&firmwarekms>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@7 { + target = <&v3d>; + __overlay__ { + interrupts = <1 10>; + status = "okay"; + }; + }; + + fragment@8 { + target = <&vc4>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@9 { + target-path = "/soc/dma"; + __overlay__ { + brcm,dma-channel-mask = <0x7f35>; + }; + }; + + __overrides__ { + cma-256 = <0>,"+0-1-2-3-4"; + cma-192 = <0>,"-0+1-2-3-4"; + cma-128 = <0>,"-0-1+2-3-4"; + cma-96 = <0>,"-0-1-2+3-4"; + cma-64 = <0>,"-0-1-2-3+4"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts 2018-10-29 19:31:20.548782751 +0100 @@ -0,0 +1,151 @@ +/* + * vc4-kms-v3d-overlay.dts + */ + +/dts-v1/; +/plugin/; + +#include + +/ { + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target-path = "/chosen"; + __overlay__ { + bootargs = "cma=256M"; + }; + }; + + fragment@1 { + target-path = "/chosen"; + __dormant__ { + bootargs = "cma=192M"; + }; + }; + + fragment@2 { + target-path = "/chosen"; + __dormant__ { + bootargs = "cma=128M"; + }; + }; + + fragment@3 { + target-path = "/chosen"; + __dormant__ { + bootargs = "cma=96M"; + }; + }; + + fragment@4 { + target-path = "/chosen"; + __dormant__ { + bootargs = "cma=64M"; + }; + }; + + fragment@5 { + target = <&i2c2>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@6 { + target = <&fb>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@7 { + target = <&pixelvalve0>; + __overlay__ { + interrupts = <2 13>; /* pwa0 */ + status = "okay"; + }; + }; + + fragment@8 { + target = <&pixelvalve1>; + __overlay__ { + interrupts = <2 14>; /* pwa1 */ + status = "okay"; + }; + }; + + fragment@9 { + target = <&pixelvalve2>; + __overlay__ { + interrupts = <2 10>; /* pixelvalve */ + status = "okay"; + }; + }; + + fragment@10 { + target = <&hvs>; + __overlay__ { + interrupts = <2 1>; + status = "okay"; + }; + }; + + fragment@11 { + target = <&hdmi>; + __overlay__ { + interrupts = <2 8>, <2 9>; + status = "okay"; + }; + }; + + fragment@12 { + target = <&v3d>; + __overlay__ { + interrupts = <1 10>; + status = "okay"; + }; + }; + + fragment@13 { + target = <&vc4>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@14 { + target-path = "/soc/dma"; + __overlay__ { + brcm,dma-channel-mask = <0x7f35>; + }; + }; + + + fragment@15 { + target = <&clocks>; + __overlay__ { + claim-clocks = < + BCM2835_PLLD_DSI0 + BCM2835_PLLD_DSI1 + BCM2835_PLLH_AUX + BCM2835_PLLH_PIX + >; + }; + }; + + fragment@16 { + target = <&vec>; + __overlay__ { + status = "okay"; + }; + }; + + __overrides__ { + cma-256 = <0>,"+0-1-2-3-4"; + cma-192 = <0>,"-0+1-2-3-4"; + cma-128 = <0>,"-0-1+2-3-4"; + cma-96 = <0>,"-0-1-2+3-4"; + cma-64 = <0>,"-0-1-2-3+4"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/vga666-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/vga666-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/vga666-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/vga666-overlay.dts 2018-10-29 19:31:20.548782751 +0100 @@ -0,0 +1,30 @@ +/dts-v1/; +/plugin/; + +/{ + compatible = "brcm,bcm2708"; + + // There is no VGA driver module, but we need a platform device + // node (that doesn't already use pinctrl) to hang the pinctrl + // reference on - leds will do + + fragment@0 { + target = <&leds>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&vga666_pins>; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + vga666_pins: vga666_pins { + brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 + 13 14 15 16 17 18 19 20 21>; + brcm,function = <6>; /* alt2 */ + brcm,pull = <0>; /* no pull */ + }; + }; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts 2018-10-29 19:31:20.548782751 +0100 @@ -0,0 +1,41 @@ +// Definitions for w1-gpio module (without external pullup) +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/"; + __overlay__ { + + w1: onewire@0 { + compatible = "w1-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&w1_pins>; + gpios = <&gpio 4 0>; + rpi,parasitic-power = <0>; + status = "okay"; + }; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + w1_pins: w1_pins@0 { + brcm,pins = <4>; + brcm,function = <0>; // in (initially) + brcm,pull = <0>; // off + }; + }; + }; + + __overrides__ { + gpiopin = <&w1>,"gpios:4", + <&w1>,"reg:0", + <&w1_pins>,"brcm,pins:0", + <&w1_pins>,"reg:0"; + pullup = <&w1>,"rpi,parasitic-power:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts 2018-10-29 19:31:20.548782751 +0100 @@ -0,0 +1,43 @@ +// Definitions for w1-gpio module (with external pullup) +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target-path = "/"; + __overlay__ { + + w1: onewire@0 { + compatible = "w1-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&w1_pins>; + gpios = <&gpio 4 0>, <&gpio 5 1>; + rpi,parasitic-power = <0>; + status = "okay"; + }; + }; + }; + + fragment@1 { + target = <&gpio>; + __overlay__ { + w1_pins: w1_pins@0 { + brcm,pins = <4 5>; + brcm,function = <0 1>; // in out + brcm,pull = <0 0>; // off off + }; + }; + }; + + __overrides__ { + gpiopin = <&w1>,"gpios:4", + <&w1>,"reg:0", + <&w1_pins>,"brcm,pins:0", + <&w1_pins>,"reg:0"; + extpullup = <&w1>,"gpios:16", + <&w1_pins>,"brcm,pins:4"; + pullup = <&w1>,"rpi,parasitic-power:0"; + }; +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/boot/dts/overlays/wittypi-overlay.dts linux-vendor/arch/arm/boot/dts/overlays/wittypi-overlay.dts --- linux-4.18.16/arch/arm/boot/dts/overlays/wittypi-overlay.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/boot/dts/overlays/wittypi-overlay.dts 2018-10-29 19:31:20.549782701 +0100 @@ -0,0 +1,44 @@ +/* + * Device Tree overlay for Witty Pi extension board by UUGear + * + */ + +/dts-v1/; +/plugin/; + +/ { + + compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; + + fragment@0 { + target = <&leds>; + __overlay__ { + compatible = "gpio-leds"; + wittypi_led: wittypi_led { + label = "wittypi_led"; + linux,default-trigger = "default-on"; + gpios = <&gpio 17 0>; + }; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + rtc: ds1337@68 { + compatible = "dallas,ds1337"; + reg = <0x68>; + wakeup-source; + }; + }; + }; + + __overrides__ { + led_gpio = <&wittypi_led>,"gpios:4"; + led_trigger = <&wittypi_led>,"linux,default-trigger"; + }; + +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/configs/bcm2709_defconfig linux-vendor/arch/arm/configs/bcm2709_defconfig --- linux-4.18.16/arch/arm/configs/bcm2709_defconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/configs/bcm2709_defconfig 2018-10-29 19:31:20.558782253 +0100 @@ -0,0 +1,1370 @@ +CONFIG_LOCALVERSION="-v7" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_GENERIC_IRQ_DEBUGFS=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=m +CONFIG_IKCONFIG_PROC=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EMBEDDED=y +# CONFIG_COMPAT_BRK is not set +CONFIG_PROFILING=y +CONFIG_OPROFILE=m +CONFIG_KPROBES=y +CONFIG_JUMP_LABEL=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLK_DEV_THROTTLING=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_MAC_PARTITION=y +CONFIG_CFQ_GROUP_IOSCHED=y +CONFIG_ARCH_BCM=y +CONFIG_ARCH_BCM2835=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_SMP=y +CONFIG_VMSPLIT_2G=y +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_CPU_SW_DOMAIN_PAN is not set +CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +CONFIG_CMA=y +CONFIG_ZSMALLOC=m +CONFIG_PGTABLE_MAPPING=y +CONFIG_UACCESS_WITH_MEMCPY=y +CONFIG_SECCOMP=y +# CONFIG_ATAGS is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait" +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_KERNEL_MODE_NEON=y +CONFIG_BINFMT_MISC=m +# CONFIG_SUSPEND is not set +CONFIG_PM=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=y +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BBR=m +CONFIG_IPV6=m +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_SIT_6RD=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_PE_SIP=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_ATM=m +CONFIG_L2TP=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_ATALK=m +CONFIG_6LOWPAN=m +CONFIG_IEEE802154=m +CONFIG_IEEE802154_6LOWPAN=m +CONFIG_MAC802154=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=m +CONFIG_NET_SCH_FQ=m +CONFIG_NET_SCH_HHF=m +CONFIG_NET_SCH_PIE=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_IPSET=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_BATMAN_ADV=m +CONFIG_OPENVSWITCH=m +CONFIG_NET_PKTGEN=m +CONFIG_HAMRADIO=y +CONFIG_AX25=m +CONFIG_NETROM=m +CONFIG_ROSE=m +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_YAM=m +CONFIG_CAN=m +CONFIG_CAN_VCAN=m +CONFIG_CAN_SLCAN=m +CONFIG_CAN_MCP251X=m +CONFIG_CAN_GS_USB=m +CONFIG_BT=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m +CONFIG_BT_6LOWPAN=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m +CONFIG_BT_WILINK=m +CONFIG_CFG80211=m +CONFIG_MAC80211=m +CONFIG_MAC80211_MESH=y +CONFIG_WIMAX=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=y +CONFIG_NET_9P=m +CONFIG_NFC=m +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=5 +CONFIG_MTD=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_NAND=m +CONFIG_MTD_SPI_NOR=m +CONFIG_MTD_UBI=m +CONFIG_OF_CONFIGFS=y +CONFIG_ZRAM=m +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_CDROM_PKTCDVD=m +CONFIG_ATA_OVER_ETH=m +CONFIG_EEPROM_AT24=m +CONFIG_TI_ST=m +CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_CHR_DEV_SG=m +CONFIG_SCSI_ISCSI_ATTRS=y +CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m +CONFIG_MD=y +CONFIG_MD_LINEAR=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m +CONFIG_DM_ZERO=m +CONFIG_DM_DELAY=m +CONFIG_NETDEVICES=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_IFB=m +CONFIG_MACVLAN=m +CONFIG_IPVLAN=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_ENC28J60=m +CONFIG_QCA7000_SPI=m +CONFIG_MDIO_BITBANG=m +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_HUAWEI_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SR9700=m +CONFIG_USB_NET_SR9800=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=y +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=m +CONFIG_USB_NET_CX82310_ETH=m +CONFIG_USB_NET_KALMIA=m +CONFIG_USB_NET_QMI_WWAN=m +CONFIG_USB_HSO=m +CONFIG_USB_NET_INT51X1=m +CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m +CONFIG_ATH9K=m +CONFIG_ATH9K_HTC=m +CONFIG_CARL9170=m +CONFIG_ATH6KL=m +CONFIG_ATH6KL_USB=m +CONFIG_AR5523=m +CONFIG_AT76C50X_USB=m +CONFIG_B43=m +# CONFIG_B43_PHY_N is not set +CONFIG_B43LEGACY=m +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_USB=y +CONFIG_BRCMDBG=y +CONFIG_HOSTAP=m +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_THINFIRM=m +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_MWIFIEX=m +CONFIG_MWIFIEX_SDIO=m +CONFIG_MT7601U=m +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RTL8187=m +CONFIG_RTL8192CU=m +CONFIG_RTL8XXXU=m +CONFIG_USB_ZD1201=m +CONFIG_ZD1211RW=m +CONFIG_MAC80211_HWSIM=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_WIMAX_I2400M_USB=m +CONFIG_IEEE802154_AT86RF230=m +CONFIG_IEEE802154_MRF24J40=m +CONFIG_IEEE802154_CC2520=m +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_GPIO=m +CONFIG_KEYBOARD_MATRIX=m +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_PSXPAD_SPI=m +CONFIG_JOYSTICK_PSXPAD_SPI_FF=y +CONFIG_JOYSTICK_RPISENSE=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_EGALAX=m +CONFIG_TOUCHSCREEN_EXC3000=m +CONFIG_TOUCHSCREEN_GOODIX=m +CONFIG_TOUCHSCREEN_EDT_FT5X06=m +CONFIG_TOUCHSCREEN_RPI_FT5406=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_STMPE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_AD714X=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_YEALINK=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m +CONFIG_INPUT_ADXL34X=m +CONFIG_INPUT_CMA3000=m +CONFIG_SERIO=m +CONFIG_SERIO_RAW=m +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_BRCM_CHAR_DRIVERS=y +CONFIG_BCM_VCIO=y +CONFIG_BCM_VC_SM=y +CONFIG_BCM2835_DEVGPIOMEM=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=0 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_BCM2835AUX=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_SC16IS7XX=m +CONFIG_SERIAL_SC16IS7XX_SPI=y +CONFIG_SERIAL_DEV_BUS=m +CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y +CONFIG_RAW_DRIVER=y +CONFIG_TCG_TPM=m +CONFIG_TCG_TIS_CORE=m +CONFIG_TCG_TIS_SPI=m +# CONFIG_SECURITYFS is not set +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_MUX=m +CONFIG_I2C_MUX_GPMUX=m +CONFIG_I2C_MUX_PCA954x=m +CONFIG_I2C_BCM2708=m +CONFIG_I2C_BCM2835=m +CONFIG_I2C_GPIO=m +CONFIG_I2C_ROBOTFUZZ_OSIF=m +CONFIG_I2C_TINY_USB=m +CONFIG_SPI=y +CONFIG_SPI_BCM2835=m +CONFIG_SPI_BCM2835AUX=m +CONFIG_SPI_GPIO=m +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_SLAVE=y +CONFIG_PPS=m +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PPS_CLIENT_GPIO=m +CONFIG_PINCTRL_MCP23S08=m +CONFIG_GPIO_BCM_VIRT=y +CONFIG_GPIO_MOCKUP=m +CONFIG_GPIO_PCF857X=m +CONFIG_GPIO_ARIZONA=m +CONFIG_GPIO_STMPE=y +CONFIG_W1=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS1WM=m +CONFIG_W1_MASTER_GPIO=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2408=m +CONFIG_W1_SLAVE_DS2413=m +CONFIG_W1_SLAVE_DS2406=m +CONFIG_W1_SLAVE_DS2423=m +CONFIG_W1_SLAVE_DS2431=m +CONFIG_W1_SLAVE_DS2433=m +CONFIG_W1_SLAVE_DS2438=m +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_DS2780=m +CONFIG_W1_SLAVE_DS2781=m +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_GPIO=y +CONFIG_BATTERY_DS2760=m +CONFIG_BATTERY_GAUGE_LTC2941=m +CONFIG_HWMON=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_JC42=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_RPI_POE_FAN=m +CONFIG_SENSORS_SHT21=m +CONFIG_SENSORS_SHT3x=m +CONFIG_SENSORS_SHTC1=m +CONFIG_SENSORS_ADS1015=m +CONFIG_SENSORS_INA2XX=m +CONFIG_SENSORS_TMP102=m +CONFIG_THERMAL=y +CONFIG_BCM2835_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_GPIO_WATCHDOG=m +CONFIG_BCM2835_WDT=y +CONFIG_MFD_STMPE=y +CONFIG_STMPE_SPI=y +CONFIG_MFD_ARIZONA_I2C=m +CONFIG_MFD_ARIZONA_SPI=m +CONFIG_MFD_WM5102=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=m +CONFIG_REGULATOR_ARIZONA_LDO1=m +CONFIG_REGULATOR_ARIZONA_MICSUPP=m +CONFIG_RC_CORE=y +CONFIG_LIRC=y +CONFIG_RC_DECODERS=y +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_IR_IMON_DECODER=m +CONFIG_RC_DEVICES=y +CONFIG_RC_ATI_REMOTE=m +CONFIG_IR_IMON=m +CONFIG_IR_MCEUSB=m +CONFIG_IR_REDRAT3=m +CONFIG_IR_STREAMZAP=m +CONFIG_IR_IGUANA=m +CONFIG_IR_TTUSBIR=m +CONFIG_RC_LOOPBACK=m +CONFIG_IR_GPIO_CIR=m +CONFIG_IR_GPIO_TX=m +CONFIG_IR_PWM_TX=m +CONFIG_MEDIA_SUPPORT=m +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GL860=m +CONFIG_USB_GSPCA_BENQ=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_CPIA1=m +CONFIG_USB_GSPCA_DTCS033=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_USB_GSPCA_JL2005BCD=m +CONFIG_USB_GSPCA_KINECT=m +CONFIG_USB_GSPCA_KONICA=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_NW80X=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_OV534_9=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7302=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SE401=m +CONFIG_USB_GSPCA_SN9C2028=m +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SPCA1528=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_SQ930X=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_STK1135=m +CONFIG_USB_GSPCA_STV0680=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TOPRO=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_VICAM=m +CONFIG_USB_GSPCA_XIRLINK_CIT=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_USB_PWC=m +CONFIG_VIDEO_CPIA2=m +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +CONFIG_VIDEO_USBTV=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_STK1160_COMMON=m +CONFIG_VIDEO_GO7007=m +CONFIG_VIDEO_GO7007_USB=m +CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_AU0828_RC=y +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_VIDEO_TM6000=m +CONFIG_VIDEO_TM6000_ALSA=m +CONFIG_VIDEO_TM6000_DVB=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_PCTV452E=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_FRIIO=m +CONFIG_DVB_USB_AZ6027=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_V2=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_AF9035=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_AZ6007=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_LME2510=m +CONFIG_DVB_USB_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +CONFIG_DVB_USB_DVBSKY=m +CONFIG_SMS_USB_DRV=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_AS102=m +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_V4L2=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_RADIO_SI470X=m +CONFIG_USB_SI470X=m +CONFIG_I2C_SI470X=m +CONFIG_RADIO_SI4713=m +CONFIG_I2C_SI4713=m +CONFIG_USB_MR800=m +CONFIG_USB_DSBR=m +CONFIG_RADIO_SHARK=m +CONFIG_RADIO_SHARK2=m +CONFIG_USB_KEENE=m +CONFIG_USB_MA901=m +CONFIG_RADIO_TEA5764=m +CONFIG_RADIO_SAA7706H=m +CONFIG_RADIO_TEF6862=m +CONFIG_RADIO_WL1273=m +CONFIG_RADIO_WL128X=m +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_VIDEO_UDA1342=m +CONFIG_VIDEO_SONY_BTF_MPX=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_TW2804=m +CONFIG_VIDEO_TW9903=m +CONFIG_VIDEO_TW9906=m +CONFIG_VIDEO_OV7640=m +CONFIG_VIDEO_MT9V011=m +CONFIG_DRM=m +CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_UDL=m +CONFIG_DRM_PANEL_SIMPLE=m +CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m +CONFIG_DRM_VC4=m +CONFIG_DRM_TINYDRM=m +CONFIG_TINYDRM_MI0283QT=m +CONFIG_TINYDRM_REPAPER=m +CONFIG_FB=y +CONFIG_FB_BCM2708=y +CONFIG_FB_UDL=m +CONFIG_FB_SSD1307=m +CONFIG_FB_RPISENSE=m +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_RPI=m +CONFIG_BACKLIGHT_GPIO=m +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=m +CONFIG_SND_HRTIMER=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_DUMMY=m +CONFIG_SND_ALOOP=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_UA101=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_6FIRE=m +CONFIG_SND_USB_HIFACE=m +CONFIG_SND_SOC=m +CONFIG_SND_BCM2835_SOC_I2S=m +CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m +CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m +CONFIG_SND_BCM2708_SOC_RPI_DAC=m +CONFIG_SND_BCM2708_SOC_RPI_PROTO=m +CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m +CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m +CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m +CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m +CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m +CONFIG_SND_DIGIDAC1_SOUNDCARD=m +CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m +CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m +CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m +CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC_PLUS=m +CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC=m +CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m +CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m +CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m +CONFIG_SND_PISOUND=m +CONFIG_SND_SOC_ADAU1701=m +CONFIG_SND_SOC_ADAU7002=m +CONFIG_SND_SOC_AK4554=m +CONFIG_SND_SOC_CS4271_I2C=m +CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SOC_WM8804_I2C=m +CONFIG_SND_SIMPLE_CARD=m +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +CONFIG_UHID=m +CONFIG_HID_A4TECH=m +CONFIG_HID_ACRUX=m +CONFIG_HID_APPLE=m +CONFIG_HID_ASUS=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BETOP_FF=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DRAGONRISE=m +CONFIG_HID_EMS_FF=m +CONFIG_HID_ELECOM=m +CONFIG_HID_ELO=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GEMBIRD=m +CONFIG_HID_HOLTEK=m +CONFIG_HID_KEYTOUCH=m +CONFIG_HID_KYE=m +CONFIG_HID_UCLOGIC=m +CONFIG_HID_WALTOP=m +CONFIG_HID_GYRATION=m +CONFIG_HID_TWINHAN=m +CONFIG_HID_KENSINGTON=m +CONFIG_HID_LCPOWER=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_LOGITECH_DJ=m +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_HID_MAGICMOUSE=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_MULTITOUCH=m +CONFIG_HID_NTRIG=m +CONFIG_HID_ORTEK=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_PICOLCD=m +CONFIG_HID_ROCCAT=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_SONY_FF=y +CONFIG_HID_SPEEDLINK=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_GREENASIA=m +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_HID_TOPSEED=m +CONFIG_HID_THINGM=m +CONFIG_HID_THRUSTMASTER=m +CONFIG_HID_WACOM=m +CONFIG_HID_WIIMOTE=m +CONFIG_HID_XINMO=m +CONFIG_HID_ZEROPLUS=m +CONFIG_HID_ZYDACRON=m +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=m +CONFIG_USB_DWCOTG=y +CONFIG_USB_PRINTER=m +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_REALTEK=m +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +CONFIG_USB_STORAGE_ENE_UB6250=m +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USBIP_CORE=m +CONFIG_USBIP_VHCI_HCD=m +CONFIG_USBIP_HOST=m +CONFIG_USB_DWC2=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_F81232=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_METRO=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_QCAUX=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SYMBOL=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_USB_SERIAL_XSENS_MT=m +CONFIG_USB_SERIAL_WISHBONE=m +CONFIG_USB_SERIAL_SSU100=m +CONFIG_USB_SERIAL_QT2=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_TEST=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_YUREX=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_GADGET=m +CONFIG_USB_ZERO=m +CONFIG_USB_AUDIO=m +CONFIG_USB_ETH=m +CONFIG_USB_GADGETFS=m +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_G_PRINTER=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_G_ACM_MS=m +CONFIG_USB_G_MULTI=m +CONFIG_USB_G_HID=m +CONFIG_USB_G_WEBCAM=m +CONFIG_MMC=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BCM2835_MMC=y +CONFIG_MMC_BCM2835_DMA=y +CONFIG_MMC_BCM2835_SDHOST=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SPI=m +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_TRANSIENT=m +CONFIG_LEDS_TRIGGER_CAMERA=m +CONFIG_LEDS_TRIGGER_INPUT=y +CONFIG_LEDS_TRIGGER_PANIC=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_HCTOSYS is not set +CONFIG_RTC_DRV_ABX80X=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_ISL12022=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_PCF8523=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_BQ32K=m +CONFIG_RTC_DRV_S35390A=m +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_RX8581=m +CONFIG_RTC_DRV_RX8025=m +CONFIG_RTC_DRV_EM3027=m +CONFIG_RTC_DRV_M41T93=m +CONFIG_RTC_DRV_M41T94=m +CONFIG_RTC_DRV_DS1302=m +CONFIG_RTC_DRV_DS1305=m +CONFIG_RTC_DRV_DS1390=m +CONFIG_RTC_DRV_R9701=m +CONFIG_RTC_DRV_RX4581=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF2123=m +CONFIG_RTC_DRV_DS3232=m +CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_RV3029C2=m +CONFIG_DMADEVICES=y +CONFIG_DMA_BCM2835=y +CONFIG_DMA_BCM2708=y +CONFIG_UIO=m +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_STAGING=y +CONFIG_PRISM2_USB=m +CONFIG_R8712U=m +CONFIG_R8188EU=m +CONFIG_VT6656=m +CONFIG_SPEAKUP=m +CONFIG_SPEAKUP_SYNTH_SOFT=m +CONFIG_STAGING_MEDIA=y +CONFIG_FB_TFT=m +CONFIG_FB_TFT_AGM1264K_FL=m +CONFIG_FB_TFT_BD663474=m +CONFIG_FB_TFT_HX8340BN=m +CONFIG_FB_TFT_HX8347D=m +CONFIG_FB_TFT_HX8353D=m +CONFIG_FB_TFT_HX8357D=m +CONFIG_FB_TFT_ILI9163=m +CONFIG_FB_TFT_ILI9320=m +CONFIG_FB_TFT_ILI9325=m +CONFIG_FB_TFT_ILI9340=m +CONFIG_FB_TFT_ILI9341=m +CONFIG_FB_TFT_ILI9481=m +CONFIG_FB_TFT_ILI9486=m +CONFIG_FB_TFT_PCD8544=m +CONFIG_FB_TFT_RA8875=m +CONFIG_FB_TFT_S6D02A1=m +CONFIG_FB_TFT_S6D1121=m +CONFIG_FB_TFT_SSD1289=m +CONFIG_FB_TFT_SSD1306=m +CONFIG_FB_TFT_SSD1331=m +CONFIG_FB_TFT_SSD1351=m +CONFIG_FB_TFT_ST7735R=m +CONFIG_FB_TFT_ST7789V=m +CONFIG_FB_TFT_TINYLCD=m +CONFIG_FB_TFT_TLS8204=m +CONFIG_FB_TFT_UC1701=m +CONFIG_FB_TFT_UPD161704=m +CONFIG_FB_TFT_WATTEROTT=m +CONFIG_FB_FLEX=m +CONFIG_FB_TFT_FBTFT_DEVICE=m +CONFIG_BCM2835_VCHIQ=y +CONFIG_SND_BCM2835=m +CONFIG_VIDEO_BCM2835=m +CONFIG_MAILBOX=y +CONFIG_BCM2835_MBOX=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_RASPBERRYPI_POWER=y +CONFIG_EXTCON=m +CONFIG_EXTCON_ARIZONA=m +CONFIG_IIO=m +CONFIG_IIO_BUFFER_CB=m +CONFIG_MCP320X=m +CONFIG_MCP3422=m +CONFIG_DHT11=m +CONFIG_HDC100X=m +CONFIG_HTU21=m +CONFIG_INV_MPU6050_I2C=m +CONFIG_TSL4531=m +CONFIG_VEML6070=m +CONFIG_BMP280=m +CONFIG_PWM_BCM2835=m +CONFIG_PWM_PCA9685=m +CONFIG_RPI_AXIPERF=m +CONFIG_RASPBERRYPI_FIRMWARE=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +CONFIG_GFS2_FS=m +CONFIG_OCFS2_FS=m +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_NILFS2_FS=m +CONFIG_F2FS_FS=y +CONFIG_FANOTIFY=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_OVERLAY_FS=m +CONFIG_FSCACHE=y +CONFIG_FSCACHE_STATS=y +CONFIG_FSCACHE_HISTOGRAM=y +CONFIG_CACHEFILES=y +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +CONFIG_NTFS_FS=m +CONFIG_NTFS_RW=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_ECRYPT_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_SUMMARY=y +CONFIG_UBIFS_FS=m +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +CONFIG_ROOT_NFS=y +CONFIG_NFS_FSCACHE=y +CONFIG_NFSD=m +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_CIFS=m +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_ACL=y +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_FSCACHE=y +CONFIG_9P_FS=m +CONFIG_9P_FS_POSIX_ACL=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_DLM=m +CONFIG_PRINTK_TIME=y +CONFIG_BOOT_PRINTK_DELAY=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_RCU_TRACE is not set +CONFIG_LATENCYTOP=y +CONFIG_IRQSOFF_TRACER=y +CONFIG_SCHED_TRACER=y +CONFIG_STACK_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_UPROBE_EVENTS is not set +CONFIG_FUNCTION_PROFILER=y +CONFIG_KGDB=y +CONFIG_KGDB_KDB=y +CONFIG_KDB_KEYBOARD=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +# CONFIG_CRYPTO_HW is not set +CONFIG_ARM_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM_NEON=m +CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRYPTO_AES_ARM_BS=m +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/configs/bcmrpi_defconfig linux-vendor/arch/arm/configs/bcmrpi_defconfig --- linux-4.18.16/arch/arm/configs/bcmrpi_defconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/configs/bcmrpi_defconfig 2018-10-29 19:31:20.558782253 +0100 @@ -0,0 +1,1363 @@ +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_GENERIC_IRQ_DEBUGFS=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=m +CONFIG_IKCONFIG_PROC=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EMBEDDED=y +# CONFIG_COMPAT_BRK is not set +CONFIG_PROFILING=y +CONFIG_OPROFILE=m +CONFIG_KPROBES=y +CONFIG_JUMP_LABEL=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLK_DEV_THROTTLING=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_MAC_PARTITION=y +CONFIG_CFQ_GROUP_IOSCHED=y +CONFIG_ARCH_MULTI_V6=y +# CONFIG_ARCH_MULTI_V7 is not set +CONFIG_ARCH_BCM=y +CONFIG_ARCH_BCM2835=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_CPU_SW_DOMAIN_PAN is not set +CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +CONFIG_CMA=y +CONFIG_ZSMALLOC=m +CONFIG_PGTABLE_MAPPING=y +CONFIG_UACCESS_WITH_MEMCPY=y +CONFIG_SECCOMP=y +# CONFIG_ATAGS is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait" +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_VFP=y +CONFIG_BINFMT_MISC=m +# CONFIG_SUSPEND is not set +CONFIG_PM=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=y +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BBR=m +CONFIG_IPV6=m +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_SIT_6RD=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_PE_SIP=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_ATM=m +CONFIG_L2TP=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_ATALK=m +CONFIG_6LOWPAN=m +CONFIG_IEEE802154=m +CONFIG_IEEE802154_6LOWPAN=m +CONFIG_MAC802154=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=m +CONFIG_NET_SCH_FQ=m +CONFIG_NET_SCH_HHF=m +CONFIG_NET_SCH_PIE=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_IPSET=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_BATMAN_ADV=m +CONFIG_OPENVSWITCH=m +CONFIG_NET_PKTGEN=m +CONFIG_HAMRADIO=y +CONFIG_AX25=m +CONFIG_NETROM=m +CONFIG_ROSE=m +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_YAM=m +CONFIG_CAN=m +CONFIG_CAN_VCAN=m +CONFIG_CAN_SLCAN=m +CONFIG_CAN_MCP251X=m +CONFIG_CAN_GS_USB=m +CONFIG_BT=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m +CONFIG_BT_6LOWPAN=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m +CONFIG_BT_WILINK=m +CONFIG_CFG80211=m +CONFIG_MAC80211=m +CONFIG_MAC80211_MESH=y +CONFIG_WIMAX=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=y +CONFIG_NET_9P=m +CONFIG_NFC=m +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=5 +CONFIG_MTD=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_NAND=m +CONFIG_MTD_SPI_NOR=m +CONFIG_MTD_UBI=m +CONFIG_OF_CONFIGFS=y +CONFIG_ZRAM=m +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_CDROM_PKTCDVD=m +CONFIG_ATA_OVER_ETH=m +CONFIG_EEPROM_AT24=m +CONFIG_TI_ST=m +CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_CHR_DEV_SG=m +CONFIG_SCSI_ISCSI_ATTRS=y +CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m +CONFIG_MD=y +CONFIG_MD_LINEAR=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m +CONFIG_DM_ZERO=m +CONFIG_DM_DELAY=m +CONFIG_NETDEVICES=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_IFB=m +CONFIG_MACVLAN=m +CONFIG_IPVLAN=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_ENC28J60=m +CONFIG_QCA7000_SPI=m +CONFIG_MDIO_BITBANG=m +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=m +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_HUAWEI_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SR9700=m +CONFIG_USB_NET_SR9800=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=y +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=m +CONFIG_USB_NET_CX82310_ETH=m +CONFIG_USB_NET_KALMIA=m +CONFIG_USB_NET_QMI_WWAN=m +CONFIG_USB_HSO=m +CONFIG_USB_NET_INT51X1=m +CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m +CONFIG_ATH9K=m +CONFIG_ATH9K_HTC=m +CONFIG_CARL9170=m +CONFIG_ATH6KL=m +CONFIG_ATH6KL_USB=m +CONFIG_AR5523=m +CONFIG_AT76C50X_USB=m +CONFIG_B43=m +# CONFIG_B43_PHY_N is not set +CONFIG_B43LEGACY=m +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_USB=y +CONFIG_BRCMDBG=y +CONFIG_HOSTAP=m +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_THINFIRM=m +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_MWIFIEX=m +CONFIG_MWIFIEX_SDIO=m +CONFIG_MT7601U=m +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RTL8187=m +CONFIG_RTL8192CU=m +CONFIG_RTL8XXXU=m +CONFIG_USB_ZD1201=m +CONFIG_ZD1211RW=m +CONFIG_MAC80211_HWSIM=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_WIMAX_I2400M_USB=m +CONFIG_IEEE802154_AT86RF230=m +CONFIG_IEEE802154_MRF24J40=m +CONFIG_IEEE802154_CC2520=m +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_GPIO=m +CONFIG_KEYBOARD_MATRIX=m +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_PSXPAD_SPI=m +CONFIG_JOYSTICK_PSXPAD_SPI_FF=y +CONFIG_JOYSTICK_RPISENSE=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_EGALAX=m +CONFIG_TOUCHSCREEN_EXC3000=m +CONFIG_TOUCHSCREEN_GOODIX=m +CONFIG_TOUCHSCREEN_EDT_FT5X06=m +CONFIG_TOUCHSCREEN_RPI_FT5406=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_STMPE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_AD714X=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_YEALINK=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m +CONFIG_INPUT_ADXL34X=m +CONFIG_INPUT_CMA3000=m +CONFIG_SERIO=m +CONFIG_SERIO_RAW=m +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_BRCM_CHAR_DRIVERS=y +CONFIG_BCM_VCIO=y +CONFIG_BCM_VC_SM=y +CONFIG_BCM2835_DEVGPIOMEM=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=0 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_BCM2835AUX=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_SC16IS7XX=m +CONFIG_SERIAL_SC16IS7XX_SPI=y +CONFIG_SERIAL_DEV_BUS=m +CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y +CONFIG_RAW_DRIVER=y +CONFIG_TCG_TPM=m +CONFIG_TCG_TIS_CORE=m +CONFIG_TCG_TIS_SPI=m +# CONFIG_SECURITYFS is not set +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_MUX=m +CONFIG_I2C_MUX_GPMUX=m +CONFIG_I2C_MUX_PCA954x=m +CONFIG_I2C_BCM2708=m +CONFIG_I2C_BCM2835=m +CONFIG_I2C_GPIO=m +CONFIG_I2C_ROBOTFUZZ_OSIF=m +CONFIG_I2C_TINY_USB=m +CONFIG_SPI=y +CONFIG_SPI_BCM2835=m +CONFIG_SPI_BCM2835AUX=m +CONFIG_SPI_GPIO=m +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_SLAVE=y +CONFIG_PPS=m +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PPS_CLIENT_GPIO=m +CONFIG_PINCTRL_MCP23S08=m +CONFIG_GPIO_MOCKUP=m +CONFIG_GPIO_PCF857X=m +CONFIG_GPIO_ARIZONA=m +CONFIG_GPIO_STMPE=y +CONFIG_W1=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS1WM=m +CONFIG_W1_MASTER_GPIO=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2408=m +CONFIG_W1_SLAVE_DS2413=m +CONFIG_W1_SLAVE_DS2406=m +CONFIG_W1_SLAVE_DS2423=m +CONFIG_W1_SLAVE_DS2431=m +CONFIG_W1_SLAVE_DS2433=m +CONFIG_W1_SLAVE_DS2438=m +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_DS2780=m +CONFIG_W1_SLAVE_DS2781=m +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_GPIO=y +CONFIG_BATTERY_DS2760=m +CONFIG_BATTERY_GAUGE_LTC2941=m +CONFIG_HWMON=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_JC42=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_RPI_POE_FAN=m +CONFIG_SENSORS_SHT21=m +CONFIG_SENSORS_SHT3x=m +CONFIG_SENSORS_SHTC1=m +CONFIG_SENSORS_ADS1015=m +CONFIG_SENSORS_INA2XX=m +CONFIG_SENSORS_TMP102=m +CONFIG_THERMAL=y +CONFIG_BCM2835_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_GPIO_WATCHDOG=m +CONFIG_BCM2835_WDT=y +CONFIG_MFD_STMPE=y +CONFIG_STMPE_SPI=y +CONFIG_MFD_ARIZONA_I2C=m +CONFIG_MFD_ARIZONA_SPI=m +CONFIG_MFD_WM5102=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=m +CONFIG_REGULATOR_ARIZONA_LDO1=m +CONFIG_REGULATOR_ARIZONA_MICSUPP=m +CONFIG_RC_CORE=y +CONFIG_LIRC=y +CONFIG_RC_DECODERS=y +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_IR_IMON_DECODER=m +CONFIG_RC_DEVICES=y +CONFIG_RC_ATI_REMOTE=m +CONFIG_IR_IMON=m +CONFIG_IR_MCEUSB=m +CONFIG_IR_REDRAT3=m +CONFIG_IR_STREAMZAP=m +CONFIG_IR_IGUANA=m +CONFIG_IR_TTUSBIR=m +CONFIG_RC_LOOPBACK=m +CONFIG_IR_GPIO_CIR=m +CONFIG_IR_GPIO_TX=m +CONFIG_IR_PWM_TX=m +CONFIG_MEDIA_SUPPORT=m +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GL860=m +CONFIG_USB_GSPCA_BENQ=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_CPIA1=m +CONFIG_USB_GSPCA_DTCS033=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_USB_GSPCA_JL2005BCD=m +CONFIG_USB_GSPCA_KINECT=m +CONFIG_USB_GSPCA_KONICA=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_NW80X=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_OV534_9=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7302=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SE401=m +CONFIG_USB_GSPCA_SN9C2028=m +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SPCA1528=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_SQ930X=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_STK1135=m +CONFIG_USB_GSPCA_STV0680=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TOPRO=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_VICAM=m +CONFIG_USB_GSPCA_XIRLINK_CIT=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_USB_PWC=m +CONFIG_VIDEO_CPIA2=m +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +CONFIG_VIDEO_USBTV=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_STK1160_COMMON=m +CONFIG_VIDEO_GO7007=m +CONFIG_VIDEO_GO7007_USB=m +CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_AU0828_RC=y +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_VIDEO_TM6000=m +CONFIG_VIDEO_TM6000_ALSA=m +CONFIG_VIDEO_TM6000_DVB=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_PCTV452E=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_FRIIO=m +CONFIG_DVB_USB_AZ6027=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_V2=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_AF9035=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_AZ6007=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_LME2510=m +CONFIG_DVB_USB_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +CONFIG_DVB_USB_DVBSKY=m +CONFIG_SMS_USB_DRV=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_AS102=m +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_V4L2=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_RADIO_SI470X=m +CONFIG_USB_SI470X=m +CONFIG_I2C_SI470X=m +CONFIG_RADIO_SI4713=m +CONFIG_I2C_SI4713=m +CONFIG_USB_MR800=m +CONFIG_USB_DSBR=m +CONFIG_RADIO_SHARK=m +CONFIG_RADIO_SHARK2=m +CONFIG_USB_KEENE=m +CONFIG_USB_MA901=m +CONFIG_RADIO_TEA5764=m +CONFIG_RADIO_SAA7706H=m +CONFIG_RADIO_TEF6862=m +CONFIG_RADIO_WL1273=m +CONFIG_RADIO_WL128X=m +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_VIDEO_UDA1342=m +CONFIG_VIDEO_SONY_BTF_MPX=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_TW2804=m +CONFIG_VIDEO_TW9903=m +CONFIG_VIDEO_TW9906=m +CONFIG_VIDEO_OV7640=m +CONFIG_VIDEO_MT9V011=m +CONFIG_DRM=m +CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_UDL=m +CONFIG_DRM_PANEL_SIMPLE=m +CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m +CONFIG_DRM_VC4=m +CONFIG_DRM_TINYDRM=m +CONFIG_TINYDRM_MI0283QT=m +CONFIG_TINYDRM_REPAPER=m +CONFIG_FB=y +CONFIG_FB_BCM2708=y +CONFIG_FB_UDL=m +CONFIG_FB_SSD1307=m +CONFIG_FB_RPISENSE=m +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_RPI=m +CONFIG_BACKLIGHT_GPIO=m +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=m +CONFIG_SND_HRTIMER=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_DUMMY=m +CONFIG_SND_ALOOP=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_UA101=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_6FIRE=m +CONFIG_SND_USB_HIFACE=m +CONFIG_SND_SOC=m +CONFIG_SND_BCM2835_SOC_I2S=m +CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m +CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m +CONFIG_SND_BCM2708_SOC_RPI_DAC=m +CONFIG_SND_BCM2708_SOC_RPI_PROTO=m +CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m +CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m +CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m +CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m +CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m +CONFIG_SND_DIGIDAC1_SOUNDCARD=m +CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m +CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m +CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m +CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC_PLUS=m +CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC=m +CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m +CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m +CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m +CONFIG_SND_PISOUND=m +CONFIG_SND_SOC_ADAU1701=m +CONFIG_SND_SOC_ADAU7002=m +CONFIG_SND_SOC_AK4554=m +CONFIG_SND_SOC_CS4271_I2C=m +CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SOC_WM8804_I2C=m +CONFIG_SND_SIMPLE_CARD=m +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +CONFIG_UHID=m +CONFIG_HID_A4TECH=m +CONFIG_HID_ACRUX=m +CONFIG_HID_APPLE=m +CONFIG_HID_ASUS=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BETOP_FF=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DRAGONRISE=m +CONFIG_HID_EMS_FF=m +CONFIG_HID_ELECOM=m +CONFIG_HID_ELO=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GEMBIRD=m +CONFIG_HID_HOLTEK=m +CONFIG_HID_KEYTOUCH=m +CONFIG_HID_KYE=m +CONFIG_HID_UCLOGIC=m +CONFIG_HID_WALTOP=m +CONFIG_HID_GYRATION=m +CONFIG_HID_TWINHAN=m +CONFIG_HID_KENSINGTON=m +CONFIG_HID_LCPOWER=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_LOGITECH_DJ=m +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_HID_MAGICMOUSE=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_MULTITOUCH=m +CONFIG_HID_NTRIG=m +CONFIG_HID_ORTEK=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_PICOLCD=m +CONFIG_HID_ROCCAT=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_SONY_FF=y +CONFIG_HID_SPEEDLINK=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_GREENASIA=m +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_HID_TOPSEED=m +CONFIG_HID_THINGM=m +CONFIG_HID_THRUSTMASTER=m +CONFIG_HID_WACOM=m +CONFIG_HID_WIIMOTE=m +CONFIG_HID_XINMO=m +CONFIG_HID_ZEROPLUS=m +CONFIG_HID_ZYDACRON=m +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=m +CONFIG_USB_DWCOTG=y +CONFIG_USB_PRINTER=m +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_REALTEK=m +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +CONFIG_USB_STORAGE_ENE_UB6250=m +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USBIP_CORE=m +CONFIG_USBIP_VHCI_HCD=m +CONFIG_USBIP_HOST=m +CONFIG_USB_DWC2=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_F81232=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_METRO=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_QCAUX=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SYMBOL=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_USB_SERIAL_XSENS_MT=m +CONFIG_USB_SERIAL_WISHBONE=m +CONFIG_USB_SERIAL_SSU100=m +CONFIG_USB_SERIAL_QT2=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_TEST=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_YUREX=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_GADGET=m +CONFIG_USB_ZERO=m +CONFIG_USB_AUDIO=m +CONFIG_USB_ETH=m +CONFIG_USB_GADGETFS=m +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_G_PRINTER=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_G_ACM_MS=m +CONFIG_USB_G_MULTI=m +CONFIG_USB_G_HID=m +CONFIG_USB_G_WEBCAM=m +CONFIG_MMC=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BCM2835_MMC=y +CONFIG_MMC_BCM2835_DMA=y +CONFIG_MMC_BCM2835_SDHOST=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SPI=m +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_TRANSIENT=m +CONFIG_LEDS_TRIGGER_CAMERA=m +CONFIG_LEDS_TRIGGER_INPUT=y +CONFIG_LEDS_TRIGGER_PANIC=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_HCTOSYS is not set +CONFIG_RTC_DRV_ABX80X=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_ISL12022=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_PCF8523=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_BQ32K=m +CONFIG_RTC_DRV_S35390A=m +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_RX8581=m +CONFIG_RTC_DRV_RX8025=m +CONFIG_RTC_DRV_EM3027=m +CONFIG_RTC_DRV_M41T93=m +CONFIG_RTC_DRV_M41T94=m +CONFIG_RTC_DRV_DS1302=m +CONFIG_RTC_DRV_DS1305=m +CONFIG_RTC_DRV_DS1390=m +CONFIG_RTC_DRV_R9701=m +CONFIG_RTC_DRV_RX4581=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF2123=m +CONFIG_RTC_DRV_DS3232=m +CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_RV3029C2=m +CONFIG_DMADEVICES=y +CONFIG_DMA_BCM2835=y +CONFIG_DMA_BCM2708=y +CONFIG_UIO=m +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_STAGING=y +CONFIG_PRISM2_USB=m +CONFIG_R8712U=m +CONFIG_R8188EU=m +CONFIG_VT6656=m +CONFIG_SPEAKUP=m +CONFIG_SPEAKUP_SYNTH_SOFT=m +CONFIG_STAGING_MEDIA=y +CONFIG_FB_TFT=m +CONFIG_FB_TFT_AGM1264K_FL=m +CONFIG_FB_TFT_BD663474=m +CONFIG_FB_TFT_HX8340BN=m +CONFIG_FB_TFT_HX8347D=m +CONFIG_FB_TFT_HX8353D=m +CONFIG_FB_TFT_HX8357D=m +CONFIG_FB_TFT_ILI9163=m +CONFIG_FB_TFT_ILI9320=m +CONFIG_FB_TFT_ILI9325=m +CONFIG_FB_TFT_ILI9340=m +CONFIG_FB_TFT_ILI9341=m +CONFIG_FB_TFT_ILI9481=m +CONFIG_FB_TFT_ILI9486=m +CONFIG_FB_TFT_PCD8544=m +CONFIG_FB_TFT_RA8875=m +CONFIG_FB_TFT_S6D02A1=m +CONFIG_FB_TFT_S6D1121=m +CONFIG_FB_TFT_SSD1289=m +CONFIG_FB_TFT_SSD1306=m +CONFIG_FB_TFT_SSD1331=m +CONFIG_FB_TFT_SSD1351=m +CONFIG_FB_TFT_ST7735R=m +CONFIG_FB_TFT_ST7789V=m +CONFIG_FB_TFT_TINYLCD=m +CONFIG_FB_TFT_TLS8204=m +CONFIG_FB_TFT_UC1701=m +CONFIG_FB_TFT_UPD161704=m +CONFIG_FB_TFT_WATTEROTT=m +CONFIG_FB_FLEX=m +CONFIG_FB_TFT_FBTFT_DEVICE=m +CONFIG_BCM2835_VCHIQ=y +CONFIG_SND_BCM2835=m +CONFIG_VIDEO_BCM2835=m +CONFIG_MAILBOX=y +CONFIG_BCM2835_MBOX=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_RASPBERRYPI_POWER=y +CONFIG_EXTCON=m +CONFIG_EXTCON_ARIZONA=m +CONFIG_IIO=m +CONFIG_IIO_BUFFER_CB=m +CONFIG_MCP320X=m +CONFIG_MCP3422=m +CONFIG_DHT11=m +CONFIG_HDC100X=m +CONFIG_HTU21=m +CONFIG_INV_MPU6050_I2C=m +CONFIG_TSL4531=m +CONFIG_VEML6070=m +CONFIG_BMP280=m +CONFIG_PWM_BCM2835=m +CONFIG_PWM_PCA9685=m +CONFIG_RPI_AXIPERF=m +CONFIG_RASPBERRYPI_FIRMWARE=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +CONFIG_GFS2_FS=m +CONFIG_OCFS2_FS=m +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_NILFS2_FS=m +CONFIG_F2FS_FS=y +CONFIG_FANOTIFY=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_OVERLAY_FS=m +CONFIG_FSCACHE=y +CONFIG_FSCACHE_STATS=y +CONFIG_FSCACHE_HISTOGRAM=y +CONFIG_CACHEFILES=y +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +CONFIG_NTFS_FS=m +CONFIG_NTFS_RW=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_ECRYPT_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_SUMMARY=y +CONFIG_UBIFS_FS=m +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +CONFIG_ROOT_NFS=y +CONFIG_NFS_FSCACHE=y +CONFIG_NFSD=m +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_CIFS=m +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_ACL=y +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_FSCACHE=y +CONFIG_9P_FS=m +CONFIG_9P_FS_POSIX_ACL=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_DLM=m +CONFIG_PRINTK_TIME=y +CONFIG_BOOT_PRINTK_DELAY=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DETECT_HUNG_TASK=y +CONFIG_LATENCYTOP=y +CONFIG_IRQSOFF_TRACER=y +CONFIG_SCHED_TRACER=y +CONFIG_STACK_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_UPROBE_EVENTS is not set +CONFIG_FUNCTION_PROFILER=y +CONFIG_KGDB=y +CONFIG_KGDB_KDB=y +CONFIG_KDB_KEYBOARD=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +# CONFIG_CRYPTO_HW is not set +CONFIG_ARM_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM=m +CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/include/asm/cacheflush.h linux-vendor/arch/arm/include/asm/cacheflush.h --- linux-4.18.16/arch/arm/include/asm/cacheflush.h 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/include/asm/cacheflush.h 2018-10-29 19:31:20.563782003 +0100 @@ -94,6 +94,21 @@ * DMA Cache Coherency * =================== * + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * - start - virtual start address + * - end - virtual end address + * + * dma_clean_range(start, end) + * + * Clean (write back) the specified virtual address range. + * - start - virtual start address + * - end - virtual end address + * * dma_flush_range(start, end) * * Clean and invalidate the specified virtual address range. @@ -115,6 +130,8 @@ void (*dma_map_area)(const void *, size_t, int); void (*dma_unmap_area)(const void *, size_t, int); + void (*dma_inv_range)(const void *, const void *); + void (*dma_clean_range)(const void *, const void *); void (*dma_flush_range)(const void *, const void *); } __no_randomize_layout; @@ -140,6 +157,8 @@ * is visible to DMA, or data written by DMA to system memory is * visible to the CPU. */ +#define dmac_inv_range cpu_cache.dma_inv_range +#define dmac_clean_range cpu_cache.dma_clean_range #define dmac_flush_range cpu_cache.dma_flush_range #else @@ -159,6 +178,8 @@ * is visible to DMA, or data written by DMA to system memory is * visible to the CPU. */ +extern void dmac_inv_range(const void *, const void *); +extern void dmac_clean_range(const void *, const void *); extern void dmac_flush_range(const void *, const void *); #endif diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/include/asm/glue-cache.h linux-vendor/arch/arm/include/asm/glue-cache.h --- linux-4.18.16/arch/arm/include/asm/glue-cache.h 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/include/asm/glue-cache.h 2018-10-29 19:31:20.564781953 +0100 @@ -158,6 +158,8 @@ #define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range) #define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area) +#define dmac_inv_range __glue(_CACHE,_dma_inv_range) +#define dmac_clean_range __glue(_CACHE,_dma_clean_range) #define dmac_flush_range __glue(_CACHE,_dma_flush_range) #endif diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/include/asm/irqflags.h linux-vendor/arch/arm/include/asm/irqflags.h --- linux-4.18.16/arch/arm/include/asm/irqflags.h 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/include/asm/irqflags.h 2018-10-29 19:31:20.564781953 +0100 @@ -163,13 +163,23 @@ } /* - * restore saved IRQ & FIQ state + * restore saved IRQ state */ #define arch_local_irq_restore arch_local_irq_restore static inline void arch_local_irq_restore(unsigned long flags) { - asm volatile( - " msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore" + unsigned long temp = 0; + flags &= ~(1 << 6); + asm volatile ( + " mrs %0, cpsr" + : "=r" (temp) + : + : "memory", "cc"); + /* Preserve FIQ bit */ + temp &= (1 << 6); + flags = flags | temp; + asm volatile ( + " msr cpsr_c, %0 @ local_irq_restore" : : "r" (flags) : "memory", "cc"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/include/asm/string.h linux-vendor/arch/arm/include/asm/string.h --- linux-4.18.16/arch/arm/include/asm/string.h 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/include/asm/string.h 2018-10-29 19:31:20.564781953 +0100 @@ -39,4 +39,9 @@ return __memset64(p, v, n * 8, v >> 32); } +#ifdef CONFIG_BCM2835_FAST_MEMCPY +#define __HAVE_ARCH_MEMCMP +extern int memcmp(const void *, const void *, size_t); +#endif + #endif diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/include/asm/uaccess.h linux-vendor/arch/arm/include/asm/uaccess.h --- linux-4.18.16/arch/arm/include/asm/uaccess.h 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/include/asm/uaccess.h 2018-10-29 19:31:20.565781903 +0100 @@ -447,6 +447,9 @@ extern unsigned long __must_check arm_copy_from_user(void *to, const void __user *from, unsigned long n); +extern unsigned long __must_check +__copy_from_user_std(void *to, const void __user *from, unsigned long n); + static inline unsigned long __must_check raw_copy_from_user(void *to, const void __user *from, unsigned long n) { diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/kernel/fiqasm.S linux-vendor/arch/arm/kernel/fiqasm.S --- linux-4.18.16/arch/arm/kernel/fiqasm.S 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/kernel/fiqasm.S 2018-10-29 19:31:20.573781505 +0100 @@ -47,3 +47,7 @@ mov r0, r0 @ avoid hazard prior to ARMv4 ret lr ENDPROC(__get_fiq_regs) + +ENTRY(__FIQ_Branch) + mov pc, r8 +ENDPROC(__FIQ_Branch) diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/kernel/fiq.c linux-vendor/arch/arm/kernel/fiq.c --- linux-4.18.16/arch/arm/kernel/fiq.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/kernel/fiq.c 2018-10-29 19:31:20.573781505 +0100 @@ -56,6 +56,8 @@ static unsigned long dfl_fiq_insn; static struct pt_regs dfl_fiq_regs; +extern int irq_activate(struct irq_desc *desc); + /* Default reacquire function * - we always relinquish FIQ control * - we always reacquire FIQ control @@ -140,6 +142,8 @@ void enable_fiq(int fiq) { + struct irq_desc *desc = irq_to_desc(fiq + fiq_start); + irq_activate(desc); enable_irq(fiq + fiq_start); } diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/kernel/reboot.c linux-vendor/arch/arm/kernel/reboot.c --- linux-4.18.16/arch/arm/kernel/reboot.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/kernel/reboot.c 2018-10-29 19:31:20.575781405 +0100 @@ -105,9 +105,7 @@ */ void machine_halt(void) { - local_irq_disable(); - smp_send_stop(); - while (1); + machine_power_off(); } /* diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/lib/arm-mem.h linux-vendor/arch/arm/lib/arm-mem.h --- linux-4.18.16/arch/arm/lib/arm-mem.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/lib/arm-mem.h 2018-10-29 19:31:20.575781405 +0100 @@ -0,0 +1,159 @@ +/* +Copyright (c) 2013, Raspberry Pi Foundation +Copyright (c) 2013, RISC OS Open Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +.macro myfunc fname + .func fname + .global fname +fname: +.endm + +.macro preload_leading_step1 backwards, ptr, base +/* If the destination is already 16-byte aligned, then we need to preload + * between 0 and prefetch_distance (inclusive) cache lines ahead so there + * are no gaps when the inner loop starts. + */ + .if backwards + sub ptr, base, #1 + bic ptr, ptr, #31 + .else + bic ptr, base, #31 + .endif + .set OFFSET, 0 + .rept prefetch_distance+1 + pld [ptr, #OFFSET] + .if backwards + .set OFFSET, OFFSET-32 + .else + .set OFFSET, OFFSET+32 + .endif + .endr +.endm + +.macro preload_leading_step2 backwards, ptr, base, leading_bytes, tmp +/* However, if the destination is not 16-byte aligned, we may need to + * preload one more cache line than that. The question we need to ask is: + * are the leading bytes more than the amount by which the source + * pointer will be rounded down for preloading, and if so, by how many + * cache lines? + */ + .if backwards +/* Here we compare against how many bytes we are into the + * cache line, counting down from the highest such address. + * Effectively, we want to calculate + * leading_bytes = dst&15 + * cacheline_offset = 31-((src-leading_bytes-1)&31) + * extra_needed = leading_bytes - cacheline_offset + * and test if extra_needed is <= 0, or rearranging: + * leading_bytes + (src-leading_bytes-1)&31 <= 31 + */ + mov tmp, base, lsl #32-5 + sbc tmp, tmp, leading_bytes, lsl #32-5 + adds tmp, tmp, leading_bytes, lsl #32-5 + bcc 61f + pld [ptr, #-32*(prefetch_distance+1)] + .else +/* Effectively, we want to calculate + * leading_bytes = (-dst)&15 + * cacheline_offset = (src+leading_bytes)&31 + * extra_needed = leading_bytes - cacheline_offset + * and test if extra_needed is <= 0. + */ + mov tmp, base, lsl #32-5 + add tmp, tmp, leading_bytes, lsl #32-5 + rsbs tmp, tmp, leading_bytes, lsl #32-5 + bls 61f + pld [ptr, #32*(prefetch_distance+1)] + .endif +61: +.endm + +.macro preload_trailing backwards, base, remain, tmp + /* We need either 0, 1 or 2 extra preloads */ + .if backwards + rsb tmp, base, #0 + mov tmp, tmp, lsl #32-5 + .else + mov tmp, base, lsl #32-5 + .endif + adds tmp, tmp, remain, lsl #32-5 + adceqs tmp, tmp, #0 + /* The instruction above has two effects: ensures Z is only + * set if C was clear (so Z indicates that both shifted quantities + * were 0), and clears C if Z was set (so C indicates that the sum + * of the shifted quantities was greater and not equal to 32) */ + beq 82f + .if backwards + sub tmp, base, #1 + bic tmp, tmp, #31 + .else + bic tmp, base, #31 + .endif + bcc 81f + .if backwards + pld [tmp, #-32*(prefetch_distance+1)] +81: + pld [tmp, #-32*prefetch_distance] + .else + pld [tmp, #32*(prefetch_distance+2)] +81: + pld [tmp, #32*(prefetch_distance+1)] + .endif +82: +.endm + +.macro preload_all backwards, narrow_case, shift, base, remain, tmp0, tmp1 + .if backwards + sub tmp0, base, #1 + bic tmp0, tmp0, #31 + pld [tmp0] + sub tmp1, base, remain, lsl #shift + .else + bic tmp0, base, #31 + pld [tmp0] + add tmp1, base, remain, lsl #shift + sub tmp1, tmp1, #1 + .endif + bic tmp1, tmp1, #31 + cmp tmp1, tmp0 + beq 92f + .if narrow_case + /* In this case, all the data fits in either 1 or 2 cache lines */ + pld [tmp1] + .else +91: + .if backwards + sub tmp0, tmp0, #32 + .else + add tmp0, tmp0, #32 + .endif + cmp tmp0, tmp1 + pld [tmp0] + bne 91b + .endif +92: +.endm diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/lib/copy_from_user.S linux-vendor/arch/arm/lib/copy_from_user.S --- linux-4.18.16/arch/arm/lib/copy_from_user.S 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/lib/copy_from_user.S 2018-10-29 19:31:20.576781355 +0100 @@ -89,11 +89,13 @@ .text -ENTRY(arm_copy_from_user) +ENTRY(__copy_from_user_std) +WEAK(arm_copy_from_user) #include "copy_template.S" ENDPROC(arm_copy_from_user) +ENDPROC(__copy_from_user_std) .pushsection .fixup,"ax" .align 0 diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/lib/exports_rpi.c linux-vendor/arch/arm/lib/exports_rpi.c --- linux-4.18.16/arch/arm/lib/exports_rpi.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/lib/exports_rpi.c 2018-10-29 19:31:20.576781355 +0100 @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2014, Raspberry Pi (Trading) Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2, as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +EXPORT_SYMBOL(memcmp); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/lib/Makefile linux-vendor/arch/arm/lib/Makefile --- linux-4.18.16/arch/arm/lib/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/lib/Makefile 2018-10-29 19:31:20.575781405 +0100 @@ -7,8 +7,8 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ csumpartialcopy.o csumpartialcopyuser.o clearbit.o \ - delay.o delay-loop.o findbit.o memchr.o memcpy.o \ - memmove.o memset.o setbit.o \ + delay.o delay-loop.o findbit.o memchr.o \ + setbit.o \ strchr.o strrchr.o \ testchangebit.o testclearbit.o testsetbit.o \ ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ @@ -19,6 +19,16 @@ mmu-y := clear_user.o copy_page.o getuser.o putuser.o \ copy_from_user.o copy_to_user.o +# Choose optimised implementations for Raspberry Pi +ifeq ($(CONFIG_BCM2835_FAST_MEMCPY),y) + CFLAGS_uaccess_with_memcpy.o += -DCOPY_FROM_USER_THRESHOLD=1600 + CFLAGS_uaccess_with_memcpy.o += -DCOPY_TO_USER_THRESHOLD=672 + obj-$(CONFIG_MODULES) += exports_rpi.o + lib-y += memcpy_rpi.o memmove_rpi.o memset_rpi.o memcmp_rpi.o +else + lib-y += memcpy.o memmove.o memset.o +endif + # using lib_ here won't override already available weak symbols obj-$(CONFIG_UACCESS_WITH_MEMCPY) += uaccess_with_memcpy.o diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/lib/memcmp_rpi.S linux-vendor/arch/arm/lib/memcmp_rpi.S --- linux-4.18.16/arch/arm/lib/memcmp_rpi.S 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/lib/memcmp_rpi.S 2018-10-29 19:31:20.576781355 +0100 @@ -0,0 +1,285 @@ +/* +Copyright (c) 2013, Raspberry Pi Foundation +Copyright (c) 2013, RISC OS Open Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include "arm-mem.h" + +/* Prevent the stack from becoming executable */ +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + + .text + .arch armv6 + .object_arch armv4 + .arm + .altmacro + .p2align 2 + +.macro memcmp_process_head unaligned + .if unaligned + ldr DAT0, [S_1], #4 + ldr DAT1, [S_1], #4 + ldr DAT2, [S_1], #4 + ldr DAT3, [S_1], #4 + .else + ldmia S_1!, {DAT0, DAT1, DAT2, DAT3} + .endif + ldmia S_2!, {DAT4, DAT5, DAT6, DAT7} +.endm + +.macro memcmp_process_tail + cmp DAT0, DAT4 + cmpeq DAT1, DAT5 + cmpeq DAT2, DAT6 + cmpeq DAT3, DAT7 + bne 200f +.endm + +.macro memcmp_leading_31bytes + movs DAT0, OFF, lsl #31 + ldrmib DAT0, [S_1], #1 + ldrcsh DAT1, [S_1], #2 + ldrmib DAT4, [S_2], #1 + ldrcsh DAT5, [S_2], #2 + movpl DAT0, #0 + movcc DAT1, #0 + movpl DAT4, #0 + movcc DAT5, #0 + submi N, N, #1 + subcs N, N, #2 + cmp DAT0, DAT4 + cmpeq DAT1, DAT5 + bne 200f + movs DAT0, OFF, lsl #29 + ldrmi DAT0, [S_1], #4 + ldrcs DAT1, [S_1], #4 + ldrcs DAT2, [S_1], #4 + ldrmi DAT4, [S_2], #4 + ldmcsia S_2!, {DAT5, DAT6} + movpl DAT0, #0 + movcc DAT1, #0 + movcc DAT2, #0 + movpl DAT4, #0 + movcc DAT5, #0 + movcc DAT6, #0 + submi N, N, #4 + subcs N, N, #8 + cmp DAT0, DAT4 + cmpeq DAT1, DAT5 + cmpeq DAT2, DAT6 + bne 200f + tst OFF, #16 + beq 105f + memcmp_process_head 1 + sub N, N, #16 + memcmp_process_tail +105: +.endm + +.macro memcmp_trailing_15bytes unaligned + movs N, N, lsl #29 + .if unaligned + ldrcs DAT0, [S_1], #4 + ldrcs DAT1, [S_1], #4 + .else + ldmcsia S_1!, {DAT0, DAT1} + .endif + ldrmi DAT2, [S_1], #4 + ldmcsia S_2!, {DAT4, DAT5} + ldrmi DAT6, [S_2], #4 + movcc DAT0, #0 + movcc DAT1, #0 + movpl DAT2, #0 + movcc DAT4, #0 + movcc DAT5, #0 + movpl DAT6, #0 + cmp DAT0, DAT4 + cmpeq DAT1, DAT5 + cmpeq DAT2, DAT6 + bne 200f + movs N, N, lsl #2 + ldrcsh DAT0, [S_1], #2 + ldrmib DAT1, [S_1] + ldrcsh DAT4, [S_2], #2 + ldrmib DAT5, [S_2] + movcc DAT0, #0 + movpl DAT1, #0 + movcc DAT4, #0 + movpl DAT5, #0 + cmp DAT0, DAT4 + cmpeq DAT1, DAT5 + bne 200f +.endm + +.macro memcmp_long_inner_loop unaligned +110: + memcmp_process_head unaligned + pld [S_2, #prefetch_distance*32 + 16] + memcmp_process_tail + memcmp_process_head unaligned + pld [S_1, OFF] + memcmp_process_tail + subs N, N, #32 + bhs 110b + /* Just before the final (prefetch_distance+1) 32-byte blocks, + * deal with final preloads */ + preload_trailing 0, S_1, N, DAT0 + preload_trailing 0, S_2, N, DAT0 + add N, N, #(prefetch_distance+2)*32 - 16 +120: + memcmp_process_head unaligned + memcmp_process_tail + subs N, N, #16 + bhs 120b + /* Trailing words and bytes */ + tst N, #15 + beq 199f + memcmp_trailing_15bytes unaligned +199: /* Reached end without detecting a difference */ + mov a1, #0 + setend le + pop {DAT1-DAT6, pc} +.endm + +.macro memcmp_short_inner_loop unaligned + subs N, N, #16 /* simplifies inner loop termination */ + blo 122f +120: + memcmp_process_head unaligned + memcmp_process_tail + subs N, N, #16 + bhs 120b +122: /* Trailing words and bytes */ + tst N, #15 + beq 199f + memcmp_trailing_15bytes unaligned +199: /* Reached end without detecting a difference */ + mov a1, #0 + setend le + pop {DAT1-DAT6, pc} +.endm + +/* + * int memcmp(const void *s1, const void *s2, size_t n); + * On entry: + * a1 = pointer to buffer 1 + * a2 = pointer to buffer 2 + * a3 = number of bytes to compare (as unsigned chars) + * On exit: + * a1 = >0/=0/<0 if s1 >/=/< s2 + */ + +.set prefetch_distance, 2 + +ENTRY(memcmp) + S_1 .req a1 + S_2 .req a2 + N .req a3 + DAT0 .req a4 + DAT1 .req v1 + DAT2 .req v2 + DAT3 .req v3 + DAT4 .req v4 + DAT5 .req v5 + DAT6 .req v6 + DAT7 .req ip + OFF .req lr + + push {DAT1-DAT6, lr} + setend be /* lowest-addressed bytes are most significant */ + + /* To preload ahead as we go, we need at least (prefetch_distance+2) 32-byte blocks */ + cmp N, #(prefetch_distance+3)*32 - 1 + blo 170f + + /* Long case */ + /* Adjust N so that the decrement instruction can also test for + * inner loop termination. We want it to stop when there are + * (prefetch_distance+1) complete blocks to go. */ + sub N, N, #(prefetch_distance+2)*32 + preload_leading_step1 0, DAT0, S_1 + preload_leading_step1 0, DAT1, S_2 + tst S_2, #31 + beq 154f + rsb OFF, S_2, #0 /* no need to AND with 15 here */ + preload_leading_step2 0, DAT0, S_1, OFF, DAT2 + preload_leading_step2 0, DAT1, S_2, OFF, DAT2 + memcmp_leading_31bytes +154: /* Second source now cacheline (32-byte) aligned; we have at + * least one prefetch to go. */ + /* Prefetch offset is best selected such that it lies in the + * first 8 of each 32 bytes - but it's just as easy to aim for + * the first one */ + and OFF, S_1, #31 + rsb OFF, OFF, #32*prefetch_distance + tst S_1, #3 + bne 140f + memcmp_long_inner_loop 0 +140: memcmp_long_inner_loop 1 + +170: /* Short case */ + teq N, #0 + beq 199f + preload_all 0, 0, 0, S_1, N, DAT0, DAT1 + preload_all 0, 0, 0, S_2, N, DAT0, DAT1 + tst S_2, #3 + beq 174f +172: subs N, N, #1 + blo 199f + ldrb DAT0, [S_1], #1 + ldrb DAT4, [S_2], #1 + cmp DAT0, DAT4 + bne 200f + tst S_2, #3 + bne 172b +174: /* Second source now 4-byte aligned; we have 0 or more bytes to go */ + tst S_1, #3 + bne 140f + memcmp_short_inner_loop 0 +140: memcmp_short_inner_loop 1 + +200: /* Difference found: determine sign. */ + movhi a1, #1 + movlo a1, #-1 + setend le + pop {DAT1-DAT6, pc} + + .unreq S_1 + .unreq S_2 + .unreq N + .unreq DAT0 + .unreq DAT1 + .unreq DAT2 + .unreq DAT3 + .unreq DAT4 + .unreq DAT5 + .unreq DAT6 + .unreq DAT7 + .unreq OFF +ENDPROC(memcmp) diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/lib/memcpymove.h linux-vendor/arch/arm/lib/memcpymove.h --- linux-4.18.16/arch/arm/lib/memcpymove.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/lib/memcpymove.h 2018-10-29 19:31:20.577781305 +0100 @@ -0,0 +1,506 @@ +/* +Copyright (c) 2013, Raspberry Pi Foundation +Copyright (c) 2013, RISC OS Open Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +.macro unaligned_words backwards, align, use_pld, words, r0, r1, r2, r3, r4, r5, r6, r7, r8 + .if words == 1 + .if backwards + mov r1, r0, lsl #32-align*8 + ldr r0, [S, #-4]! + orr r1, r1, r0, lsr #align*8 + str r1, [D, #-4]! + .else + mov r0, r1, lsr #align*8 + ldr r1, [S, #4]! + orr r0, r0, r1, lsl #32-align*8 + str r0, [D], #4 + .endif + .elseif words == 2 + .if backwards + ldr r1, [S, #-4]! + mov r2, r0, lsl #32-align*8 + ldr r0, [S, #-4]! + orr r2, r2, r1, lsr #align*8 + mov r1, r1, lsl #32-align*8 + orr r1, r1, r0, lsr #align*8 + stmdb D!, {r1, r2} + .else + ldr r1, [S, #4]! + mov r0, r2, lsr #align*8 + ldr r2, [S, #4]! + orr r0, r0, r1, lsl #32-align*8 + mov r1, r1, lsr #align*8 + orr r1, r1, r2, lsl #32-align*8 + stmia D!, {r0, r1} + .endif + .elseif words == 4 + .if backwards + ldmdb S!, {r2, r3} + mov r4, r0, lsl #32-align*8 + ldmdb S!, {r0, r1} + orr r4, r4, r3, lsr #align*8 + mov r3, r3, lsl #32-align*8 + orr r3, r3, r2, lsr #align*8 + mov r2, r2, lsl #32-align*8 + orr r2, r2, r1, lsr #align*8 + mov r1, r1, lsl #32-align*8 + orr r1, r1, r0, lsr #align*8 + stmdb D!, {r1, r2, r3, r4} + .else + ldmib S!, {r1, r2} + mov r0, r4, lsr #align*8 + ldmib S!, {r3, r4} + orr r0, r0, r1, lsl #32-align*8 + mov r1, r1, lsr #align*8 + orr r1, r1, r2, lsl #32-align*8 + mov r2, r2, lsr #align*8 + orr r2, r2, r3, lsl #32-align*8 + mov r3, r3, lsr #align*8 + orr r3, r3, r4, lsl #32-align*8 + stmia D!, {r0, r1, r2, r3} + .endif + .elseif words == 8 + .if backwards + ldmdb S!, {r4, r5, r6, r7} + mov r8, r0, lsl #32-align*8 + ldmdb S!, {r0, r1, r2, r3} + .if use_pld + pld [S, OFF] + .endif + orr r8, r8, r7, lsr #align*8 + mov r7, r7, lsl #32-align*8 + orr r7, r7, r6, lsr #align*8 + mov r6, r6, lsl #32-align*8 + orr r6, r6, r5, lsr #align*8 + mov r5, r5, lsl #32-align*8 + orr r5, r5, r4, lsr #align*8 + mov r4, r4, lsl #32-align*8 + orr r4, r4, r3, lsr #align*8 + mov r3, r3, lsl #32-align*8 + orr r3, r3, r2, lsr #align*8 + mov r2, r2, lsl #32-align*8 + orr r2, r2, r1, lsr #align*8 + mov r1, r1, lsl #32-align*8 + orr r1, r1, r0, lsr #align*8 + stmdb D!, {r5, r6, r7, r8} + stmdb D!, {r1, r2, r3, r4} + .else + ldmib S!, {r1, r2, r3, r4} + mov r0, r8, lsr #align*8 + ldmib S!, {r5, r6, r7, r8} + .if use_pld + pld [S, OFF] + .endif + orr r0, r0, r1, lsl #32-align*8 + mov r1, r1, lsr #align*8 + orr r1, r1, r2, lsl #32-align*8 + mov r2, r2, lsr #align*8 + orr r2, r2, r3, lsl #32-align*8 + mov r3, r3, lsr #align*8 + orr r3, r3, r4, lsl #32-align*8 + mov r4, r4, lsr #align*8 + orr r4, r4, r5, lsl #32-align*8 + mov r5, r5, lsr #align*8 + orr r5, r5, r6, lsl #32-align*8 + mov r6, r6, lsr #align*8 + orr r6, r6, r7, lsl #32-align*8 + mov r7, r7, lsr #align*8 + orr r7, r7, r8, lsl #32-align*8 + stmia D!, {r0, r1, r2, r3} + stmia D!, {r4, r5, r6, r7} + .endif + .endif +.endm + +.macro memcpy_leading_15bytes backwards, align + movs DAT1, DAT2, lsl #31 + sub N, N, DAT2 + .if backwards + ldrmib DAT0, [S, #-1]! + ldrcsh DAT1, [S, #-2]! + strmib DAT0, [D, #-1]! + strcsh DAT1, [D, #-2]! + .else + ldrmib DAT0, [S], #1 + ldrcsh DAT1, [S], #2 + strmib DAT0, [D], #1 + strcsh DAT1, [D], #2 + .endif + movs DAT1, DAT2, lsl #29 + .if backwards + ldrmi DAT0, [S, #-4]! + .if align == 0 + ldmcsdb S!, {DAT1, DAT2} + .else + ldrcs DAT2, [S, #-4]! + ldrcs DAT1, [S, #-4]! + .endif + strmi DAT0, [D, #-4]! + stmcsdb D!, {DAT1, DAT2} + .else + ldrmi DAT0, [S], #4 + .if align == 0 + ldmcsia S!, {DAT1, DAT2} + .else + ldrcs DAT1, [S], #4 + ldrcs DAT2, [S], #4 + .endif + strmi DAT0, [D], #4 + stmcsia D!, {DAT1, DAT2} + .endif +.endm + +.macro memcpy_trailing_15bytes backwards, align + movs N, N, lsl #29 + .if backwards + .if align == 0 + ldmcsdb S!, {DAT0, DAT1} + .else + ldrcs DAT1, [S, #-4]! + ldrcs DAT0, [S, #-4]! + .endif + ldrmi DAT2, [S, #-4]! + stmcsdb D!, {DAT0, DAT1} + strmi DAT2, [D, #-4]! + .else + .if align == 0 + ldmcsia S!, {DAT0, DAT1} + .else + ldrcs DAT0, [S], #4 + ldrcs DAT1, [S], #4 + .endif + ldrmi DAT2, [S], #4 + stmcsia D!, {DAT0, DAT1} + strmi DAT2, [D], #4 + .endif + movs N, N, lsl #2 + .if backwards + ldrcsh DAT0, [S, #-2]! + ldrmib DAT1, [S, #-1] + strcsh DAT0, [D, #-2]! + strmib DAT1, [D, #-1] + .else + ldrcsh DAT0, [S], #2 + ldrmib DAT1, [S] + strcsh DAT0, [D], #2 + strmib DAT1, [D] + .endif +.endm + +.macro memcpy_long_inner_loop backwards, align + .if align != 0 + .if backwards + ldr DAT0, [S, #-align]! + .else + ldr LAST, [S, #-align]! + .endif + .endif +110: + .if align == 0 + .if backwards + ldmdb S!, {DAT0, DAT1, DAT2, DAT3, DAT4, DAT5, DAT6, LAST} + pld [S, OFF] + stmdb D!, {DAT4, DAT5, DAT6, LAST} + stmdb D!, {DAT0, DAT1, DAT2, DAT3} + .else + ldmia S!, {DAT0, DAT1, DAT2, DAT3, DAT4, DAT5, DAT6, LAST} + pld [S, OFF] + stmia D!, {DAT0, DAT1, DAT2, DAT3} + stmia D!, {DAT4, DAT5, DAT6, LAST} + .endif + .else + unaligned_words backwards, align, 1, 8, DAT0, DAT1, DAT2, DAT3, DAT4, DAT5, DAT6, DAT7, LAST + .endif + subs N, N, #32 + bhs 110b + /* Just before the final (prefetch_distance+1) 32-byte blocks, deal with final preloads */ + preload_trailing backwards, S, N, OFF + add N, N, #(prefetch_distance+2)*32 - 32 +120: + .if align == 0 + .if backwards + ldmdb S!, {DAT0, DAT1, DAT2, DAT3, DAT4, DAT5, DAT6, LAST} + stmdb D!, {DAT4, DAT5, DAT6, LAST} + stmdb D!, {DAT0, DAT1, DAT2, DAT3} + .else + ldmia S!, {DAT0, DAT1, DAT2, DAT3, DAT4, DAT5, DAT6, LAST} + stmia D!, {DAT0, DAT1, DAT2, DAT3} + stmia D!, {DAT4, DAT5, DAT6, LAST} + .endif + .else + unaligned_words backwards, align, 0, 8, DAT0, DAT1, DAT2, DAT3, DAT4, DAT5, DAT6, DAT7, LAST + .endif + subs N, N, #32 + bhs 120b + tst N, #16 + .if align == 0 + .if backwards + ldmnedb S!, {DAT0, DAT1, DAT2, LAST} + stmnedb D!, {DAT0, DAT1, DAT2, LAST} + .else + ldmneia S!, {DAT0, DAT1, DAT2, LAST} + stmneia D!, {DAT0, DAT1, DAT2, LAST} + .endif + .else + beq 130f + unaligned_words backwards, align, 0, 4, DAT0, DAT1, DAT2, DAT3, LAST +130: + .endif + /* Trailing words and bytes */ + tst N, #15 + beq 199f + .if align != 0 + add S, S, #align + .endif + memcpy_trailing_15bytes backwards, align +199: + pop {DAT3, DAT4, DAT5, DAT6, DAT7} + pop {D, DAT1, DAT2, pc} +.endm + +.macro memcpy_medium_inner_loop backwards, align +120: + .if backwards + .if align == 0 + ldmdb S!, {DAT0, DAT1, DAT2, LAST} + .else + ldr LAST, [S, #-4]! + ldr DAT2, [S, #-4]! + ldr DAT1, [S, #-4]! + ldr DAT0, [S, #-4]! + .endif + stmdb D!, {DAT0, DAT1, DAT2, LAST} + .else + .if align == 0 + ldmia S!, {DAT0, DAT1, DAT2, LAST} + .else + ldr DAT0, [S], #4 + ldr DAT1, [S], #4 + ldr DAT2, [S], #4 + ldr LAST, [S], #4 + .endif + stmia D!, {DAT0, DAT1, DAT2, LAST} + .endif + subs N, N, #16 + bhs 120b + /* Trailing words and bytes */ + tst N, #15 + beq 199f + memcpy_trailing_15bytes backwards, align +199: + pop {D, DAT1, DAT2, pc} +.endm + +.macro memcpy_short_inner_loop backwards, align + tst N, #16 + .if backwards + .if align == 0 + ldmnedb S!, {DAT0, DAT1, DAT2, LAST} + .else + ldrne LAST, [S, #-4]! + ldrne DAT2, [S, #-4]! + ldrne DAT1, [S, #-4]! + ldrne DAT0, [S, #-4]! + .endif + stmnedb D!, {DAT0, DAT1, DAT2, LAST} + .else + .if align == 0 + ldmneia S!, {DAT0, DAT1, DAT2, LAST} + .else + ldrne DAT0, [S], #4 + ldrne DAT1, [S], #4 + ldrne DAT2, [S], #4 + ldrne LAST, [S], #4 + .endif + stmneia D!, {DAT0, DAT1, DAT2, LAST} + .endif + memcpy_trailing_15bytes backwards, align +199: + pop {D, DAT1, DAT2, pc} +.endm + +.macro memcpy backwards + D .req a1 + S .req a2 + N .req a3 + DAT0 .req a4 + DAT1 .req v1 + DAT2 .req v2 + DAT3 .req v3 + DAT4 .req v4 + DAT5 .req v5 + DAT6 .req v6 + DAT7 .req sl + LAST .req ip + OFF .req lr + + .cfi_startproc + + push {D, DAT1, DAT2, lr} + + .cfi_def_cfa_offset 16 + .cfi_rel_offset D, 0 + .cfi_undefined S + .cfi_undefined N + .cfi_undefined DAT0 + .cfi_rel_offset DAT1, 4 + .cfi_rel_offset DAT2, 8 + .cfi_undefined LAST + .cfi_rel_offset lr, 12 + + .if backwards + add D, D, N + add S, S, N + .endif + + /* See if we're guaranteed to have at least one 16-byte aligned 16-byte write */ + cmp N, #31 + blo 170f + /* To preload ahead as we go, we need at least (prefetch_distance+2) 32-byte blocks */ + cmp N, #(prefetch_distance+3)*32 - 1 + blo 160f + + /* Long case */ + push {DAT3, DAT4, DAT5, DAT6, DAT7} + + .cfi_def_cfa_offset 36 + .cfi_rel_offset D, 20 + .cfi_rel_offset DAT1, 24 + .cfi_rel_offset DAT2, 28 + .cfi_rel_offset DAT3, 0 + .cfi_rel_offset DAT4, 4 + .cfi_rel_offset DAT5, 8 + .cfi_rel_offset DAT6, 12 + .cfi_rel_offset DAT7, 16 + .cfi_rel_offset lr, 32 + + /* Adjust N so that the decrement instruction can also test for + * inner loop termination. We want it to stop when there are + * (prefetch_distance+1) complete blocks to go. */ + sub N, N, #(prefetch_distance+2)*32 + preload_leading_step1 backwards, DAT0, S + .if backwards + /* Bug in GAS: it accepts, but mis-assembles the instruction + * ands DAT2, D, #60, 2 + * which sets DAT2 to the number of leading bytes until destination is aligned and also clears C (sets borrow) + */ + .word 0xE210513C + beq 154f + .else + ands DAT2, D, #15 + beq 154f + rsb DAT2, DAT2, #16 /* number of leading bytes until destination aligned */ + .endif + preload_leading_step2 backwards, DAT0, S, DAT2, OFF + memcpy_leading_15bytes backwards, 1 +154: /* Destination now 16-byte aligned; we have at least one prefetch as well as at least one 16-byte output block */ + /* Prefetch offset is best selected such that it lies in the first 8 of each 32 bytes - but it's just as easy to aim for the first one */ + .if backwards + rsb OFF, S, #3 + and OFF, OFF, #28 + sub OFF, OFF, #32*(prefetch_distance+1) + .else + and OFF, S, #28 + rsb OFF, OFF, #32*prefetch_distance + .endif + movs DAT0, S, lsl #31 + bhi 157f + bcs 156f + bmi 155f + memcpy_long_inner_loop backwards, 0 +155: memcpy_long_inner_loop backwards, 1 +156: memcpy_long_inner_loop backwards, 2 +157: memcpy_long_inner_loop backwards, 3 + + .cfi_def_cfa_offset 16 + .cfi_rel_offset D, 0 + .cfi_rel_offset DAT1, 4 + .cfi_rel_offset DAT2, 8 + .cfi_same_value DAT3 + .cfi_same_value DAT4 + .cfi_same_value DAT5 + .cfi_same_value DAT6 + .cfi_same_value DAT7 + .cfi_rel_offset lr, 12 + +160: /* Medium case */ + preload_all backwards, 0, 0, S, N, DAT2, OFF + sub N, N, #16 /* simplifies inner loop termination */ + .if backwards + ands DAT2, D, #15 + beq 164f + .else + ands DAT2, D, #15 + beq 164f + rsb DAT2, DAT2, #16 + .endif + memcpy_leading_15bytes backwards, align +164: /* Destination now 16-byte aligned; we have at least one 16-byte output block */ + tst S, #3 + bne 140f + memcpy_medium_inner_loop backwards, 0 +140: memcpy_medium_inner_loop backwards, 1 + +170: /* Short case, less than 31 bytes, so no guarantee of at least one 16-byte block */ + teq N, #0 + beq 199f + preload_all backwards, 1, 0, S, N, DAT2, LAST + tst D, #3 + beq 174f +172: subs N, N, #1 + blo 199f + .if backwards + ldrb DAT0, [S, #-1]! + strb DAT0, [D, #-1]! + .else + ldrb DAT0, [S], #1 + strb DAT0, [D], #1 + .endif + tst D, #3 + bne 172b +174: /* Destination now 4-byte aligned; we have 0 or more output bytes to go */ + tst S, #3 + bne 140f + memcpy_short_inner_loop backwards, 0 +140: memcpy_short_inner_loop backwards, 1 + + .cfi_endproc + + .unreq D + .unreq S + .unreq N + .unreq DAT0 + .unreq DAT1 + .unreq DAT2 + .unreq DAT3 + .unreq DAT4 + .unreq DAT5 + .unreq DAT6 + .unreq DAT7 + .unreq LAST + .unreq OFF +.endm diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/lib/memcpy_rpi.S linux-vendor/arch/arm/lib/memcpy_rpi.S --- linux-4.18.16/arch/arm/lib/memcpy_rpi.S 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/lib/memcpy_rpi.S 2018-10-29 19:31:20.577781305 +0100 @@ -0,0 +1,61 @@ +/* +Copyright (c) 2013, Raspberry Pi Foundation +Copyright (c) 2013, RISC OS Open Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include "arm-mem.h" +#include "memcpymove.h" + +/* Prevent the stack from becoming executable */ +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + + .text + .arch armv6 + .object_arch armv4 + .arm + .altmacro + .p2align 2 + +/* + * void *memcpy(void * restrict s1, const void * restrict s2, size_t n); + * On entry: + * a1 = pointer to destination + * a2 = pointer to source + * a3 = number of bytes to copy + * On exit: + * a1 preserved + */ + +.set prefetch_distance, 3 + +ENTRY(mmiocpy) +ENTRY(memcpy) + memcpy 0 +ENDPROC(memcpy) +ENDPROC(mmiocpy) diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/lib/memmove_rpi.S linux-vendor/arch/arm/lib/memmove_rpi.S --- linux-4.18.16/arch/arm/lib/memmove_rpi.S 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/lib/memmove_rpi.S 2018-10-29 19:31:20.577781305 +0100 @@ -0,0 +1,61 @@ +/* +Copyright (c) 2013, Raspberry Pi Foundation +Copyright (c) 2013, RISC OS Open Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include "arm-mem.h" +#include "memcpymove.h" + +/* Prevent the stack from becoming executable */ +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + + .text + .arch armv6 + .object_arch armv4 + .arm + .altmacro + .p2align 2 + +/* + * void *memmove(void *s1, const void *s2, size_t n); + * On entry: + * a1 = pointer to destination + * a2 = pointer to source + * a3 = number of bytes to copy + * On exit: + * a1 preserved + */ + +.set prefetch_distance, 3 + +ENTRY(memmove) + cmp a2, a1 + bpl memcpy /* pl works even over -1 - 0 and 0x7fffffff - 0x80000000 boundaries */ + memcpy 1 +ENDPROC(memmove) diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/lib/memset_rpi.S linux-vendor/arch/arm/lib/memset_rpi.S --- linux-4.18.16/arch/arm/lib/memset_rpi.S 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm/lib/memset_rpi.S 2018-10-29 19:31:20.578781255 +0100 @@ -0,0 +1,128 @@ +/* +Copyright (c) 2013, Raspberry Pi Foundation +Copyright (c) 2013, RISC OS Open Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include "arm-mem.h" + +/* Prevent the stack from becoming executable */ +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + + .text + .arch armv6 + .object_arch armv4 + .arm + .altmacro + .p2align 2 + +/* + * void *memset(void *s, int c, size_t n); + * On entry: + * a1 = pointer to buffer to fill + * a2 = byte pattern to fill with (caller-narrowed) + * a3 = number of bytes to fill + * On exit: + * a1 preserved + */ +ENTRY(mmioset) +ENTRY(memset) +ENTRY(__memset32) +ENTRY(__memset64) + + S .req a1 + DAT0 .req a2 + N .req a3 + DAT1 .req a4 + DAT2 .req ip + DAT3 .req lr + + orr DAT0, DAT0, DAT0, lsl #8 + push {S, lr} + orr DAT0, DAT0, DAT0, lsl #16 + mov DAT1, DAT0 + + /* See if we're guaranteed to have at least one 16-byte aligned 16-byte write */ + cmp N, #31 + blo 170f + +161: sub N, N, #16 /* simplifies inner loop termination */ + /* Leading words and bytes */ + tst S, #15 + beq 164f + rsb DAT3, S, #0 /* bits 0-3 = number of leading bytes until aligned */ + movs DAT2, DAT3, lsl #31 + submi N, N, #1 + strmib DAT0, [S], #1 + subcs N, N, #2 + strcsh DAT0, [S], #2 + movs DAT2, DAT3, lsl #29 + submi N, N, #4 + strmi DAT0, [S], #4 + subcs N, N, #8 + stmcsia S!, {DAT0, DAT1} +164: /* Delayed set up of DAT2 and DAT3 so we could use them as scratch registers above */ + mov DAT2, DAT0 + mov DAT3, DAT0 + /* Now the inner loop of 16-byte stores */ +165: stmia S!, {DAT0, DAT1, DAT2, DAT3} + subs N, N, #16 + bhs 165b +166: /* Trailing words and bytes */ + movs N, N, lsl #29 + stmcsia S!, {DAT0, DAT1} + strmi DAT0, [S], #4 + movs N, N, lsl #2 + strcsh DAT0, [S], #2 + strmib DAT0, [S] +199: pop {S, pc} + +170: /* Short case */ + mov DAT2, DAT0 + mov DAT3, DAT0 + tst S, #3 + beq 174f +172: subs N, N, #1 + blo 199b + strb DAT0, [S], #1 + tst S, #3 + bne 172b +174: tst N, #16 + stmneia S!, {DAT0, DAT1, DAT2, DAT3} + b 166b + + .unreq S + .unreq DAT0 + .unreq N + .unreq DAT1 + .unreq DAT2 + .unreq DAT3 +ENDPROC(__memset64) +ENDPROC(__memset32) +ENDPROC(memset) +ENDPROC(mmioset) diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/lib/uaccess_with_memcpy.c linux-vendor/arch/arm/lib/uaccess_with_memcpy.c --- linux-4.18.16/arch/arm/lib/uaccess_with_memcpy.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/lib/uaccess_with_memcpy.c 2018-10-29 19:31:20.578781255 +0100 @@ -22,6 +22,14 @@ #include #include +#ifndef COPY_FROM_USER_THRESHOLD +#define COPY_FROM_USER_THRESHOLD 64 +#endif + +#ifndef COPY_TO_USER_THRESHOLD +#define COPY_TO_USER_THRESHOLD 64 +#endif + static int pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp) { @@ -84,7 +92,44 @@ return 1; } -static unsigned long noinline +static int +pin_page_for_read(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp) +{ + unsigned long addr = (unsigned long)_addr; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + pud_t *pud; + spinlock_t *ptl; + + pgd = pgd_offset(current->mm, addr); + if (unlikely(pgd_none(*pgd) || pgd_bad(*pgd))) + { + return 0; + } + pud = pud_offset(pgd, addr); + if (unlikely(pud_none(*pud) || pud_bad(*pud))) + { + return 0; + } + + pmd = pmd_offset(pud, addr); + if (unlikely(pmd_none(*pmd) || pmd_bad(*pmd))) + return 0; + + pte = pte_offset_map_lock(current->mm, pmd, addr, &ptl); + if (unlikely(!pte_present(*pte) || !pte_young(*pte))) { + pte_unmap_unlock(pte, ptl); + return 0; + } + + *ptep = pte; + *ptlp = ptl; + + return 1; +} + +unsigned long noinline __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n) { unsigned long ua_flags; @@ -137,6 +182,57 @@ return n; } +unsigned long noinline +__copy_from_user_memcpy(void *to, const void __user *from, unsigned long n) +{ + unsigned long ua_flags; + int atomic; + + if (unlikely(segment_eq(get_fs(), KERNEL_DS))) { + memcpy(to, (const void *)from, n); + return 0; + } + + /* the mmap semaphore is taken only if not in an atomic context */ + atomic = in_atomic(); + + if (!atomic) + down_read(¤t->mm->mmap_sem); + while (n) { + pte_t *pte; + spinlock_t *ptl; + int tocopy; + + while (!pin_page_for_read(from, &pte, &ptl)) { + char temp; + if (!atomic) + up_read(¤t->mm->mmap_sem); + if (__get_user(temp, (char __user *)from)) + goto out; + if (!atomic) + down_read(¤t->mm->mmap_sem); + } + + tocopy = (~(unsigned long)from & ~PAGE_MASK) + 1; + if (tocopy > n) + tocopy = n; + + ua_flags = uaccess_save_and_enable(); + memcpy(to, (const void *)from, tocopy); + uaccess_restore(ua_flags); + to += tocopy; + from += tocopy; + n -= tocopy; + + pte_unmap_unlock(pte, ptl); + } + if (!atomic) + up_read(¤t->mm->mmap_sem); + +out: + return n; +} + unsigned long arm_copy_to_user(void __user *to, const void *from, unsigned long n) { @@ -147,7 +243,7 @@ * With frame pointer disabled, tail call optimization kicks in * as well making this test almost invisible. */ - if (n < 64) { + if (n < COPY_TO_USER_THRESHOLD) { unsigned long ua_flags = uaccess_save_and_enable(); n = __copy_to_user_std(to, from, n); uaccess_restore(ua_flags); @@ -156,6 +252,26 @@ } return n; } + +unsigned long __must_check +arm_copy_from_user(void *to, const void __user *from, unsigned long n) +{ + /* + * This test is stubbed out of the main function above to keep + * the overhead for small copies low by avoiding a large + * register dump on the stack just to reload them right away. + * With frame pointer disabled, tail call optimization kicks in + * as well making this test almost invisible. + */ + if (n < COPY_TO_USER_THRESHOLD) { + unsigned long ua_flags = uaccess_save_and_enable(); + n = __copy_from_user_std(to, from, n); + uaccess_restore(ua_flags); + } else { + n = __copy_from_user_memcpy(to, from, n); + } + return n; +} static unsigned long noinline __clear_user_memset(void __user *addr, unsigned long n) diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/mach-bcm/board_bcm2835.c linux-vendor/arch/arm/mach-bcm/board_bcm2835.c --- linux-4.18.16/arch/arm/mach-bcm/board_bcm2835.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/mach-bcm/board_bcm2835.c 2018-10-29 19:31:20.579781205 +0100 @@ -15,12 +15,25 @@ #include #include #include +#include #include #include #include "platsmp.h" +static void __init bcm2835_init(void) +{ + struct device_node *np = of_find_node_by_path("/system"); + u32 val; + u64 val64; + + if (!of_property_read_u32(np, "linux,revision", &val)) + system_rev = val; + if (!of_property_read_u64(np, "linux,serial", &val64)) + system_serial_low = val64; +} + static const char * const bcm2835_compat[] = { #ifdef CONFIG_ARCH_MULTI_V6 "brcm,bcm2835", @@ -33,6 +46,7 @@ }; DT_MACHINE_START(BCM2835, "BCM2835") + .init_machine = bcm2835_init, .dt_compat = bcm2835_compat, .smp = smp_ops(bcm2836_smp_ops), MACHINE_END diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/mach-bcm/Kconfig linux-vendor/arch/arm/mach-bcm/Kconfig --- linux-4.18.16/arch/arm/mach-bcm/Kconfig 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/mach-bcm/Kconfig 2018-10-29 19:31:20.578781255 +0100 @@ -165,8 +165,10 @@ select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7 select TIMER_OF select BCM2835_TIMER + select FIQ select PINCTRL select PINCTRL_BCM2835 + select MFD_SYSCON if ARCH_MULTI_V7 help This enables support for the Broadcom BCM2835 and BCM2836 SoCs. This SoC is used in the Raspberry Pi and Roku 2 devices. @@ -185,6 +187,13 @@ The base chip is BCM53573 and there are some packaging modifications like BCM47189 and BCM47452. +config BCM2835_FAST_MEMCPY + bool "Enable optimized __copy_to_user and __copy_from_user" + depends on ARCH_BCM2835 && ARCH_MULTI_V6 + default y + help + Optimized versions of __copy_to_user and __copy_from_user for Pi1. + config ARCH_BCM_63XX bool "Broadcom BCM63xx DSL SoC" depends on ARCH_MULTI_V7 diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/Makefile linux-vendor/arch/arm/Makefile --- linux-4.18.16/arch/arm/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/Makefile 2018-10-29 19:31:20.418789237 +0100 @@ -345,6 +345,8 @@ %.dtb: | scripts $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ +%.dtbo: | scripts + $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ PHONY += dtbs dtbs_install diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/mm/cache-v6.S linux-vendor/arch/arm/mm/cache-v6.S --- linux-4.18.16/arch/arm/mm/cache-v6.S 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/mm/cache-v6.S 2018-10-29 19:31:20.611779609 +0100 @@ -201,7 +201,7 @@ * - start - virtual start address of region * - end - virtual end address of region */ -v6_dma_inv_range: +ENTRY(v6_dma_inv_range) #ifdef CONFIG_DMA_CACHE_RWFO ldrb r2, [r0] @ read for ownership strb r2, [r0] @ write for ownership @@ -246,7 +246,7 @@ * - start - virtual start address of region * - end - virtual end address of region */ -v6_dma_clean_range: +ENTRY(v6_dma_clean_range) bic r0, r0, #D_CACHE_LINE_SIZE - 1 1: #ifdef CONFIG_DMA_CACHE_RWFO diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/mm/cache-v7.S linux-vendor/arch/arm/mm/cache-v7.S --- linux-4.18.16/arch/arm/mm/cache-v7.S 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/mm/cache-v7.S 2018-10-29 19:31:20.611779609 +0100 @@ -350,7 +350,8 @@ * - start - virtual start address of region * - end - virtual end address of region */ -v7_dma_inv_range: +ENTRY(b15_dma_inv_range) +ENTRY(v7_dma_inv_range) dcache_line_size r2, r3 sub r3, r2, #1 tst r0, r3 @@ -378,7 +379,8 @@ * - start - virtual start address of region * - end - virtual end address of region */ -v7_dma_clean_range: +ENTRY(b15_dma_clean_range) +ENTRY(v7_dma_clean_range) dcache_line_size r2, r3 sub r3, r2, #1 bic r0, r0, r3 diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/mm/proc-macros.S linux-vendor/arch/arm/mm/proc-macros.S --- linux-4.18.16/arch/arm/mm/proc-macros.S 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/mm/proc-macros.S 2018-10-29 19:31:20.613779509 +0100 @@ -325,6 +325,8 @@ .long \name\()_flush_kern_dcache_area .long \name\()_dma_map_area .long \name\()_dma_unmap_area + .long \name\()_dma_inv_range + .long \name\()_dma_clean_range .long \name\()_dma_flush_range .size \name\()_cache_fns, . - \name\()_cache_fns .endm diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/mm/proc-syms.c linux-vendor/arch/arm/mm/proc-syms.c --- linux-4.18.16/arch/arm/mm/proc-syms.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/mm/proc-syms.c 2018-10-29 19:31:20.613779509 +0100 @@ -30,6 +30,9 @@ EXPORT_SYMBOL(__cpuc_flush_user_range); EXPORT_SYMBOL(__cpuc_coherent_kern_range); EXPORT_SYMBOL(__cpuc_flush_dcache_area); +EXPORT_SYMBOL(dmac_inv_range); +EXPORT_SYMBOL(dmac_clean_range); +EXPORT_SYMBOL(dmac_flush_range); #else EXPORT_SYMBOL(cpu_cache); #endif diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/mm/proc-v6.S linux-vendor/arch/arm/mm/proc-v6.S --- linux-4.18.16/arch/arm/mm/proc-v6.S 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/mm/proc-v6.S 2018-10-29 19:31:20.613779509 +0100 @@ -73,10 +73,19 @@ * * IRQs are already disabled. */ + +/* See jira SW-5991 for details of this workaround */ ENTRY(cpu_v6_do_idle) - mov r1, #0 - mcr p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode - mcr p15, 0, r1, c7, c0, 4 @ wait for interrupt + .align 5 + mov r1, #2 +1: subs r1, #1 + nop + mcreq p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode + mcreq p15, 0, r1, c7, c0, 4 @ wait for interrupt + nop + nop + nop + bne 1b ret lr ENTRY(cpu_v6_dcache_clean_area) diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm/vfp/vfpmodule.c linux-vendor/arch/arm/vfp/vfpmodule.c --- linux-4.18.16/arch/arm/vfp/vfpmodule.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm/vfp/vfpmodule.c 2018-10-29 19:31:20.614779459 +0100 @@ -179,8 +179,11 @@ * case the thread migrates to a different CPU. The * restoring is done lazily. */ - if ((fpexc & FPEXC_EN) && vfp_current_hw_state[cpu]) + if ((fpexc & FPEXC_EN) && vfp_current_hw_state[cpu]) { + /* vfp_save_state oopses on VFP11 if EX bit set */ + fmxr(FPEXC, fpexc & ~FPEXC_EX); vfp_save_state(vfp_current_hw_state[cpu], fpexc); + } #endif /* @@ -462,13 +465,16 @@ /* if vfp is on, then save state for resumption */ if (fpexc & FPEXC_EN) { pr_debug("%s: saving vfp state\n", __func__); + /* vfp_save_state oopses on VFP11 if EX bit set */ + fmxr(FPEXC, fpexc & ~FPEXC_EX); vfp_save_state(&ti->vfpstate, fpexc); /* disable, just in case */ fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); } else if (vfp_current_hw_state[ti->cpu]) { #ifndef CONFIG_SMP - fmxr(FPEXC, fpexc | FPEXC_EN); + /* vfp_save_state oopses on VFP11 if EX bit set */ + fmxr(FPEXC, (fpexc & ~FPEXC_EX) | FPEXC_EN); vfp_save_state(vfp_current_hw_state[ti->cpu], fpexc); fmxr(FPEXC, fpexc); #endif @@ -531,7 +537,8 @@ /* * Save the last VFP state on this CPU. */ - fmxr(FPEXC, fpexc | FPEXC_EN); + /* vfp_save_state oopses on VFP11 if EX bit set */ + fmxr(FPEXC, (fpexc & ~FPEXC_EX) | FPEXC_EN); vfp_save_state(&thread->vfpstate, fpexc | FPEXC_EN); fmxr(FPEXC, fpexc); } @@ -603,6 +610,7 @@ struct vfp_hard_struct *hwstate = &thread->vfpstate.hard; unsigned long fpexc; int err = 0; + u32 fpsid = fmrx(FPSID); /* Disable VFP to avoid corrupting the new thread state. */ vfp_flush_hwstate(thread); @@ -626,8 +634,12 @@ /* Ensure the VFP is enabled. */ fpexc |= FPEXC_EN; - /* Ensure FPINST2 is invalid and the exception flag is cleared. */ - fpexc &= ~(FPEXC_EX | FPEXC_FP2V); + /* Mask FPXEC_EX and FPEXC_FP2V if not required by VFP arch */ + if ((fpsid & FPSID_ARCH_MASK) != (1 << FPSID_ARCH_BIT)) { + /* Ensure FPINST2 is invalid and the exception flag is cleared. */ + fpexc &= ~(FPEXC_EX | FPEXC_FP2V); + } + hwstate->fpexc = fpexc; __get_user_error(hwstate->fpinst, &ufp_exc->fpinst, err); @@ -697,7 +709,8 @@ cpu = get_cpu(); fpexc = fmrx(FPEXC) | FPEXC_EN; - fmxr(FPEXC, fpexc); + /* vfp_save_state oopses on VFP11 if EX bit set */ + fmxr(FPEXC, fpexc & ~FPEXC_EX); /* * Save the userland NEON/VFP state. Under UP, diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dts linux-vendor/arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dts --- linux-4.18.16/arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dts 2018-10-29 19:31:20.616779359 +0100 @@ -0,0 +1,3 @@ +#define RPI364 + +#include "../../../../arm/boot/dts/bcm2710-rpi-3-b.dts" diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dts linux-vendor/arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dts --- linux-4.18.16/arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dts 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dts 2018-10-29 19:31:20.616779359 +0100 @@ -0,0 +1,3 @@ +#define RPI364 + +#include "../../../../arm/boot/dts/bcm2710-rpi-3-b-plus.dts" diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm64/boot/dts/broadcom/Makefile linux-vendor/arch/arm64/boot/dts/broadcom/Makefile --- linux-4.18.16/arch/arm64/boot/dts/broadcom/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm64/boot/dts/broadcom/Makefile 2018-10-29 19:31:20.615779409 +0100 @@ -1,6 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-b.dtb \ bcm2837-rpi-3-b-plus.dtb +dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-3-b.dtb +dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b.dtb +dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b-plus.dtb subdir-y += northstar2 subdir-y += stingray diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm64/boot/dts/Makefile linux-vendor/arch/arm64/boot/dts/Makefile --- linux-4.18.16/arch/arm64/boot/dts/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm64/boot/dts/Makefile 2018-10-29 19:31:20.615779409 +0100 @@ -25,3 +25,5 @@ subdir-y += synaptics subdir-y += xilinx subdir-y += zte + +subdir-y += overlays diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm64/configs/bcmrpi3_defconfig linux-vendor/arch/arm64/configs/bcmrpi3_defconfig --- linux-4.18.16/arch/arm64/configs/bcmrpi3_defconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/arch/arm64/configs/bcmrpi3_defconfig 2018-10-29 19:31:20.625778909 +0100 @@ -0,0 +1,1295 @@ +CONFIG_LOCALVERSION="-v8" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=m +CONFIG_IKCONFIG_PROC=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EMBEDDED=y +# CONFIG_COMPAT_BRK is not set +CONFIG_PROFILING=y +CONFIG_KPROBES=y +CONFIG_JUMP_LABEL=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLK_DEV_THROTTLING=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_MAC_PARTITION=y +CONFIG_CFQ_GROUP_IOSCHED=y +CONFIG_ARCH_BCM2835=y +# CONFIG_CAVIUM_ERRATUM_22375 is not set +# CONFIG_CAVIUM_ERRATUM_23154 is not set +# CONFIG_CAVIUM_ERRATUM_27456 is not set +CONFIG_SCHED_MC=y +CONFIG_NR_CPUS=4 +CONFIG_PREEMPT=y +CONFIG_HZ_1000=y +CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +CONFIG_CMA=y +CONFIG_ZSMALLOC=m +CONFIG_PGTABLE_MAPPING=y +CONFIG_SECCOMP=y +CONFIG_ARMV8_DEPRECATED=y +CONFIG_SWP_EMULATION=y +CONFIG_CP15_BARRIER_EMULATION=y +CONFIG_SETEND_EMULATION=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_CMDLINE="console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait" +CONFIG_BINFMT_MISC=y +CONFIG_COMPAT=y +# CONFIG_SUSPEND is not set +CONFIG_PM=y +CONFIG_CPU_IDLE=y +CONFIG_ARM_CPUIDLE=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=y +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_DIAG=m +CONFIG_IPV6=m +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_PE_SIP=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_ATM=m +CONFIG_L2TP=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_ATALK=m +CONFIG_6LOWPAN=m +CONFIG_IEEE802154=m +CONFIG_IEEE802154_6LOWPAN=m +CONFIG_MAC802154=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m +CONFIG_NET_SCH_FQ=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BBR=m +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_IPSET=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_BATMAN_ADV=m +CONFIG_OPENVSWITCH=m +CONFIG_NET_PKTGEN=m +CONFIG_HAMRADIO=y +CONFIG_AX25=m +CONFIG_NETROM=m +CONFIG_ROSE=m +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_YAM=m +CONFIG_CAN=m +CONFIG_CAN_VCAN=m +CONFIG_CAN_MCP251X=m +CONFIG_BT=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m +CONFIG_BT_6LOWPAN=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m +CONFIG_BT_WILINK=m +CONFIG_CFG80211=m +CONFIG_MAC80211=m +CONFIG_MAC80211_MESH=y +CONFIG_WIMAX=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=y +CONFIG_NET_9P=m +CONFIG_NFC=m +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=5 +CONFIG_MTD=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_NAND=m +CONFIG_MTD_UBI=m +CONFIG_OF_CONFIGFS=y +CONFIG_ZRAM=m +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_CDROM_PKTCDVD=m +CONFIG_ATA_OVER_ETH=m +CONFIG_EEPROM_AT24=m +CONFIG_TI_ST=m +CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_CHR_DEV_SG=m +CONFIG_SCSI_ISCSI_ATTRS=y +CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m +CONFIG_MD=y +CONFIG_MD_LINEAR=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m +CONFIG_DM_ZERO=m +CONFIG_DM_DELAY=m +CONFIG_NETDEVICES=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_IFB=m +CONFIG_MACVLAN=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_ENC28J60=m +CONFIG_QCA7000_SPI=m +CONFIG_MDIO_BITBANG=m +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_HUAWEI_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SR9700=m +CONFIG_USB_NET_SR9800=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=y +CONFIG_USB_LAN78XX=y +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=m +CONFIG_USB_NET_CX82310_ETH=m +CONFIG_USB_NET_KALMIA=m +CONFIG_USB_NET_QMI_WWAN=m +CONFIG_USB_HSO=m +CONFIG_USB_NET_INT51X1=m +CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m +CONFIG_ATH9K=m +CONFIG_ATH9K_HTC=m +CONFIG_CARL9170=m +CONFIG_ATH6KL=m +CONFIG_ATH6KL_USB=m +CONFIG_AR5523=m +CONFIG_AT76C50X_USB=m +CONFIG_B43=m +# CONFIG_B43_PHY_N is not set +CONFIG_B43LEGACY=m +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_USB=y +CONFIG_HOSTAP=m +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_THINFIRM=m +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_MWIFIEX=m +CONFIG_MWIFIEX_SDIO=m +CONFIG_MT7601U=m +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RTL8187=m +CONFIG_RTL8192CU=m +CONFIG_USB_ZD1201=m +CONFIG_ZD1211RW=m +CONFIG_MAC80211_HWSIM=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_WIMAX_I2400M_USB=m +CONFIG_IEEE802154_AT86RF230=m +CONFIG_IEEE802154_MRF24J40=m +CONFIG_IEEE802154_CC2520=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_GPIO=m +CONFIG_KEYBOARD_MATRIX=m +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_RPISENSE=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_EGALAX=m +CONFIG_TOUCHSCREEN_EKTF2127=m +CONFIG_TOUCHSCREEN_RPI_FT5406=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_STMPE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_AD714X=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_YEALINK=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m +CONFIG_INPUT_ADXL34X=m +CONFIG_INPUT_CMA3000=m +CONFIG_SERIO=m +CONFIG_SERIO_RAW=m +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_BRCM_CHAR_DRIVERS=y +CONFIG_BCM_VCIO=y +CONFIG_BCM2835_DEVGPIOMEM=y +# CONFIG_BCM2835_SMI_DEV is not set +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=0 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_BCM2835AUX=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_SC16IS7XX=m +CONFIG_SERIAL_SC16IS7XX_SPI=y +CONFIG_SERIAL_DEV_BUS=m +CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y +CONFIG_RAW_DRIVER=y +CONFIG_TCG_TPM=m +CONFIG_TCG_TIS_CORE=m +CONFIG_TCG_TIS_SPI=m +# CONFIG_SECURITYFS is not set +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_MUX_PCA954x=m +CONFIG_I2C_BCM2708=m +CONFIG_I2C_BCM2835=m +CONFIG_I2C_GPIO=m +CONFIG_SPI=y +CONFIG_SPI_BCM2835=m +CONFIG_SPI_BCM2835AUX=m +CONFIG_SPI_SPIDEV=y +CONFIG_PPS=m +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PPS_CLIENT_GPIO=m +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_BCM_EXP=y +CONFIG_GPIO_BCM_VIRT=y +CONFIG_GPIO_ARIZONA=m +CONFIG_GPIO_STMPE=y +CONFIG_W1=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS1WM=m +CONFIG_W1_MASTER_GPIO=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2408=m +CONFIG_W1_SLAVE_DS2413=m +CONFIG_W1_SLAVE_DS2406=m +CONFIG_W1_SLAVE_DS2423=m +CONFIG_W1_SLAVE_DS2431=m +CONFIG_W1_SLAVE_DS2433=m +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_DS2780=m +CONFIG_W1_SLAVE_DS2781=m +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_POWER_RESET_GPIO=y +CONFIG_BATTERY_DS2760=m +CONFIG_HWMON=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_SHT21=m +CONFIG_SENSORS_SHTC1=m +CONFIG_SENSORS_INA2XX=m +CONFIG_THERMAL=y +CONFIG_BCM2835_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_BCM2835_WDT=y +CONFIG_MFD_STMPE=y +CONFIG_STMPE_SPI=y +CONFIG_MFD_ARIZONA_I2C=m +CONFIG_MFD_ARIZONA_SPI=m +CONFIG_MFD_WM5102=y +CONFIG_LIRC=m +CONFIG_RC_DEVICES=y +CONFIG_RC_ATI_REMOTE=m +CONFIG_IR_IMON=m +CONFIG_IR_MCEUSB=m +CONFIG_IR_REDRAT3=m +CONFIG_IR_STREAMZAP=m +CONFIG_IR_IGUANA=m +CONFIG_IR_TTUSBIR=m +CONFIG_RC_LOOPBACK=m +CONFIG_IR_GPIO_CIR=m +CONFIG_MEDIA_SUPPORT=m +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GL860=m +CONFIG_USB_GSPCA_BENQ=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_CPIA1=m +CONFIG_USB_GSPCA_DTCS033=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_USB_GSPCA_JL2005BCD=m +CONFIG_USB_GSPCA_KINECT=m +CONFIG_USB_GSPCA_KONICA=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_NW80X=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_OV534_9=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7302=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SE401=m +CONFIG_USB_GSPCA_SN9C2028=m +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SPCA1528=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_SQ930X=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_STK1135=m +CONFIG_USB_GSPCA_STV0680=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TOPRO=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_VICAM=m +CONFIG_USB_GSPCA_XIRLINK_CIT=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_USB_PWC=m +CONFIG_VIDEO_CPIA2=m +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +CONFIG_VIDEO_USBTV=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_STK1160_COMMON=m +CONFIG_VIDEO_GO7007=m +CONFIG_VIDEO_GO7007_USB=m +CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_AU0828_RC=y +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_VIDEO_TM6000=m +CONFIG_VIDEO_TM6000_ALSA=m +CONFIG_VIDEO_TM6000_DVB=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_PCTV452E=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_FRIIO=m +CONFIG_DVB_USB_AZ6027=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_V2=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_AF9035=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_AZ6007=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_LME2510=m +CONFIG_DVB_USB_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +CONFIG_DVB_USB_DVBSKY=m +CONFIG_SMS_USB_DRV=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_AS102=m +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_V4L2=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_RADIO_SI470X=y +CONFIG_USB_SI470X=m +CONFIG_I2C_SI470X=m +CONFIG_RADIO_SI4713=m +CONFIG_I2C_SI4713=m +CONFIG_USB_MR800=m +CONFIG_USB_DSBR=m +CONFIG_RADIO_SHARK=m +CONFIG_RADIO_SHARK2=m +CONFIG_USB_KEENE=m +CONFIG_USB_MA901=m +CONFIG_RADIO_TEA5764=m +CONFIG_RADIO_SAA7706H=m +CONFIG_RADIO_TEF6862=m +CONFIG_RADIO_WL1273=m +CONFIG_RADIO_WL128X=m +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_VIDEO_UDA1342=m +CONFIG_VIDEO_SONY_BTF_MPX=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_TW2804=m +CONFIG_VIDEO_TW9903=m +CONFIG_VIDEO_TW9906=m +CONFIG_VIDEO_OV7640=m +CONFIG_VIDEO_MT9V011=m +CONFIG_DRM=m +CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_PANEL_SIMPLE=m +CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m +CONFIG_DRM_UDL=m +CONFIG_DRM_PANEL_SIMPLE=m +CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m +CONFIG_DRM_VC4=m +CONFIG_FB=y +CONFIG_FB_BCM2708=y +CONFIG_FB_UDL=m +CONFIG_FB_SSD1307=m +CONFIG_FB_RPISENSE=m +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_RPI=m +CONFIG_BACKLIGHT_GPIO=m +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=m +CONFIG_SND_HRTIMER=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_DUMMY=m +CONFIG_SND_ALOOP=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_UA101=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_6FIRE=m +CONFIG_SND_SOC=m +CONFIG_SND_BCM2835_SOC_I2S=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m +CONFIG_SND_BCM2708_SOC_RPI_DAC=m +CONFIG_SND_BCM2708_SOC_RPI_PROTO=m +CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m +CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m +CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m +CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m +CONFIG_SND_DIGIDAC1_SOUNDCARD=m +CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m +CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m +CONFIG_SND_PISOUND=m +CONFIG_SND_SOC_ADAU1701=m +CONFIG_SND_SOC_AK4554=m +CONFIG_SND_SOC_CS4271_I2C=m +CONFIG_SND_SOC_WM8804_I2C=m +CONFIG_SND_SIMPLE_CARD=m +CONFIG_HIDRAW=y +CONFIG_UHID=m +CONFIG_HID_A4TECH=m +CONFIG_HID_ACRUX=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BETOP_FF=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DRAGONRISE=m +CONFIG_HID_EMS_FF=m +CONFIG_HID_ELECOM=m +CONFIG_HID_ELO=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GEMBIRD=m +CONFIG_HID_HOLTEK=m +CONFIG_HID_KEYTOUCH=m +CONFIG_HID_KYE=m +CONFIG_HID_UCLOGIC=m +CONFIG_HID_WALTOP=m +CONFIG_HID_GYRATION=m +CONFIG_HID_TWINHAN=m +CONFIG_HID_KENSINGTON=m +CONFIG_HID_LCPOWER=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_LOGITECH_DJ=m +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_HID_MAGICMOUSE=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_MULTITOUCH=m +CONFIG_HID_NTRIG=m +CONFIG_HID_ORTEK=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_PICOLCD=m +CONFIG_HID_ROCCAT=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SPEEDLINK=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_GREENASIA=m +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_HID_TOPSEED=m +CONFIG_HID_THINGM=m +CONFIG_HID_THRUSTMASTER=m +CONFIG_HID_WACOM=m +CONFIG_HID_WIIMOTE=m +CONFIG_HID_XINMO=m +CONFIG_HID_ZEROPLUS=m +CONFIG_HID_ZYDACRON=m +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=m +CONFIG_USB_DWCOTG=y +CONFIG_USB_PRINTER=m +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_REALTEK=m +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +CONFIG_USB_STORAGE_ENE_UB6250=m +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USBIP_CORE=m +CONFIG_USBIP_VHCI_HCD=m +CONFIG_USBIP_HOST=m +CONFIG_USB_DWC2=y +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_F81232=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_METRO=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_QCAUX=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SYMBOL=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_USB_SERIAL_XSENS_MT=m +CONFIG_USB_SERIAL_WISHBONE=m +CONFIG_USB_SERIAL_SSU100=m +CONFIG_USB_SERIAL_QT2=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_TEST=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_YUREX=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m +CONFIG_MMC=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BCM2835_MMC=y +CONFIG_MMC_BCM2835_DMA=y +CONFIG_MMC_BCM2835_SDHOST=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_IPROC=m +CONFIG_MMC_SPI=m +CONFIG_MMC_BCM2835=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_TRANSIENT=m +CONFIG_LEDS_TRIGGER_CAMERA=m +CONFIG_LEDS_TRIGGER_INPUT=y +CONFIG_LEDS_TRIGGER_PANIC=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_HCTOSYS is not set +CONFIG_RTC_DRV_ABX80X=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_ISL12022=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_PCF8523=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_BQ32K=m +CONFIG_RTC_DRV_S35390A=m +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_RX8581=m +CONFIG_RTC_DRV_RX8025=m +CONFIG_RTC_DRV_EM3027=m +CONFIG_RTC_DRV_M41T93=m +CONFIG_RTC_DRV_M41T94=m +CONFIG_RTC_DRV_DS1302=m +CONFIG_RTC_DRV_DS1305=m +CONFIG_RTC_DRV_DS1390=m +CONFIG_RTC_DRV_R9701=m +CONFIG_RTC_DRV_RX4581=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF2123=m +CONFIG_RTC_DRV_DS3232=m +CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_RV3029C2=m +CONFIG_DMADEVICES=y +CONFIG_DMA_BCM2835=y +CONFIG_DMA_BCM2708=y +CONFIG_UIO=m +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_STAGING=y +CONFIG_IRDA=m +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRTTY_SIR=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KS959_DONGLE=m +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_MCS_FIR=m +CONFIG_PRISM2_USB=m +CONFIG_R8712U=m +CONFIG_R8188EU=m +CONFIG_VT6656=m +CONFIG_SPEAKUP=m +CONFIG_SPEAKUP_SYNTH_SOFT=m +CONFIG_STAGING_MEDIA=y +CONFIG_LIRC_STAGING=y +CONFIG_LIRC_RPI=m +CONFIG_FB_TFT=m +CONFIG_FB_TFT_AGM1264K_FL=m +CONFIG_FB_TFT_BD663474=m +CONFIG_FB_TFT_HX8340BN=m +CONFIG_FB_TFT_HX8347D=m +CONFIG_FB_TFT_HX8353D=m +CONFIG_FB_TFT_HX8357D=m +CONFIG_FB_TFT_ILI9163=m +CONFIG_FB_TFT_ILI9320=m +CONFIG_FB_TFT_ILI9325=m +CONFIG_FB_TFT_ILI9340=m +CONFIG_FB_TFT_ILI9341=m +CONFIG_FB_TFT_ILI9481=m +CONFIG_FB_TFT_ILI9486=m +CONFIG_FB_TFT_PCD8544=m +CONFIG_FB_TFT_RA8875=m +CONFIG_FB_TFT_S6D02A1=m +CONFIG_FB_TFT_S6D1121=m +CONFIG_FB_TFT_SSD1289=m +CONFIG_FB_TFT_SSD1306=m +CONFIG_FB_TFT_SSD1331=m +CONFIG_FB_TFT_SSD1351=m +CONFIG_FB_TFT_ST7735R=m +CONFIG_FB_TFT_TINYLCD=m +CONFIG_FB_TFT_TLS8204=m +CONFIG_FB_TFT_UC1701=m +CONFIG_FB_TFT_UPD161704=m +CONFIG_FB_TFT_WATTEROTT=m +CONFIG_FB_FLEX=m +CONFIG_FB_TFT_FBTFT_DEVICE=m +CONFIG_SND_BCM2835=m +CONFIG_MAILBOX=y +CONFIG_BCM2835_MBOX=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_RASPBERRYPI_POWER=y +CONFIG_EXTCON=m +CONFIG_EXTCON_ARIZONA=m +CONFIG_IIO=m +CONFIG_IIO_BUFFER=y +CONFIG_IIO_BUFFER_CB=m +CONFIG_IIO_KFIFO_BUF=m +CONFIG_MCP320X=m +CONFIG_MCP3422=m +CONFIG_DHT11=m +CONFIG_HTU21=m +CONFIG_PWM_BCM2835=m +CONFIG_PWM_PCA9685=m +CONFIG_RASPBERRYPI_FIRMWARE=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +CONFIG_GFS2_FS=m +CONFIG_OCFS2_FS=m +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_NILFS2_FS=m +CONFIG_F2FS_FS=y +CONFIG_FANOTIFY=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_OVERLAY_FS=m +CONFIG_FSCACHE=y +CONFIG_FSCACHE_STATS=y +CONFIG_FSCACHE_HISTOGRAM=y +CONFIG_CACHEFILES=y +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +CONFIG_NTFS_FS=m +CONFIG_NTFS_RW=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_ECRYPT_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_SUMMARY=y +CONFIG_UBIFS_FS=m +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_ROOT_NFS=y +CONFIG_NFS_FSCACHE=y +CONFIG_NFSD=m +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_CIFS=m +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_ACL=y +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_FSCACHE=y +CONFIG_9P_FS=m +CONFIG_9P_FS_POSIX_ACL=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_DLM=m +CONFIG_PRINTK_TIME=y +CONFIG_BOOT_PRINTK_DELAY=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DETECT_HUNG_TASK=y +CONFIG_LATENCYTOP=y +CONFIG_IRQSOFF_TRACER=y +CONFIG_SCHED_TRACER=y +CONFIG_STACK_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_FUNCTION_PROFILER=y +CONFIG_KGDB=y +CONFIG_KGDB_KDB=y +CONFIG_KDB_KEYBOARD=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_AES_ARM64=m +CONFIG_CRYPTO_AES_ARM64_BS=m +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=m +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y +CONFIG_MMC_BCM2835_MMC=y +CONFIG_MMC_SDHCI_IPROC=m diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm64/Kconfig.platforms linux-vendor/arch/arm64/Kconfig.platforms --- linux-4.18.16/arch/arm64/Kconfig.platforms 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm64/Kconfig.platforms 2018-10-29 19:31:20.615779409 +0100 @@ -1,11 +1,5 @@ menu "Platform selection" -config ARCH_ACTIONS - bool "Actions Semi Platforms" - select OWL_TIMER - help - This enables support for the Actions Semiconductor S900 SoC family. - config ARCH_SUNXI bool "Allwinner sunxi 64-bit SoC Family" select ARCH_HAS_RESET_CONTROLLER diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm64/kernel/armv8_deprecated.c linux-vendor/arch/arm64/kernel/armv8_deprecated.c --- linux-4.18.16/arch/arm64/kernel/armv8_deprecated.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm64/kernel/armv8_deprecated.c 2018-10-29 19:31:20.633778511 +0100 @@ -182,10 +182,15 @@ switch (ops->status) { case INSN_DEPRECATED: +#if 0 insn->current_mode = INSN_EMULATE; /* Disable the HW mode if it was turned on at early boot time */ run_all_cpu_set_hw_mode(insn, false); +#else + insn->current_mode = INSN_HW; + run_all_cpu_set_hw_mode(insn, true); insn->max = INSN_HW; +#endif break; case INSN_OBSOLETE: insn->current_mode = INSN_UNDEF; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/arch/arm64/Makefile linux-vendor/arch/arm64/Makefile --- linux-4.18.16/arch/arm64/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/arch/arm64/Makefile 2018-10-29 19:31:20.615779409 +0100 @@ -129,6 +129,9 @@ %.dtb: scripts $(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@ +%.dtbo: | scripts + $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ + PHONY += dtbs dtbs_install dtbs: prepare scripts diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/Documentation/devicetree/bindings/hwmon/rpi-poe-fan.txt linux-vendor/Documentation/devicetree/bindings/hwmon/rpi-poe-fan.txt --- linux-4.18.16/Documentation/devicetree/bindings/hwmon/rpi-poe-fan.txt 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/Documentation/devicetree/bindings/hwmon/rpi-poe-fan.txt 2018-10-29 19:31:20.367791782 +0100 @@ -0,0 +1,55 @@ +Bindings for the Raspberry Pi PoE HAT fan + +Required properties: +- compatible : "raspberrypi,rpi-poe-fan" +- firmware : Reference to the RPi firmware device node +- pwms : the PWM that is used to control the PWM fan +- cooling-levels : PWM duty cycle values in a range from 0 to 255 + which correspond to thermal cooling states + +Example: + fan0: rpi-poe-fan@0 { + compatible = "raspberrypi,rpi-poe-fan"; + firmware = <&firmware>; + cooling-min-state = <0>; + cooling-max-state = <3>; + #cooling-cells = <2>; + cooling-levels = <0 50 150 255>; + status = "okay"; + }; + + thermal-zones { + cpu_thermal: cpu-thermal { + trips { + threshold: trip-point@0 { + temperature = <45000>; + hysteresis = <5000>; + type = "active"; + }; + target: trip-point@1 { + temperature = <50000>; + hysteresis = <2000>; + type = "active"; + }; + cpu_hot: cpu_hot@0 { + temperature = <55000>; + hysteresis = <2000>; + type = "active"; + }; + }; + cooling-maps { + map0 { + trip = <&threshold>; + cooling-device = <&fan0 0 1>; + }; + map1 { + trip = <&target>; + cooling-device = <&fan0 1 2>; + }; + map2 { + trip = <&cpu_hot>; + cooling-device = <&fan0 2 3>; + }; + }; + }; + }; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt linux-vendor/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt --- linux-4.18.16/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt 2018-10-29 19:31:20.367791782 +0100 @@ -0,0 +1,17 @@ +* Broadcom BCM2835 SMI character device driver. + +SMI or secondary memory interface is a peripheral specific to certain Broadcom +SOCs, and is helpful for talking to things like parallel-interface displays +and NAND flashes (in fact, most things with a parallel register interface). + +This driver adds a character device which provides a user-space interface to +an instance of the SMI driver. + +Required properties: +- compatible: "brcm,bcm2835-smi-dev" +- smi_handle: a phandle to the smi node. + +Optional properties: +- None. + + diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt linux-vendor/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt --- linux-4.18.16/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt 2018-10-29 19:31:20.367791782 +0100 @@ -0,0 +1,48 @@ +* Broadcom BCM2835 SMI driver. + +SMI or secondary memory interface is a peripheral specific to certain Broadcom +SOCs, and is helpful for talking to things like parallel-interface displays +and NAND flashes (in fact, most things with a parallel register interface). + +Required properties: +- compatible: "brcm,bcm2835-smi" +- reg: Should contain location and length of SMI registers and SMI clkman regs +- interrupts: *the* SMI interrupt. +- pinctrl-names: should be "default". +- pinctrl-0: the phandle of the gpio pin node. +- brcm,smi-clock-source: the clock source for clkman +- brcm,smi-clock-divisor: the integer clock divisor for clkman +- dmas: the dma controller phandle and the DREQ number (4 on a 2835) +- dma-names: the name used by the driver to request its channel. + Should be "rx-tx". + +Optional properties: +- None. + +Examples: + +8 data pin configuration: + +smi: smi@7e600000 { + compatible = "brcm,bcm2835-smi"; + reg = <0x7e600000 0x44>, <0x7e1010b0 0x8>; + interrupts = <2 16>; + pinctrl-names = "default"; + pinctrl-0 = <&smi_pins>; + brcm,smi-clock-source = <6>; + brcm,smi-clock-divisor = <4>; + dmas = <&dma 4>; + dma-names = "rx-tx"; + + status = "okay"; +}; + +smi_pins: smi_pins { + brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 13 14 15>; + /* Alt 1: SMI */ + brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5>; + /* /CS, /WE and /OE are pulled high, as they are + generally active low signals */ + brcm,pull = <2 2 2 2 2 2 0 0 0 0 0 0 0 0>; +}; + diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt linux-vendor/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt --- linux-4.18.16/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt 2018-10-29 19:31:20.367791782 +0100 @@ -0,0 +1,42 @@ +* BCM2835 SMI NAND flash + +This driver is a shim between the BCM2835 SMI driver (SMI is a peripheral for +talking to parallel register interfaces) and Linux's MTD layer. + +Required properties: +- compatible: "brcm,bcm2835-smi-nand" +- status: "okay" + +Optional properties: +- partition@n, where n is an integer from a consecutive sequence starting at 0 + - Difficult to store partition table on NAND device - normally put it + in the source code, kernel bootparams, or device tree (the best way!) + - Sub-properties: + - label: the partition name, as shown by mtdinfo /dev/mtd* + - reg: the size and offset of this partition. + - (optional) read-only: an empty property flagging as read only + +Example: + +nand: flash@0 { + compatible = "brcm,bcm2835-smi-nand"; + status = "okay"; + + partition@0 { + label = "stage2"; + // 128k + reg = <0 0x20000>; + read-only; + }; + partition@1 { + label = "firmware"; + // 16M + reg = <0x20000 0x1000000>; + read-only; + }; + partition@2 { + label = "root"; + // 2G + reg = <0x1020000 0x80000000>; + }; +}; \ Manca newline alla fine del file diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/Documentation/devicetree/bindings/power/reset/gpio-poweroff.txt linux-vendor/Documentation/devicetree/bindings/power/reset/gpio-poweroff.txt --- linux-4.18.16/Documentation/devicetree/bindings/power/reset/gpio-poweroff.txt 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/Documentation/devicetree/bindings/power/reset/gpio-poweroff.txt 2018-10-29 19:31:20.367791782 +0100 @@ -29,6 +29,7 @@ inactive state. - timeout-ms: Time to wait before asserting a WARN_ON(1). If nothing is specified, 3000 ms is used. +- export : Export the GPIO line to the sysfs system Examples: diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/Documentation/devicetree/bindings/serial/pl011.txt linux-vendor/Documentation/devicetree/bindings/serial/pl011.txt --- linux-4.18.16/Documentation/devicetree/bindings/serial/pl011.txt 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/Documentation/devicetree/bindings/serial/pl011.txt 2018-10-29 19:31:20.380791134 +0100 @@ -35,6 +35,9 @@ - poll-timeout-ms: Poll timeout when auto-poll is set, default 3000ms. +- cts-event-workaround: + Enables the (otherwise vendor-specific) workaround for the + CTS-induced TX lockup. See also bindings/arm/primecell.txt diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/Documentation/devicetree/bindings/vendor-prefixes.txt linux-vendor/Documentation/devicetree/bindings/vendor-prefixes.txt --- linux-4.18.16/Documentation/devicetree/bindings/vendor-prefixes.txt 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/Documentation/devicetree/bindings/vendor-prefixes.txt 2018-10-29 19:31:20.381791084 +0100 @@ -53,6 +53,7 @@ axis Axis Communications AB bananapi BIPAI KEJI LIMITED bhf Beckhoff Automation GmbH & Co. KG +blokaslabs Vilniaus Blokas UAB boe BOE Technology Group Co., Ltd. bosch Bosch Sensortec GmbH boundary Boundary Devices Inc. diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/Documentation/devicetree/configfs-overlays.txt linux-vendor/Documentation/devicetree/configfs-overlays.txt --- linux-4.18.16/Documentation/devicetree/configfs-overlays.txt 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/Documentation/devicetree/configfs-overlays.txt 2018-10-29 19:31:20.381791084 +0100 @@ -0,0 +1,31 @@ +Howto use the configfs overlay interface. + +A device-tree configfs entry is created in /config/device-tree/overlays +and and it is manipulated using standard file system I/O. +Note that this is a debug level interface, for use by developers and +not necessarily something accessed by normal users due to the +security implications of having direct access to the kernel's device tree. + +* To create an overlay you mkdir the directory: + + # mkdir /config/device-tree/overlays/foo + +* Either you echo the overlay firmware file to the path property file. + + # echo foo.dtbo >/config/device-tree/overlays/foo/path + +* Or you cat the contents of the overlay to the dtbo file + + # cat foo.dtbo >/config/device-tree/overlays/foo/dtbo + +The overlay file will be applied, and devices will be created/destroyed +as required. + +To remove it simply rmdir the directory. + + # rmdir /config/device-tree/overlays/foo + +The rationalle of the dual interface (firmware & direct copy) is that each is +better suited to different use patterns. The firmware interface is what's +intended to be used by hardware managers in the kernel, while the copy interface +make sense for developers (since it avoids problems with namespaces). diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/Documentation/hwmon/rpi-poe-fan linux-vendor/Documentation/hwmon/rpi-poe-fan --- linux-4.18.16/Documentation/hwmon/rpi-poe-fan 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/Documentation/hwmon/rpi-poe-fan 2018-10-29 19:31:20.395790387 +0100 @@ -0,0 +1,15 @@ +Kernel driver rpi-poe-fan +===================== + +This driver enables the use of the Raspberry Pi PoE HAT fan. + +Author: Serge Schneider + +Description +----------- + +The driver implements a simple interface for driving the Raspberry Pi PoE +(Power over Ethernet) HAT fan. The driver passes commands to the Raspberry Pi +firmware through the mailbox property interface. The firmware then forwards +the commands to the board over I2C on the ID_EEPROM pins. The driver exposes +the fan to the user space through the hwmon sysfs interface. diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/bluetooth/hci_h5.c linux-vendor/drivers/bluetooth/hci_h5.c --- linux-4.18.16/drivers/bluetooth/hci_h5.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/bluetooth/hci_h5.c 2018-10-29 19:31:20.937763343 +0100 @@ -310,7 +310,8 @@ h5_link_control(hu, conf_req, 3); } else if (memcmp(data, conf_req, 2) == 0) { h5_link_control(hu, conf_rsp, 2); - h5_link_control(hu, conf_req, 3); + if (h5->state != H5_ACTIVE) + h5_link_control(hu, conf_req, 3); } else if (memcmp(data, conf_rsp, 2) == 0) { if (H5_HDR_LEN(hdr) > 2) h5->tx_win = (data[2] & 0x07); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/broadcom/bcm2835-gpiomem.c linux-vendor/drivers/char/broadcom/bcm2835-gpiomem.c --- linux-4.18.16/drivers/char/broadcom/bcm2835-gpiomem.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/char/broadcom/bcm2835-gpiomem.c 2018-10-29 19:31:20.941763143 +0100 @@ -0,0 +1,258 @@ +/** + * GPIO memory device driver + * + * Creates a chardev /dev/gpiomem which will provide user access to + * the BCM2835's GPIO registers when it is mmap()'d. + * No longer need root for user GPIO access, but without relaxing permissions + * on /dev/mem. + * + * Written by Luke Wren + * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2, as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEVICE_NAME "bcm2835-gpiomem" +#define DRIVER_NAME "gpiomem-bcm2835" +#define DEVICE_MINOR 0 + +struct bcm2835_gpiomem_instance { + unsigned long gpio_regs_phys; + struct device *dev; +}; + +static struct cdev bcm2835_gpiomem_cdev; +static dev_t bcm2835_gpiomem_devid; +static struct class *bcm2835_gpiomem_class; +static struct device *bcm2835_gpiomem_dev; +static struct bcm2835_gpiomem_instance *inst; + + +/**************************************************************************** +* +* GPIO mem chardev file ops +* +***************************************************************************/ + +static int bcm2835_gpiomem_open(struct inode *inode, struct file *file) +{ + int dev = iminor(inode); + int ret = 0; + + if (dev != DEVICE_MINOR) { + dev_err(inst->dev, "Unknown minor device: %d", dev); + ret = -ENXIO; + } + return ret; +} + +static int bcm2835_gpiomem_release(struct inode *inode, struct file *file) +{ + int dev = iminor(inode); + int ret = 0; + + if (dev != DEVICE_MINOR) { + dev_err(inst->dev, "Unknown minor device %d", dev); + ret = -ENXIO; + } + return ret; +} + +static const struct vm_operations_struct bcm2835_gpiomem_vm_ops = { +#ifdef CONFIG_HAVE_IOREMAP_PROT + .access = generic_access_phys +#endif +}; + +static int bcm2835_gpiomem_mmap(struct file *file, struct vm_area_struct *vma) +{ + /* Ignore what the user says - they're getting the GPIO regs + whether they like it or not! */ + unsigned long gpio_page = inst->gpio_regs_phys >> PAGE_SHIFT; + + vma->vm_page_prot = phys_mem_access_prot(file, gpio_page, + PAGE_SIZE, + vma->vm_page_prot); + vma->vm_ops = &bcm2835_gpiomem_vm_ops; + if (remap_pfn_range(vma, vma->vm_start, + gpio_page, + PAGE_SIZE, + vma->vm_page_prot)) { + return -EAGAIN; + } + return 0; +} + +static const struct file_operations +bcm2835_gpiomem_fops = { + .owner = THIS_MODULE, + .open = bcm2835_gpiomem_open, + .release = bcm2835_gpiomem_release, + .mmap = bcm2835_gpiomem_mmap, +}; + + + /**************************************************************************** +* +* Probe and remove functions +* +***************************************************************************/ + + +static int bcm2835_gpiomem_probe(struct platform_device *pdev) +{ + int err; + void *ptr_err; + struct device *dev = &pdev->dev; + struct resource *ioresource; + + /* Allocate buffers and instance data */ + + inst = kzalloc(sizeof(struct bcm2835_gpiomem_instance), GFP_KERNEL); + + if (!inst) { + err = -ENOMEM; + goto failed_inst_alloc; + } + + inst->dev = dev; + + ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (ioresource) { + inst->gpio_regs_phys = ioresource->start; + } else { + dev_err(inst->dev, "failed to get IO resource"); + err = -ENOENT; + goto failed_get_resource; + } + + /* Create character device entries */ + + err = alloc_chrdev_region(&bcm2835_gpiomem_devid, + DEVICE_MINOR, 1, DEVICE_NAME); + if (err != 0) { + dev_err(inst->dev, "unable to allocate device number"); + goto failed_alloc_chrdev; + } + cdev_init(&bcm2835_gpiomem_cdev, &bcm2835_gpiomem_fops); + bcm2835_gpiomem_cdev.owner = THIS_MODULE; + err = cdev_add(&bcm2835_gpiomem_cdev, bcm2835_gpiomem_devid, 1); + if (err != 0) { + dev_err(inst->dev, "unable to register device"); + goto failed_cdev_add; + } + + /* Create sysfs entries */ + + bcm2835_gpiomem_class = class_create(THIS_MODULE, DEVICE_NAME); + ptr_err = bcm2835_gpiomem_class; + if (IS_ERR(ptr_err)) + goto failed_class_create; + + bcm2835_gpiomem_dev = device_create(bcm2835_gpiomem_class, NULL, + bcm2835_gpiomem_devid, NULL, + "gpiomem"); + ptr_err = bcm2835_gpiomem_dev; + if (IS_ERR(ptr_err)) + goto failed_device_create; + + dev_info(inst->dev, "Initialised: Registers at 0x%08lx", + inst->gpio_regs_phys); + + return 0; + +failed_device_create: + class_destroy(bcm2835_gpiomem_class); +failed_class_create: + cdev_del(&bcm2835_gpiomem_cdev); + err = PTR_ERR(ptr_err); +failed_cdev_add: + unregister_chrdev_region(bcm2835_gpiomem_devid, 1); +failed_alloc_chrdev: +failed_get_resource: + kfree(inst); +failed_inst_alloc: + dev_err(inst->dev, "could not load bcm2835_gpiomem"); + return err; +} + +static int bcm2835_gpiomem_remove(struct platform_device *pdev) +{ + struct device *dev = inst->dev; + + kfree(inst); + device_destroy(bcm2835_gpiomem_class, bcm2835_gpiomem_devid); + class_destroy(bcm2835_gpiomem_class); + cdev_del(&bcm2835_gpiomem_cdev); + unregister_chrdev_region(bcm2835_gpiomem_devid, 1); + + dev_info(dev, "GPIO mem driver removed - OK"); + return 0; +} + + /**************************************************************************** +* +* Register the driver with device tree +* +***************************************************************************/ + +static const struct of_device_id bcm2835_gpiomem_of_match[] = { + {.compatible = "brcm,bcm2835-gpiomem",}, + { /* sentinel */ }, +}; + +MODULE_DEVICE_TABLE(of, bcm2835_gpiomem_of_match); + +static struct platform_driver bcm2835_gpiomem_driver = { + .probe = bcm2835_gpiomem_probe, + .remove = bcm2835_gpiomem_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = bcm2835_gpiomem_of_match, + }, +}; + +module_platform_driver(bcm2835_gpiomem_driver); + +MODULE_ALIAS("platform:gpiomem-bcm2835"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("gpiomem driver for accessing GPIO from userspace"); +MODULE_AUTHOR("Luke Wren "); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/broadcom/bcm2835_smi_dev.c linux-vendor/drivers/char/broadcom/bcm2835_smi_dev.c --- linux-4.18.16/drivers/char/broadcom/bcm2835_smi_dev.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/char/broadcom/bcm2835_smi_dev.c 2018-10-29 19:31:20.941763143 +0100 @@ -0,0 +1,402 @@ +/** + * Character device driver for Broadcom Secondary Memory Interface + * + * Written by Luke Wren + * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2, as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DEVICE_NAME "bcm2835-smi-dev" +#define DRIVER_NAME "smi-dev-bcm2835" +#define DEVICE_MINOR 0 + +static struct cdev bcm2835_smi_cdev; +static dev_t bcm2835_smi_devid; +static struct class *bcm2835_smi_class; +static struct device *bcm2835_smi_dev; + +struct bcm2835_smi_dev_instance { + struct device *dev; +}; + +static struct bcm2835_smi_instance *smi_inst; +static struct bcm2835_smi_dev_instance *inst; + +static const char *const ioctl_names[] = { + "READ_SETTINGS", + "WRITE_SETTINGS", + "ADDRESS" +}; + +/**************************************************************************** +* +* SMI chardev file ops +* +***************************************************************************/ +static long +bcm2835_smi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long ret = 0; + + dev_info(inst->dev, "serving ioctl..."); + + switch (cmd) { + case BCM2835_SMI_IOC_GET_SETTINGS:{ + struct smi_settings *settings; + + dev_info(inst->dev, "Reading SMI settings to user."); + settings = bcm2835_smi_get_settings_from_regs(smi_inst); + if (copy_to_user((void *)arg, settings, + sizeof(struct smi_settings))) + dev_err(inst->dev, "settings copy failed."); + break; + } + case BCM2835_SMI_IOC_WRITE_SETTINGS:{ + struct smi_settings *settings; + + dev_info(inst->dev, "Setting user's SMI settings."); + settings = bcm2835_smi_get_settings_from_regs(smi_inst); + if (copy_from_user(settings, (void *)arg, + sizeof(struct smi_settings))) + dev_err(inst->dev, "settings copy failed."); + else + bcm2835_smi_set_regs_from_settings(smi_inst); + break; + } + case BCM2835_SMI_IOC_ADDRESS: + dev_info(inst->dev, "SMI address set: 0x%02x", (int)arg); + bcm2835_smi_set_address(smi_inst, arg); + break; + default: + dev_err(inst->dev, "invalid ioctl cmd: %d", cmd); + ret = -ENOTTY; + break; + } + + return ret; +} + +static int bcm2835_smi_open(struct inode *inode, struct file *file) +{ + int dev = iminor(inode); + + dev_dbg(inst->dev, "SMI device opened."); + + if (dev != DEVICE_MINOR) { + dev_err(inst->dev, + "bcm2835_smi_release: Unknown minor device: %d", + dev); + return -ENXIO; + } + + return 0; +} + +static int bcm2835_smi_release(struct inode *inode, struct file *file) +{ + int dev = iminor(inode); + + if (dev != DEVICE_MINOR) { + dev_err(inst->dev, + "bcm2835_smi_release: Unknown minor device %d", dev); + return -ENXIO; + } + + return 0; +} + +static ssize_t dma_bounce_user( + enum dma_transfer_direction dma_dir, + char __user *user_ptr, + size_t count, + struct bcm2835_smi_bounce_info *bounce) +{ + int chunk_size; + int chunk_no = 0; + int count_left = count; + + while (count_left) { + int rv; + void *buf; + + /* Wait for current chunk to complete: */ + if (down_timeout(&bounce->callback_sem, + msecs_to_jiffies(1000))) { + dev_err(inst->dev, "DMA bounce timed out"); + count -= (count_left); + break; + } + + if (bounce->callback_sem.count >= DMA_BOUNCE_BUFFER_COUNT - 1) + dev_err(inst->dev, "WARNING: Ring buffer overflow"); + chunk_size = count_left > DMA_BOUNCE_BUFFER_SIZE ? + DMA_BOUNCE_BUFFER_SIZE : count_left; + buf = bounce->buffer[chunk_no % DMA_BOUNCE_BUFFER_COUNT]; + if (dma_dir == DMA_DEV_TO_MEM) + rv = copy_to_user(user_ptr, buf, chunk_size); + else + rv = copy_from_user(buf, user_ptr, chunk_size); + if (rv) + dev_err(inst->dev, "copy_*_user() failed!: %d", rv); + user_ptr += chunk_size; + count_left -= chunk_size; + chunk_no++; + } + return count; +} + +static ssize_t +bcm2835_read_file(struct file *f, char __user *user_ptr, + size_t count, loff_t *offs) +{ + int odd_bytes; + + dev_dbg(inst->dev, "User reading %d bytes from SMI.", count); + /* We don't want to DMA a number of bytes % 4 != 0 (32 bit FIFO) */ + if (count > DMA_THRESHOLD_BYTES) + odd_bytes = count & 0x3; + else + odd_bytes = count; + count -= odd_bytes; + if (count) { + struct bcm2835_smi_bounce_info *bounce; + + count = bcm2835_smi_user_dma(smi_inst, + DMA_DEV_TO_MEM, user_ptr, count, + &bounce); + if (count) + count = dma_bounce_user(DMA_DEV_TO_MEM, user_ptr, + count, bounce); + } + if (odd_bytes) { + /* Read from FIFO directly if not using DMA */ + uint8_t buf[DMA_THRESHOLD_BYTES]; + + bcm2835_smi_read_buf(smi_inst, buf, odd_bytes); + if (copy_to_user(user_ptr, buf, odd_bytes)) + dev_err(inst->dev, "copy_to_user() failed."); + count += odd_bytes; + + } + return count; +} + +static ssize_t +bcm2835_write_file(struct file *f, const char __user *user_ptr, + size_t count, loff_t *offs) +{ + int odd_bytes; + + dev_dbg(inst->dev, "User writing %d bytes to SMI.", count); + if (count > DMA_THRESHOLD_BYTES) + odd_bytes = count & 0x3; + else + odd_bytes = count; + count -= odd_bytes; + if (count) { + struct bcm2835_smi_bounce_info *bounce; + + count = bcm2835_smi_user_dma(smi_inst, + DMA_MEM_TO_DEV, (char __user *)user_ptr, count, + &bounce); + if (count) + count = dma_bounce_user(DMA_MEM_TO_DEV, + (char __user *)user_ptr, + count, bounce); + } + if (odd_bytes) { + uint8_t buf[DMA_THRESHOLD_BYTES]; + + if (copy_from_user(buf, user_ptr, odd_bytes)) + dev_err(inst->dev, "copy_from_user() failed."); + else + bcm2835_smi_write_buf(smi_inst, buf, odd_bytes); + count += odd_bytes; + } + return count; +} + +static const struct file_operations +bcm2835_smi_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = bcm2835_smi_ioctl, + .open = bcm2835_smi_open, + .release = bcm2835_smi_release, + .read = bcm2835_read_file, + .write = bcm2835_write_file, +}; + + +/**************************************************************************** +* +* bcm2835_smi_probe - called when the driver is loaded. +* +***************************************************************************/ + +static int bcm2835_smi_dev_probe(struct platform_device *pdev) +{ + int err; + void *ptr_err; + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node, *smi_node; + + if (!node) { + dev_err(dev, "No device tree node supplied!"); + return -EINVAL; + } + + smi_node = of_parse_phandle(node, "smi_handle", 0); + + if (!smi_node) { + dev_err(dev, "No such property: smi_handle"); + return -ENXIO; + } + + smi_inst = bcm2835_smi_get(smi_node); + + if (!smi_inst) + return -EPROBE_DEFER; + + /* Allocate buffers and instance data */ + + inst = devm_kzalloc(dev, sizeof(*inst), GFP_KERNEL); + + if (!inst) + return -ENOMEM; + + inst->dev = dev; + + /* Create character device entries */ + + err = alloc_chrdev_region(&bcm2835_smi_devid, + DEVICE_MINOR, 1, DEVICE_NAME); + if (err != 0) { + dev_err(inst->dev, "unable to allocate device number"); + return -ENOMEM; + } + cdev_init(&bcm2835_smi_cdev, &bcm2835_smi_fops); + bcm2835_smi_cdev.owner = THIS_MODULE; + err = cdev_add(&bcm2835_smi_cdev, bcm2835_smi_devid, 1); + if (err != 0) { + dev_err(inst->dev, "unable to register device"); + err = -ENOMEM; + goto failed_cdev_add; + } + + /* Create sysfs entries */ + + bcm2835_smi_class = class_create(THIS_MODULE, DEVICE_NAME); + ptr_err = bcm2835_smi_class; + if (IS_ERR(ptr_err)) + goto failed_class_create; + + bcm2835_smi_dev = device_create(bcm2835_smi_class, NULL, + bcm2835_smi_devid, NULL, + "smi"); + ptr_err = bcm2835_smi_dev; + if (IS_ERR(ptr_err)) + goto failed_device_create; + + dev_info(inst->dev, "initialised"); + + return 0; + +failed_device_create: + class_destroy(bcm2835_smi_class); +failed_class_create: + cdev_del(&bcm2835_smi_cdev); + err = PTR_ERR(ptr_err); +failed_cdev_add: + unregister_chrdev_region(bcm2835_smi_devid, 1); + dev_err(dev, "could not load bcm2835_smi_dev"); + return err; +} + +/**************************************************************************** +* +* bcm2835_smi_remove - called when the driver is unloaded. +* +***************************************************************************/ + +static int bcm2835_smi_dev_remove(struct platform_device *pdev) +{ + device_destroy(bcm2835_smi_class, bcm2835_smi_devid); + class_destroy(bcm2835_smi_class); + cdev_del(&bcm2835_smi_cdev); + unregister_chrdev_region(bcm2835_smi_devid, 1); + + dev_info(inst->dev, "SMI character dev removed - OK"); + return 0; +} + +/**************************************************************************** +* +* Register the driver with device tree +* +***************************************************************************/ + +static const struct of_device_id bcm2835_smi_dev_of_match[] = { + {.compatible = "brcm,bcm2835-smi-dev",}, + { /* sentinel */ }, +}; + +MODULE_DEVICE_TABLE(of, bcm2835_smi_dev_of_match); + +static struct platform_driver bcm2835_smi_dev_driver = { + .probe = bcm2835_smi_dev_probe, + .remove = bcm2835_smi_dev_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = bcm2835_smi_dev_of_match, + }, +}; + +module_platform_driver(bcm2835_smi_dev_driver); + +MODULE_ALIAS("platform:smi-dev-bcm2835"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION( + "Character device driver for BCM2835's secondary memory interface"); +MODULE_AUTHOR("Luke Wren "); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/broadcom/Kconfig linux-vendor/drivers/char/broadcom/Kconfig --- linux-4.18.16/drivers/char/broadcom/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/char/broadcom/Kconfig 2018-10-29 19:31:20.941763143 +0100 @@ -0,0 +1,51 @@ +# +# Broadcom char driver config +# + +menuconfig BRCM_CHAR_DRIVERS + bool "Broadcom Char Drivers" + help + Broadcom's char drivers + +if BRCM_CHAR_DRIVERS + +config BCM2708_VCMEM + bool "Videocore Memory" + default y + help + Helper for videocore memory access and total size allocation. + +config BCM_VCIO + tristate "Mailbox userspace access" + depends on BCM2835_MBOX + help + Gives access to the mailbox property channel from userspace. + +endif + +config BCM_VC_SM + bool "VMCS Shared Memory" + depends on BCM2835_VCHIQ + select BCM2708_VCMEM + select DMA_SHARED_BUFFER + default n + help + Support for the VC shared memory on the Broadcom reference + design. Uses the VCHIQ stack. + +config BCM2835_DEVGPIOMEM + tristate "/dev/gpiomem rootless GPIO access via mmap() on the BCM2835" + default m + help + Provides users with root-free access to the GPIO registers + on the 2835. Calling mmap(/dev/gpiomem) will map the GPIO + register page to the user's pointer. + +config BCM2835_SMI_DEV + tristate "Character device driver for BCM2835 Secondary Memory Interface" + depends on BCM2835_SMI + default m + help + This driver provides a character device interface (ioctl + read/write) to + Broadcom's Secondary Memory interface. The low-level functionality is provided + by the SMI driver itself. diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/broadcom/Makefile linux-vendor/drivers/char/broadcom/Makefile --- linux-4.18.16/drivers/char/broadcom/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/char/broadcom/Makefile 2018-10-29 19:31:20.941763143 +0100 @@ -0,0 +1,6 @@ +obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o +obj-$(CONFIG_BCM_VCIO) += vcio.o +obj-$(CONFIG_BCM_VC_SM) += vc_sm/ + +obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o +obj-$(CONFIG_BCM2835_SMI_DEV) += bcm2835_smi_dev.o diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/broadcom/vcio.c linux-vendor/drivers/char/broadcom/vcio.c --- linux-4.18.16/drivers/char/broadcom/vcio.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/char/broadcom/vcio.c 2018-10-29 19:31:20.944762993 +0100 @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2010 Broadcom + * Copyright (C) 2015 Noralf Trønnes + * + * 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. + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MBOX_CHAN_PROPERTY 8 + +#define VCIO_IOC_MAGIC 100 +#define IOCTL_MBOX_PROPERTY _IOWR(VCIO_IOC_MAGIC, 0, char *) + +static struct { + dev_t devt; + struct cdev cdev; + struct class *class; + struct rpi_firmware *fw; +} vcio; + +static int vcio_user_property_list(void *user) +{ + u32 *buf, size; + int ret; + + /* The first 32-bit is the size of the buffer */ + if (copy_from_user(&size, user, sizeof(size))) + return -EFAULT; + + buf = kmalloc(size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + if (copy_from_user(buf, user, size)) { + kfree(buf); + return -EFAULT; + } + + /* Strip off protocol encapsulation */ + ret = rpi_firmware_property_list(vcio.fw, &buf[2], size - 12); + if (ret) { + kfree(buf); + return ret; + } + + buf[1] = RPI_FIRMWARE_STATUS_SUCCESS; + if (copy_to_user(user, buf, size)) + ret = -EFAULT; + + kfree(buf); + + return ret; +} + +static int vcio_device_open(struct inode *inode, struct file *file) +{ + try_module_get(THIS_MODULE); + + return 0; +} + +static int vcio_device_release(struct inode *inode, struct file *file) +{ + module_put(THIS_MODULE); + + return 0; +} + +static long vcio_device_ioctl(struct file *file, unsigned int ioctl_num, + unsigned long ioctl_param) +{ + switch (ioctl_num) { + case IOCTL_MBOX_PROPERTY: + return vcio_user_property_list((void *)ioctl_param); + default: + pr_err("unknown ioctl: %d\n", ioctl_num); + return -EINVAL; + } +} + +const struct file_operations vcio_fops = { + .unlocked_ioctl = vcio_device_ioctl, + .open = vcio_device_open, + .release = vcio_device_release, +}; + +static int __init vcio_init(void) +{ + struct device_node *np; + static struct device *dev; + int ret; + + np = of_find_compatible_node(NULL, NULL, + "raspberrypi,bcm2835-firmware"); +/* Uncomment this when we only boot with Device Tree + if (!of_device_is_available(np)) + return -ENODEV; +*/ + vcio.fw = rpi_firmware_get(np); + if (!vcio.fw) + return -ENODEV; + + ret = alloc_chrdev_region(&vcio.devt, 0, 1, "vcio"); + if (ret) { + pr_err("failed to allocate device number\n"); + return ret; + } + + cdev_init(&vcio.cdev, &vcio_fops); + vcio.cdev.owner = THIS_MODULE; + ret = cdev_add(&vcio.cdev, vcio.devt, 1); + if (ret) { + pr_err("failed to register device\n"); + goto err_unregister_chardev; + } + + /* + * Create sysfs entries + * 'bcm2708_vcio' is used for backwards compatibility so we don't break + * userspace. Raspian has a udev rule that changes the permissions. + */ + vcio.class = class_create(THIS_MODULE, "bcm2708_vcio"); + if (IS_ERR(vcio.class)) { + ret = PTR_ERR(vcio.class); + pr_err("failed to create class\n"); + goto err_cdev_del; + } + + dev = device_create(vcio.class, NULL, vcio.devt, NULL, "vcio"); + if (IS_ERR(dev)) { + ret = PTR_ERR(dev); + pr_err("failed to create device\n"); + goto err_class_destroy; + } + + return 0; + +err_class_destroy: + class_destroy(vcio.class); +err_cdev_del: + cdev_del(&vcio.cdev); +err_unregister_chardev: + unregister_chrdev_region(vcio.devt, 1); + + return ret; +} +module_init(vcio_init); + +static void __exit vcio_exit(void) +{ + device_destroy(vcio.class, vcio.devt); + class_destroy(vcio.class); + cdev_del(&vcio.cdev); + unregister_chrdev_region(vcio.devt, 1); +} +module_exit(vcio_exit); + +MODULE_AUTHOR("Gray Girling"); +MODULE_AUTHOR("Noralf Trønnes"); +MODULE_DESCRIPTION("Mailbox userspace access"); +MODULE_LICENSE("GPL"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/broadcom/vc_mem.c linux-vendor/drivers/char/broadcom/vc_mem.c --- linux-4.18.16/drivers/char/broadcom/vc_mem.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/char/broadcom/vc_mem.c 2018-10-29 19:31:20.942763093 +0100 @@ -0,0 +1,422 @@ +/***************************************************************************** +* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed to you +* under the terms of the GNU General Public License version 2, available at +* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). +* +* Notwithstanding the above, under no circumstances may you combine this +* software in any way with any other Broadcom software provided under a +* license other than the GPL, without Broadcom's express prior written +* consent. +*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "vc-mem" + +// Device (/dev) related variables +static dev_t vc_mem_devnum = 0; +static struct class *vc_mem_class = NULL; +static struct cdev vc_mem_cdev; +static int vc_mem_inited = 0; + +#ifdef CONFIG_DEBUG_FS +static struct dentry *vc_mem_debugfs_entry; +#endif + +/* + * Videocore memory addresses and size + * + * Drivers that wish to know the videocore memory addresses and sizes should + * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in + * headers. This allows the other drivers to not be tied down to a a certain + * address/size at compile time. + * + * In the future, the goal is to have the videocore memory virtual address and + * size be calculated at boot time rather than at compile time. The decision of + * where the videocore memory resides and its size would be in the hands of the + * bootloader (and/or kernel). When that happens, the values of these variables + * would be calculated and assigned in the init function. + */ +// in the 2835 VC in mapped above ARM, but ARM has full access to VC space +unsigned long mm_vc_mem_phys_addr = 0x00000000; +unsigned int mm_vc_mem_size = 0; +unsigned int mm_vc_mem_base = 0; + +EXPORT_SYMBOL(mm_vc_mem_phys_addr); +EXPORT_SYMBOL(mm_vc_mem_size); +EXPORT_SYMBOL(mm_vc_mem_base); + +static uint phys_addr = 0; +static uint mem_size = 0; +static uint mem_base = 0; + + +/**************************************************************************** +* +* vc_mem_open +* +***************************************************************************/ + +static int +vc_mem_open(struct inode *inode, struct file *file) +{ + (void) inode; + (void) file; + + pr_debug("%s: called file = 0x%p\n", __func__, file); + + return 0; +} + +/**************************************************************************** +* +* vc_mem_release +* +***************************************************************************/ + +static int +vc_mem_release(struct inode *inode, struct file *file) +{ + (void) inode; + (void) file; + + pr_debug("%s: called file = 0x%p\n", __func__, file); + + return 0; +} + +/**************************************************************************** +* +* vc_mem_get_size +* +***************************************************************************/ + +static void +vc_mem_get_size(void) +{ +} + +/**************************************************************************** +* +* vc_mem_get_base +* +***************************************************************************/ + +static void +vc_mem_get_base(void) +{ +} + +/**************************************************************************** +* +* vc_mem_get_current_size +* +***************************************************************************/ + +int +vc_mem_get_current_size(void) +{ + return mm_vc_mem_size; +} + +EXPORT_SYMBOL_GPL(vc_mem_get_current_size); + +/**************************************************************************** +* +* vc_mem_ioctl +* +***************************************************************************/ + +static long +vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int rc = 0; + + (void) cmd; + (void) arg; + + pr_debug("%s: called file = 0x%p\n", __func__, file); + + switch (cmd) { + case VC_MEM_IOC_MEM_PHYS_ADDR: + { + pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", + __func__, (void *) mm_vc_mem_phys_addr); + + if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, + sizeof (mm_vc_mem_phys_addr)) != 0) { + rc = -EFAULT; + } + break; + } + case VC_MEM_IOC_MEM_SIZE: + { + // Get the videocore memory size first + vc_mem_get_size(); + + pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, + mm_vc_mem_size); + + if (copy_to_user((void *) arg, &mm_vc_mem_size, + sizeof (mm_vc_mem_size)) != 0) { + rc = -EFAULT; + } + break; + } + case VC_MEM_IOC_MEM_BASE: + { + // Get the videocore memory base + vc_mem_get_base(); + + pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, + mm_vc_mem_base); + + if (copy_to_user((void *) arg, &mm_vc_mem_base, + sizeof (mm_vc_mem_base)) != 0) { + rc = -EFAULT; + } + break; + } + case VC_MEM_IOC_MEM_LOAD: + { + // Get the videocore memory base + vc_mem_get_base(); + + pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __func__, + mm_vc_mem_base); + + if (copy_to_user((void *) arg, &mm_vc_mem_base, + sizeof (mm_vc_mem_base)) != 0) { + rc = -EFAULT; + } + break; + } + default: + { + return -ENOTTY; + } + } + pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc); + + return rc; +} + +/**************************************************************************** +* +* vc_mem_mmap +* +***************************************************************************/ + +static int +vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) +{ + int rc = 0; + unsigned long length = vma->vm_end - vma->vm_start; + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + + pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", + __func__, (long) vma->vm_start, (long) vma->vm_end, + (long) vma->vm_pgoff); + + if (offset + length > mm_vc_mem_size) { + pr_err("%s: length %ld is too big\n", __func__, length); + return -EINVAL; + } + // Do not cache the memory map + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + rc = remap_pfn_range(vma, vma->vm_start, + (mm_vc_mem_phys_addr >> PAGE_SHIFT) + + vma->vm_pgoff, length, vma->vm_page_prot); + if (rc != 0) { + pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); + } + + return rc; +} + +/**************************************************************************** +* +* File Operations for the driver. +* +***************************************************************************/ + +static const struct file_operations vc_mem_fops = { + .owner = THIS_MODULE, + .open = vc_mem_open, + .release = vc_mem_release, + .unlocked_ioctl = vc_mem_ioctl, + .mmap = vc_mem_mmap, +}; + +#ifdef CONFIG_DEBUG_FS +static void vc_mem_debugfs_deinit(void) +{ + debugfs_remove_recursive(vc_mem_debugfs_entry); + vc_mem_debugfs_entry = NULL; +} + + +static int vc_mem_debugfs_init( + struct device *dev) +{ + vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL); + if (!vc_mem_debugfs_entry) { + dev_warn(dev, "could not create debugfs entry\n"); + return -EFAULT; + } + + if (!debugfs_create_x32("vc_mem_phys_addr", + 0444, + vc_mem_debugfs_entry, + (u32 *)&mm_vc_mem_phys_addr)) { + dev_warn(dev, "%s:could not create vc_mem_phys entry\n", + __func__); + goto fail; + } + + if (!debugfs_create_x32("vc_mem_size", + 0444, + vc_mem_debugfs_entry, + (u32 *)&mm_vc_mem_size)) { + dev_warn(dev, "%s:could not create vc_mem_size entry\n", + __func__); + goto fail; + } + + if (!debugfs_create_x32("vc_mem_base", + 0444, + vc_mem_debugfs_entry, + (u32 *)&mm_vc_mem_base)) { + dev_warn(dev, "%s:could not create vc_mem_base entry\n", + __func__); + goto fail; + } + + return 0; + +fail: + vc_mem_debugfs_deinit(); + return -EFAULT; +} + +#endif /* CONFIG_DEBUG_FS */ + + +/**************************************************************************** +* +* vc_mem_init +* +***************************************************************************/ + +static int __init +vc_mem_init(void) +{ + int rc = -EFAULT; + struct device *dev; + + pr_debug("%s: called\n", __func__); + + mm_vc_mem_phys_addr = phys_addr; + mm_vc_mem_size = mem_size; + mm_vc_mem_base = mem_base; + + vc_mem_get_size(); + + pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", + mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); + + if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { + pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", + __func__, rc); + goto out_err; + } + + cdev_init(&vc_mem_cdev, &vc_mem_fops); + if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { + pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); + goto out_unregister; + } + + vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); + if (IS_ERR(vc_mem_class)) { + rc = PTR_ERR(vc_mem_class); + pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); + goto out_cdev_del; + } + + dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, + DRIVER_NAME); + if (IS_ERR(dev)) { + rc = PTR_ERR(dev); + pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); + goto out_class_destroy; + } + +#ifdef CONFIG_DEBUG_FS + /* don't fail if the debug entries cannot be created */ + vc_mem_debugfs_init(dev); +#endif + + vc_mem_inited = 1; + return 0; + + device_destroy(vc_mem_class, vc_mem_devnum); + + out_class_destroy: + class_destroy(vc_mem_class); + vc_mem_class = NULL; + + out_cdev_del: + cdev_del(&vc_mem_cdev); + + out_unregister: + unregister_chrdev_region(vc_mem_devnum, 1); + + out_err: + return -1; +} + +/**************************************************************************** +* +* vc_mem_exit +* +***************************************************************************/ + +static void __exit +vc_mem_exit(void) +{ + pr_debug("%s: called\n", __func__); + + if (vc_mem_inited) { +#if CONFIG_DEBUG_FS + vc_mem_debugfs_deinit(); +#endif + device_destroy(vc_mem_class, vc_mem_devnum); + class_destroy(vc_mem_class); + cdev_del(&vc_mem_cdev); + unregister_chrdev_region(vc_mem_devnum, 1); + } +} + +module_init(vc_mem_init); +module_exit(vc_mem_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Broadcom Corporation"); + +module_param(phys_addr, uint, 0644); +module_param(mem_size, uint, 0644); +module_param(mem_base, uint, 0644); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/broadcom/vc_sm/Makefile linux-vendor/drivers/char/broadcom/vc_sm/Makefile --- linux-4.18.16/drivers/char/broadcom/vc_sm/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/char/broadcom/vc_sm/Makefile 2018-10-29 19:31:20.942763093 +0100 @@ -0,0 +1,9 @@ +ccflags-$(CONFIG_BCM_VC_SM) += -Werror -Wall -Wstrict-prototypes -Wno-trigraphs -O2 +ccflags-$(CONFIG_BCM_VC_SM) += -I"drivers/staging/vc04_services" -I"drivers/staging/vc04_services/interface/vchi" -I"drivers/staging/vc04_services/interface/vchiq_arm" -I"$(srctree)/fs/" +ccflags-$(CONFIG_BCM_VC_SM) += -DOS_ASSERT_FAILURE -D__STDC_VERSION=199901L -D__STDC_VERSION__=199901L -D__VCCOREVER__=0 -D__KERNEL__ -D__linux__ + +obj-$(CONFIG_BCM_VC_SM) := vc-sm.o + +vc-sm-objs := \ + vmcs_sm.o \ + vc_vchi_sm.o diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/broadcom/vc_sm/vc_sm_defs.h linux-vendor/drivers/char/broadcom/vc_sm/vc_sm_defs.h --- linux-4.18.16/drivers/char/broadcom/vc_sm/vc_sm_defs.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/char/broadcom/vc_sm/vc_sm_defs.h 2018-10-29 19:31:20.942763093 +0100 @@ -0,0 +1,237 @@ +/* + **************************************************************************** + * Copyright 2011 Broadcom Corporation. All rights reserved. + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available at + * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + **************************************************************************** + */ + +#ifndef __VC_SM_DEFS_H__INCLUDED__ +#define __VC_SM_DEFS_H__INCLUDED__ + +/* FourCC code used for VCHI connection */ +#define VC_SM_SERVER_NAME MAKE_FOURCC("SMEM") + +/* Maximum message length */ +#define VC_SM_MAX_MSG_LEN (sizeof(union vc_sm_msg_union_t) + \ + sizeof(struct vc_sm_msg_hdr_t)) +#define VC_SM_MAX_RSP_LEN (sizeof(union vc_sm_msg_union_t)) + +/* Resource name maximum size */ +#define VC_SM_RESOURCE_NAME 32 + +enum vc_sm_msg_type { + /* Message types supported for HOST->VC direction */ + + /* Allocate shared memory block */ + VC_SM_MSG_TYPE_ALLOC, + /* Lock allocated shared memory block */ + VC_SM_MSG_TYPE_LOCK, + /* Unlock allocated shared memory block */ + VC_SM_MSG_TYPE_UNLOCK, + /* Unlock allocated shared memory block, do not answer command */ + VC_SM_MSG_TYPE_UNLOCK_NOANS, + /* Free shared memory block */ + VC_SM_MSG_TYPE_FREE, + /* Resize a shared memory block */ + VC_SM_MSG_TYPE_RESIZE, + /* Walk the allocated shared memory block(s) */ + VC_SM_MSG_TYPE_WALK_ALLOC, + + /* A previously applied action will need to be reverted */ + VC_SM_MSG_TYPE_ACTION_CLEAN, + + /* + * Import a physical address and wrap into a MEM_HANDLE_T. + * Release with VC_SM_MSG_TYPE_FREE. + */ + VC_SM_MSG_TYPE_IMPORT, + + /* Message types supported for VC->HOST direction */ + + /* + * VC has finished with an imported memory allocation. + * Release any Linux reference counts on the underlying block. + */ + VC_SM_MSG_TYPE_RELEASED, + + VC_SM_MSG_TYPE_MAX +}; + +/* Type of memory to be allocated */ +enum vc_sm_alloc_type_t { + VC_SM_ALLOC_CACHED, + VC_SM_ALLOC_NON_CACHED, +}; + +/* Message header for all messages in HOST->VC direction */ +struct vc_sm_msg_hdr_t { + int32_t type; + uint32_t trans_id; + uint8_t body[0]; + +}; + +/* Request to allocate memory (HOST->VC) */ +struct vc_sm_alloc_t { + /* type of memory to allocate */ + enum vc_sm_alloc_type_t type; + /* byte amount of data to allocate per unit */ + uint32_t base_unit; + /* number of unit to allocate */ + uint32_t num_unit; + /* alignement to be applied on allocation */ + uint32_t alignement; + /* identity of who allocated this block */ + uint32_t allocator; + /* resource name (for easier tracking on vc side) */ + char name[VC_SM_RESOURCE_NAME]; + +}; + +/* Result of a requested memory allocation (VC->HOST) */ +struct vc_sm_alloc_result_t { + /* Transaction identifier */ + uint32_t trans_id; + + /* Resource handle */ + uint32_t res_handle; + /* Pointer to resource buffer */ + uint32_t res_mem; + /* Resource base size (bytes) */ + uint32_t res_base_size; + /* Resource number */ + uint32_t res_num; + +}; + +/* Request to free a previously allocated memory (HOST->VC) */ +struct vc_sm_free_t { + /* Resource handle (returned from alloc) */ + uint32_t res_handle; + /* Resource buffer (returned from alloc) */ + uint32_t res_mem; + +}; + +/* Request to lock a previously allocated memory (HOST->VC) */ +struct vc_sm_lock_unlock_t { + /* Resource handle (returned from alloc) */ + uint32_t res_handle; + /* Resource buffer (returned from alloc) */ + uint32_t res_mem; + +}; + +/* Request to resize a previously allocated memory (HOST->VC) */ +struct vc_sm_resize_t { + /* Resource handle (returned from alloc) */ + uint32_t res_handle; + /* Resource buffer (returned from alloc) */ + uint32_t res_mem; + /* Resource *new* size requested (bytes) */ + uint32_t res_new_size; + +}; + +/* Result of a requested memory lock (VC->HOST) */ +struct vc_sm_lock_result_t { + /* Transaction identifier */ + uint32_t trans_id; + + /* Resource handle */ + uint32_t res_handle; + /* Pointer to resource buffer */ + uint32_t res_mem; + /* + * Pointer to former resource buffer if the memory + * was reallocated + */ + uint32_t res_old_mem; + +}; + +/* Generic result for a request (VC->HOST) */ +struct vc_sm_result_t { + /* Transaction identifier */ + uint32_t trans_id; + + int32_t success; + +}; + +/* Request to revert a previously applied action (HOST->VC) */ +struct vc_sm_action_clean_t { + /* Action of interest */ + enum vc_sm_msg_type res_action; + /* Transaction identifier for the action of interest */ + uint32_t action_trans_id; + +}; + +/* Request to remove all data associated with a given allocator (HOST->VC) */ +struct vc_sm_free_all_t { + /* Allocator identifier */ + uint32_t allocator; +}; + +/* Request to import memory (HOST->VC) */ +struct vc_sm_import { + /* type of memory to allocate */ + enum vc_sm_alloc_type_t type; + /* pointer to the VC (ie physical) address of the allocated memory */ + uint32_t addr; + /* size of buffer */ + uint32_t size; + /* opaque handle returned in RELEASED messages */ + int32_t kernel_id; + /* Allocator identifier */ + uint32_t allocator; + /* resource name (for easier tracking on vc side) */ + char name[VC_SM_RESOURCE_NAME]; +}; + +/* Result of a requested memory import (VC->HOST) */ +struct vc_sm_import_result { + /* Transaction identifier */ + uint32_t trans_id; + + /* Resource handle */ + uint32_t res_handle; +}; + +/* Notification that VC has finished with an allocation (VC->HOST) */ +struct vc_sm_released { + /* pointer to the VC (ie physical) address of the allocated memory */ + uint32_t addr; + /* size of buffer */ + uint32_t size; + /* opaque handle returned in RELEASED messages */ + int32_t kernel_id; +}; + +/* Union of ALL messages */ +union vc_sm_msg_union_t { + struct vc_sm_alloc_t alloc; + struct vc_sm_alloc_result_t alloc_result; + struct vc_sm_free_t free; + struct vc_sm_lock_unlock_t lock_unlock; + struct vc_sm_action_clean_t action_clean; + struct vc_sm_resize_t resize; + struct vc_sm_lock_result_t lock_result; + struct vc_sm_result_t result; + struct vc_sm_free_all_t free_all; + struct vc_sm_import import; + struct vc_sm_import_result import_result; + struct vc_sm_released released; +}; + +#endif /* __VC_SM_DEFS_H__INCLUDED__ */ diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/broadcom/vc_sm/vc_sm_knl.h linux-vendor/drivers/char/broadcom/vc_sm/vc_sm_knl.h --- linux-4.18.16/drivers/char/broadcom/vc_sm/vc_sm_knl.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/char/broadcom/vc_sm/vc_sm_knl.h 2018-10-29 19:31:20.942763093 +0100 @@ -0,0 +1,53 @@ +/* + **************************************************************************** + * Copyright 2011 Broadcom Corporation. All rights reserved. + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available at + * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + **************************************************************************** + */ + +#ifndef __VC_SM_KNL_H__INCLUDED__ +#define __VC_SM_KNL_H__INCLUDED__ + +#if !defined(__KERNEL__) +#error "This interface is for kernel use only..." +#endif + +/* Type of memory to be locked (ie mapped) */ +enum vc_sm_lock_cache_mode { + VC_SM_LOCK_CACHED, + VC_SM_LOCK_NON_CACHED, +}; + +/* Allocate a shared memory handle and block. */ +int vc_sm_alloc(struct vc_sm_alloc_t *alloc, int *handle); + +/* Free a previously allocated shared memory handle and block. */ +int vc_sm_free(int handle); + +/* Lock a memory handle for use by kernel. */ +int vc_sm_lock(int handle, enum vc_sm_lock_cache_mode mode, + unsigned long *data); + +/* Unlock a memory handle in use by kernel. */ +int vc_sm_unlock(int handle, int flush, int no_vc_unlock); + +/* Get an internal resource handle mapped from the external one. */ +int vc_sm_int_handle(int handle); + +/* Map a shared memory region for use by kernel. */ +int vc_sm_map(int handle, unsigned int sm_addr, + enum vc_sm_lock_cache_mode mode, unsigned long *data); + +/* Import a block of memory into the GPU space. */ +int vc_sm_import_dmabuf(struct dma_buf *dmabuf, int *handle); + +#endif /* __VC_SM_KNL_H__INCLUDED__ */ diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/broadcom/vc_sm/vc_vchi_sm.c linux-vendor/drivers/char/broadcom/vc_sm/vc_vchi_sm.c --- linux-4.18.16/drivers/char/broadcom/vc_sm/vc_vchi_sm.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/char/broadcom/vc_sm/vc_vchi_sm.c 2018-10-29 19:31:20.942763093 +0100 @@ -0,0 +1,516 @@ +/* + **************************************************************************** + * Copyright 2011-2012 Broadcom Corporation. All rights reserved. + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available at + * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + **************************************************************************** + */ + +/* ---- Include Files ----------------------------------------------------- */ +#include +#include +#include +#include +#include +#include +#include + +#include "vc_vchi_sm.h" + +#define VC_SM_VER 1 +#define VC_SM_MIN_VER 0 + +/* ---- Private Constants and Types -------------------------------------- */ + +/* Command blocks come from a pool */ +#define SM_MAX_NUM_CMD_RSP_BLKS 32 + +struct sm_cmd_rsp_blk { + struct list_head head; /* To create lists */ + struct semaphore sema; /* To be signaled when the response is there */ + + uint16_t id; + uint16_t length; + + uint8_t msg[VC_SM_MAX_MSG_LEN]; + + uint32_t wait:1; + uint32_t sent:1; + uint32_t alloc:1; + +}; + +struct sm_instance { + uint32_t num_connections; + VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS]; + struct task_struct *io_thread; + struct semaphore io_sema; + + uint32_t trans_id; + + struct mutex lock; + struct list_head cmd_list; + struct list_head rsp_list; + struct list_head dead_list; + + struct sm_cmd_rsp_blk free_blk[SM_MAX_NUM_CMD_RSP_BLKS]; + struct list_head free_list; + struct mutex free_lock; + struct semaphore free_sema; + +}; + +/* ---- Private Variables ------------------------------------------------ */ + +/* ---- Private Function Prototypes -------------------------------------- */ + +/* ---- Private Functions ------------------------------------------------ */ +static int +bcm2835_vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle, + void *data, + unsigned int size) +{ + return vchi_queue_kernel_message(handle, + data, + size); +} + +static struct +sm_cmd_rsp_blk *vc_vchi_cmd_create(struct sm_instance *instance, + enum vc_sm_msg_type id, void *msg, + uint32_t size, int wait) +{ + struct sm_cmd_rsp_blk *blk; + struct vc_sm_msg_hdr_t *hdr; + + if (down_interruptible(&instance->free_sema)) { + blk = kmalloc(sizeof(*blk), GFP_KERNEL); + if (!blk) + return NULL; + + blk->alloc = 1; + sema_init(&blk->sema, 0); + } else { + mutex_lock(&instance->free_lock); + blk = + list_first_entry(&instance->free_list, + struct sm_cmd_rsp_blk, head); + list_del(&blk->head); + mutex_unlock(&instance->free_lock); + } + + blk->sent = 0; + blk->wait = wait; + blk->length = sizeof(*hdr) + size; + + hdr = (struct vc_sm_msg_hdr_t *) blk->msg; + hdr->type = id; + mutex_lock(&instance->lock); + hdr->trans_id = blk->id = ++instance->trans_id; + mutex_unlock(&instance->lock); + + if (size) + memcpy(hdr->body, msg, size); + + return blk; +} + +static void +vc_vchi_cmd_delete(struct sm_instance *instance, struct sm_cmd_rsp_blk *blk) +{ + if (blk->alloc) { + kfree(blk); + return; + } + + mutex_lock(&instance->free_lock); + list_add(&blk->head, &instance->free_list); + mutex_unlock(&instance->free_lock); + up(&instance->free_sema); +} + +static int vc_vchi_sm_videocore_io(void *arg) +{ + struct sm_instance *instance = arg; + struct sm_cmd_rsp_blk *cmd = NULL, *cmd_tmp; + struct vc_sm_result_t *reply; + uint32_t reply_len; + int32_t status; + int svc_use = 1; + + while (1) { + if (svc_use) + vchi_service_release(instance->vchi_handle[0]); + svc_use = 0; + if (!down_interruptible(&instance->io_sema)) { + vchi_service_use(instance->vchi_handle[0]); + svc_use = 1; + + do { + /* + * Get new command and move it to response list + */ + mutex_lock(&instance->lock); + if (list_empty(&instance->cmd_list)) { + /* no more commands to process */ + mutex_unlock(&instance->lock); + break; + } + cmd = + list_first_entry(&instance->cmd_list, + struct sm_cmd_rsp_blk, + head); + list_move(&cmd->head, &instance->rsp_list); + cmd->sent = 1; + mutex_unlock(&instance->lock); + + /* Send the command */ + status = bcm2835_vchi_msg_queue( + instance->vchi_handle[0], + cmd->msg, cmd->length); + if (status) { + pr_err("%s: failed to queue message (%d)", + __func__, status); + } + + /* If no reply is needed then we're done */ + if (!cmd->wait) { + mutex_lock(&instance->lock); + list_del(&cmd->head); + mutex_unlock(&instance->lock); + vc_vchi_cmd_delete(instance, cmd); + continue; + } + + if (status) { + up(&cmd->sema); + continue; + } + + } while (1); + + while (!vchi_msg_peek + (instance->vchi_handle[0], (void **)&reply, + &reply_len, VCHI_FLAGS_NONE)) { + mutex_lock(&instance->lock); + list_for_each_entry(cmd, &instance->rsp_list, + head) { + if (cmd->id == reply->trans_id) + break; + } + mutex_unlock(&instance->lock); + + if (&cmd->head == &instance->rsp_list) { + pr_debug("%s: received response %u, throw away...", + __func__, reply->trans_id); + } else if (reply_len > sizeof(cmd->msg)) { + pr_err("%s: reply too big (%u) %u, throw away...", + __func__, reply_len, + reply->trans_id); + } else { + memcpy(cmd->msg, reply, reply_len); + up(&cmd->sema); + } + + vchi_msg_remove(instance->vchi_handle[0]); + } + + /* Go through the dead list and free them */ + mutex_lock(&instance->lock); + list_for_each_entry_safe(cmd, cmd_tmp, + &instance->dead_list, head) { + list_del(&cmd->head); + vc_vchi_cmd_delete(instance, cmd); + } + mutex_unlock(&instance->lock); + } + } + + return 0; +} + +static void vc_sm_vchi_callback(void *param, + const VCHI_CALLBACK_REASON_T reason, + void *msg_handle) +{ + struct sm_instance *instance = param; + + (void)msg_handle; + + switch (reason) { + case VCHI_CALLBACK_MSG_AVAILABLE: + up(&instance->io_sema); + break; + + case VCHI_CALLBACK_SERVICE_CLOSED: + pr_info("%s: service CLOSED!!", __func__); + default: + break; + } +} + +struct sm_instance *vc_vchi_sm_init(VCHI_INSTANCE_T vchi_instance, + VCHI_CONNECTION_T **vchi_connections, + uint32_t num_connections) +{ + uint32_t i; + struct sm_instance *instance; + int status; + + pr_debug("%s: start", __func__); + + if (num_connections > VCHI_MAX_NUM_CONNECTIONS) { + pr_err("%s: unsupported number of connections %u (max=%u)", + __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS); + + goto err_null; + } + /* Allocate memory for this instance */ + instance = kzalloc(sizeof(*instance), GFP_KERNEL); + + /* Misc initialisations */ + mutex_init(&instance->lock); + sema_init(&instance->io_sema, 0); + INIT_LIST_HEAD(&instance->cmd_list); + INIT_LIST_HEAD(&instance->rsp_list); + INIT_LIST_HEAD(&instance->dead_list); + INIT_LIST_HEAD(&instance->free_list); + sema_init(&instance->free_sema, SM_MAX_NUM_CMD_RSP_BLKS); + mutex_init(&instance->free_lock); + for (i = 0; i < SM_MAX_NUM_CMD_RSP_BLKS; i++) { + sema_init(&instance->free_blk[i].sema, 0); + list_add(&instance->free_blk[i].head, &instance->free_list); + } + + /* Open the VCHI service connections */ + instance->num_connections = num_connections; + for (i = 0; i < num_connections; i++) { + SERVICE_CREATION_T params = { + VCHI_VERSION_EX(VC_SM_VER, VC_SM_MIN_VER), + VC_SM_SERVER_NAME, + vchi_connections[i], + 0, + 0, + vc_sm_vchi_callback, + instance, + 0, + 0, + 0, + }; + + status = vchi_service_open(vchi_instance, + ¶ms, &instance->vchi_handle[i]); + if (status) { + pr_err("%s: failed to open VCHI service (%d)", + __func__, status); + + goto err_close_services; + } + } + + /* Create the thread which takes care of all io to/from videoocore. */ + instance->io_thread = kthread_create(&vc_vchi_sm_videocore_io, + (void *)instance, "SMIO"); + if (instance->io_thread == NULL) { + pr_err("%s: failed to create SMIO thread", __func__); + + goto err_close_services; + } + set_user_nice(instance->io_thread, -10); + wake_up_process(instance->io_thread); + + pr_debug("%s: success - instance 0x%x", __func__, + (unsigned int)instance); + return instance; + +err_close_services: + for (i = 0; i < instance->num_connections; i++) { + if (instance->vchi_handle[i] != NULL) + vchi_service_close(instance->vchi_handle[i]); + } + kfree(instance); +err_null: + pr_debug("%s: FAILED", __func__); + return NULL; +} + +int vc_vchi_sm_stop(struct sm_instance **handle) +{ + struct sm_instance *instance; + uint32_t i; + + if (handle == NULL) { + pr_err("%s: invalid pointer to handle %p", __func__, handle); + goto lock; + } + + if (*handle == NULL) { + pr_err("%s: invalid handle %p", __func__, *handle); + goto lock; + } + + instance = *handle; + + /* Close all VCHI service connections */ + for (i = 0; i < instance->num_connections; i++) { + int32_t success; + + vchi_service_use(instance->vchi_handle[i]); + + success = vchi_service_close(instance->vchi_handle[i]); + } + + kfree(instance); + + *handle = NULL; + return 0; + +lock: + return -EINVAL; +} + +int vc_vchi_sm_send_msg(struct sm_instance *handle, + enum vc_sm_msg_type msg_id, + void *msg, uint32_t msg_size, + void *result, uint32_t result_size, + uint32_t *cur_trans_id, uint8_t wait_reply) +{ + int status = 0; + struct sm_instance *instance = handle; + struct sm_cmd_rsp_blk *cmd_blk; + + if (handle == NULL) { + pr_err("%s: invalid handle", __func__); + return -EINVAL; + } + if (msg == NULL) { + pr_err("%s: invalid msg pointer", __func__); + return -EINVAL; + } + + cmd_blk = + vc_vchi_cmd_create(instance, msg_id, msg, msg_size, wait_reply); + if (cmd_blk == NULL) { + pr_err("[%s]: failed to allocate global tracking resource", + __func__); + return -ENOMEM; + } + + if (cur_trans_id != NULL) + *cur_trans_id = cmd_blk->id; + + mutex_lock(&instance->lock); + list_add_tail(&cmd_blk->head, &instance->cmd_list); + mutex_unlock(&instance->lock); + up(&instance->io_sema); + + if (!wait_reply) + /* We're done */ + return 0; + + /* Wait for the response */ + if (down_interruptible(&cmd_blk->sema)) { + mutex_lock(&instance->lock); + if (!cmd_blk->sent) { + list_del(&cmd_blk->head); + mutex_unlock(&instance->lock); + vc_vchi_cmd_delete(instance, cmd_blk); + return -ENXIO; + } + mutex_unlock(&instance->lock); + + mutex_lock(&instance->lock); + list_move(&cmd_blk->head, &instance->dead_list); + mutex_unlock(&instance->lock); + up(&instance->io_sema); + return -EINTR; /* We're done */ + } + + if (result && result_size) { + memcpy(result, cmd_blk->msg, result_size); + } else { + struct vc_sm_result_t *res = + (struct vc_sm_result_t *) cmd_blk->msg; + status = (res->success == 0) ? 0 : -ENXIO; + } + + mutex_lock(&instance->lock); + list_del(&cmd_blk->head); + mutex_unlock(&instance->lock); + vc_vchi_cmd_delete(instance, cmd_blk); + return status; +} + +int vc_vchi_sm_alloc(struct sm_instance *handle, struct vc_sm_alloc_t *msg, + struct vc_sm_alloc_result_t *result, + uint32_t *cur_trans_id) +{ + return vc_vchi_sm_send_msg(handle, VC_SM_MSG_TYPE_ALLOC, + msg, sizeof(*msg), result, sizeof(*result), + cur_trans_id, 1); +} + +int vc_vchi_sm_free(struct sm_instance *handle, + struct vc_sm_free_t *msg, uint32_t *cur_trans_id) +{ + return vc_vchi_sm_send_msg(handle, VC_SM_MSG_TYPE_FREE, + msg, sizeof(*msg), 0, 0, cur_trans_id, 0); +} + +int vc_vchi_sm_lock(struct sm_instance *handle, + struct vc_sm_lock_unlock_t *msg, + struct vc_sm_lock_result_t *result, + uint32_t *cur_trans_id) +{ + return vc_vchi_sm_send_msg(handle, VC_SM_MSG_TYPE_LOCK, + msg, sizeof(*msg), result, sizeof(*result), + cur_trans_id, 1); +} + +int vc_vchi_sm_unlock(struct sm_instance *handle, + struct vc_sm_lock_unlock_t *msg, + uint32_t *cur_trans_id, uint8_t wait_reply) +{ + return vc_vchi_sm_send_msg(handle, wait_reply ? + VC_SM_MSG_TYPE_UNLOCK : + VC_SM_MSG_TYPE_UNLOCK_NOANS, msg, + sizeof(*msg), 0, 0, cur_trans_id, + wait_reply); +} + +int vc_vchi_sm_resize(struct sm_instance *handle, struct vc_sm_resize_t *msg, + uint32_t *cur_trans_id) +{ + return vc_vchi_sm_send_msg(handle, VC_SM_MSG_TYPE_RESIZE, + msg, sizeof(*msg), 0, 0, cur_trans_id, 1); +} + +int vc_vchi_sm_walk_alloc(struct sm_instance *handle) +{ + return vc_vchi_sm_send_msg(handle, VC_SM_MSG_TYPE_WALK_ALLOC, + 0, 0, 0, 0, 0, 0); +} + +int vc_vchi_sm_clean_up(struct sm_instance *handle, + struct vc_sm_action_clean_t *msg) +{ + return vc_vchi_sm_send_msg(handle, VC_SM_MSG_TYPE_ACTION_CLEAN, + msg, sizeof(*msg), 0, 0, 0, 0); +} + +int vc_vchi_sm_import(struct sm_instance *handle, struct vc_sm_import *msg, + struct vc_sm_import_result *result, + uint32_t *cur_trans_id) +{ + return vc_vchi_sm_send_msg(handle, VC_SM_MSG_TYPE_IMPORT, + msg, sizeof(*msg), result, sizeof(*result), + cur_trans_id, 1); +} diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/broadcom/vc_sm/vc_vchi_sm.h linux-vendor/drivers/char/broadcom/vc_sm/vc_vchi_sm.h --- linux-4.18.16/drivers/char/broadcom/vc_sm/vc_vchi_sm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/char/broadcom/vc_sm/vc_vchi_sm.h 2018-10-29 19:31:20.943763043 +0100 @@ -0,0 +1,102 @@ +/* + **************************************************************************** + * Copyright 2011 Broadcom Corporation. All rights reserved. + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available at + * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + **************************************************************************** + */ + +#ifndef __VC_VCHI_SM_H__INCLUDED__ +#define __VC_VCHI_SM_H__INCLUDED__ + +#include "interface/vchi/vchi.h" + +#include "vc_sm_defs.h" + +/* + * Forward declare. + */ +struct sm_instance; + +/* + * Initialize the shared memory service, opens up vchi connection to talk to it. + */ +struct sm_instance *vc_vchi_sm_init(VCHI_INSTANCE_T vchi_instance, + VCHI_CONNECTION_T **vchi_connections, + uint32_t num_connections); + +/* + * Terminates the shared memory service. + */ +int vc_vchi_sm_stop(struct sm_instance **handle); + +/* + * Ask the shared memory service to allocate some memory on videocre and + * return the result of this allocation (which upon success will be a pointer + * to some memory in videocore space). + */ +int vc_vchi_sm_alloc(struct sm_instance *handle, struct vc_sm_alloc_t *alloc, + struct vc_sm_alloc_result_t *alloc_result, + uint32_t *trans_id); + +/* + * Ask the shared memory service to free up some memory that was previously + * allocated by the vc_vchi_sm_alloc function call. + */ +int vc_vchi_sm_free(struct sm_instance *handle, + struct vc_sm_free_t *free, uint32_t *trans_id); + +/* + * Ask the shared memory service to lock up some memory that was previously + * allocated by the vc_vchi_sm_alloc function call. + */ +int vc_vchi_sm_lock(struct sm_instance *handle, + struct vc_sm_lock_unlock_t *lock_unlock, + struct vc_sm_lock_result_t *lock_result, + uint32_t *trans_id); + +/* + * Ask the shared memory service to unlock some memory that was previously + * allocated by the vc_vchi_sm_alloc function call. + */ +int vc_vchi_sm_unlock(struct sm_instance *handle, + struct vc_sm_lock_unlock_t *lock_unlock, + uint32_t *trans_id, uint8_t wait_reply); + +/* + * Ask the shared memory service to resize some memory that was previously + * allocated by the vc_vchi_sm_alloc function call. + */ +int vc_vchi_sm_resize(struct sm_instance *handle, + struct vc_sm_resize_t *resize, uint32_t *trans_id); + +/* + * Walk the allocated resources on the videocore side, the allocation will + * show up in the log. This is purely for debug/information and takes no + * specific actions. + */ +int vc_vchi_sm_walk_alloc(struct sm_instance *handle); + +/* + * Clean up following a previously interrupted action which left the system + * in a bad state of some sort. + */ +int vc_vchi_sm_clean_up(struct sm_instance *handle, + struct vc_sm_action_clean_t *action_clean); + +/* + * Import a contiguous block of memory and wrap it in a GPU MEM_HANDLE_T. + */ +int vc_vchi_sm_import(struct sm_instance *handle, struct vc_sm_import *msg, + struct vc_sm_import_result *result, + uint32_t *cur_trans_id); + +#endif /* __VC_VCHI_SM_H__INCLUDED__ */ diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/broadcom/vc_sm/vmcs_sm.c linux-vendor/drivers/char/broadcom/vc_sm/vmcs_sm.c --- linux-4.18.16/drivers/char/broadcom/vc_sm/vmcs_sm.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/char/broadcom/vc_sm/vmcs_sm.c 2018-10-29 19:31:20.943763043 +0100 @@ -0,0 +1,3543 @@ +/* + **************************************************************************** + * Copyright 2011-2012 Broadcom Corporation. All rights reserved. + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available at + * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + **************************************************************************** + */ + +/* ---- Include Files ----------------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vchiq_connected.h" +#include "vc_vchi_sm.h" + +#include +#include "vc_sm_knl.h" + +/* ---- Private Constants and Types --------------------------------------- */ + +#define DEVICE_NAME "vcsm" +#define DRIVER_NAME "bcm2835-vcsm" +#define DEVICE_MINOR 0 + +#define VC_SM_DIR_ROOT_NAME "vc-smem" +#define VC_SM_DIR_ALLOC_NAME "alloc" +#define VC_SM_STATE "state" +#define VC_SM_STATS "statistics" +#define VC_SM_RESOURCES "resources" +#define VC_SM_DEBUG "debug" +#define VC_SM_WRITE_BUF_SIZE 128 + +/* Statistics tracked per resource and globally. */ +enum sm_stats_t { + /* Attempt. */ + ALLOC, + FREE, + LOCK, + UNLOCK, + MAP, + FLUSH, + INVALID, + IMPORT, + + END_ATTEMPT, + + /* Failure. */ + ALLOC_FAIL, + FREE_FAIL, + LOCK_FAIL, + UNLOCK_FAIL, + MAP_FAIL, + FLUSH_FAIL, + INVALID_FAIL, + IMPORT_FAIL, + + END_ALL, + +}; + +static const char *const sm_stats_human_read[] = { + "Alloc", + "Free", + "Lock", + "Unlock", + "Map", + "Cache Flush", + "Cache Invalidate", + "Import", +}; + +typedef int (*VC_SM_SHOW) (struct seq_file *s, void *v); +struct sm_pde_t { + VC_SM_SHOW show; /* Debug fs function hookup. */ + struct dentry *dir_entry; /* Debug fs directory entry. */ + void *priv_data; /* Private data */ + +}; + +/* Single resource allocation tracked for all devices. */ +struct sm_mmap { + struct list_head map_list; /* Linked list of maps. */ + + struct sm_resource_t *resource; /* Pointer to the resource. */ + + pid_t res_pid; /* PID owning that resource. */ + unsigned int res_vc_hdl; /* Resource handle (videocore). */ + unsigned int res_usr_hdl; /* Resource handle (user). */ + + unsigned long res_addr; /* Mapped virtual address. */ + struct vm_area_struct *vma; /* VM area for this mapping. */ + unsigned int ref_count; /* Reference count to this vma. */ + + /* Used to link maps associated with a resource. */ + struct list_head resource_map_list; +}; + +/* Single resource allocation tracked for each opened device. */ +struct sm_resource_t { + struct list_head resource_list; /* List of resources. */ + struct list_head global_resource_list; /* Global list of resources. */ + + pid_t pid; /* PID owning that resource. */ + uint32_t res_guid; /* Unique identifier. */ + uint32_t lock_count; /* Lock count for this resource. */ + uint32_t ref_count; /* Ref count for this resource. */ + + uint32_t res_handle; /* Resource allocation handle. */ + void *res_base_mem; /* Resource base memory address. */ + uint32_t res_size; /* Resource size allocated. */ + enum vmcs_sm_cache_e res_cached; /* Resource cache type. */ + struct sm_resource_t *res_shared; /* Shared resource */ + + enum sm_stats_t res_stats[END_ALL]; /* Resource statistics. */ + + uint8_t map_count; /* Counter of mappings for this resource. */ + struct list_head map_list; /* Maps associated with a resource. */ + + /* DMABUF related fields */ + struct dma_buf *dma_buf; + struct dma_buf_attachment *attach; + struct sg_table *sgt; + dma_addr_t dma_addr; + + struct sm_priv_data_t *private; + bool map; /* whether to map pages up front */ +}; + +/* Private file data associated with each opened device. */ +struct sm_priv_data_t { + struct list_head resource_list; /* List of resources. */ + + pid_t pid; /* PID of creator. */ + + struct dentry *dir_pid; /* Debug fs entries root. */ + struct sm_pde_t dir_stats; /* Debug fs entries statistics sub-tree. */ + struct sm_pde_t dir_res; /* Debug fs resource sub-tree. */ + + int restart_sys; /* Tracks restart on interrupt. */ + enum vc_sm_msg_type int_action; /* Interrupted action. */ + uint32_t int_trans_id; /* Interrupted transaction. */ + +}; + +/* Global state information. */ +struct sm_state_t { + struct platform_device *pdev; + struct sm_instance *sm_handle; /* Handle for videocore service. */ + struct dentry *dir_root; /* Debug fs entries root. */ + struct dentry *dir_alloc; /* Debug fs entries allocations. */ + struct sm_pde_t dir_stats; /* Debug fs entries statistics sub-tree. */ + struct sm_pde_t dir_state; /* Debug fs entries state sub-tree. */ + struct dentry *debug; /* Debug fs entries debug. */ + + struct mutex map_lock; /* Global map lock. */ + struct list_head map_list; /* List of maps. */ + struct list_head resource_list; /* List of resources. */ + + enum sm_stats_t deceased[END_ALL]; /* Natural termination stats. */ + enum sm_stats_t terminated[END_ALL]; /* Forced termination stats. */ + uint32_t res_deceased_cnt; /* Natural termination counter. */ + uint32_t res_terminated_cnt; /* Forced termination counter. */ + + struct cdev sm_cdev; /* Device. */ + dev_t sm_devid; /* Device identifier. */ + struct class *sm_class; /* Class. */ + struct device *sm_dev; /* Device. */ + + struct sm_priv_data_t *data_knl; /* Kernel internal data tracking. */ + + struct mutex lock; /* Global lock. */ + uint32_t guid; /* GUID (next) tracker. */ + +}; + +/* ---- Private Variables ----------------------------------------------- */ + +static struct sm_state_t *sm_state; +static int sm_inited; + +#if 0 +static const char *const sm_cache_map_vector[] = { + "(null)", + "host", + "videocore", + "host+videocore", +}; +#endif + +/* ---- Private Function Prototypes -------------------------------------- */ + +/* ---- Private Functions ------------------------------------------------ */ + +static inline unsigned int vcaddr_to_pfn(unsigned long vc_addr) +{ + unsigned long pfn = vc_addr & 0x3FFFFFFF; + + pfn += mm_vc_mem_phys_addr; + pfn >>= PAGE_SHIFT; + return pfn; +} + +/* + * Carries over to the state statistics the statistics once owned by a deceased + * resource. + */ +static void vc_sm_resource_deceased(struct sm_resource_t *p_res, int terminated) +{ + if (sm_state != NULL) { + if (p_res != NULL) { + int ix; + + if (terminated) + sm_state->res_terminated_cnt++; + else + sm_state->res_deceased_cnt++; + + for (ix = 0; ix < END_ALL; ix++) { + if (terminated) + sm_state->terminated[ix] += + p_res->res_stats[ix]; + else + sm_state->deceased[ix] += + p_res->res_stats[ix]; + } + } + } +} + +/* + * Fetch a videocore handle corresponding to a mapping of the pid+address + * returns 0 (ie NULL) if no such handle exists in the global map. + */ +static unsigned int vmcs_sm_vc_handle_from_pid_and_address(unsigned int pid, + unsigned int addr) +{ + struct sm_mmap *map = NULL; + unsigned int handle = 0; + + if (!sm_state || addr == 0) + goto out; + + mutex_lock(&(sm_state->map_lock)); + + /* Lookup the resource. */ + if (!list_empty(&sm_state->map_list)) { + list_for_each_entry(map, &sm_state->map_list, map_list) { + if (map->res_pid != pid) + continue; + if (addr < map->res_addr || + addr >= (map->res_addr + map->resource->res_size)) + continue; + + pr_debug("[%s]: global map %p (pid %u, addr %lx) -> vc-hdl %x (usr-hdl %x)\n", + __func__, map, map->res_pid, map->res_addr, + map->res_vc_hdl, map->res_usr_hdl); + + handle = map->res_vc_hdl; + break; + } + } + + mutex_unlock(&(sm_state->map_lock)); + +out: + /* + * Use a debug log here as it may be a valid situation that we query + * for something that is not mapped, we do not want a kernel log each + * time around. + * + * There are other error log that would pop up accordingly if someone + * subsequently tries to use something invalid after being told not to + * use it... + */ + if (handle == 0) { + pr_debug("[%s]: not a valid map (pid %u, addr %x)\n", + __func__, pid, addr); + } + + return handle; +} + +/* + * Fetch a user handle corresponding to a mapping of the pid+address + * returns 0 (ie NULL) if no such handle exists in the global map. + */ +static unsigned int vmcs_sm_usr_handle_from_pid_and_address(unsigned int pid, + unsigned int addr) +{ + struct sm_mmap *map = NULL; + unsigned int handle = 0; + + if (!sm_state || addr == 0) + goto out; + + mutex_lock(&(sm_state->map_lock)); + + /* Lookup the resource. */ + if (!list_empty(&sm_state->map_list)) { + list_for_each_entry(map, &sm_state->map_list, map_list) { + if (map->res_pid != pid) + continue; + if (addr < map->res_addr || + addr >= (map->res_addr + map->resource->res_size)) + continue; + + pr_debug("[%s]: global map %p (pid %u, addr %lx) -> usr-hdl %x (vc-hdl %x)\n", + __func__, map, map->res_pid, map->res_addr, + map->res_usr_hdl, map->res_vc_hdl); + + handle = map->res_usr_hdl; + break; + } + } + + mutex_unlock(&(sm_state->map_lock)); + +out: + /* + * Use a debug log here as it may be a valid situation that we query + * for something that is not mapped yet. + * + * There are other error log that would pop up accordingly if someone + * subsequently tries to use something invalid after being told not to + * use it... + */ + if (handle == 0) + pr_debug("[%s]: not a valid map (pid %u, addr %x)\n", + __func__, pid, addr); + + return handle; +} + +#if defined(DO_NOT_USE) +/* + * Fetch an address corresponding to a mapping of the pid+handle + * returns 0 (ie NULL) if no such address exists in the global map. + */ +static unsigned int vmcs_sm_usr_address_from_pid_and_vc_handle(unsigned int pid, + unsigned int hdl) +{ + struct sm_mmap *map = NULL; + unsigned int addr = 0; + + if (sm_state == NULL || hdl == 0) + goto out; + + mutex_lock(&(sm_state->map_lock)); + + /* Lookup the resource. */ + if (!list_empty(&sm_state->map_list)) { + list_for_each_entry(map, &sm_state->map_list, map_list) { + if (map->res_pid != pid || map->res_vc_hdl != hdl) + continue; + + pr_debug("[%s]: global map %p (pid %u, vc-hdl %x, usr-hdl %x) -> addr %lx\n", + __func__, map, map->res_pid, map->res_vc_hdl, + map->res_usr_hdl, map->res_addr); + + addr = map->res_addr; + break; + } + } + + mutex_unlock(&(sm_state->map_lock)); + +out: + /* + * Use a debug log here as it may be a valid situation that we query + * for something that is not mapped, we do not want a kernel log each + * time around. + * + * There are other error log that would pop up accordingly if someone + * subsequently tries to use something invalid after being told not to + * use it... + */ + if (addr == 0) + pr_debug("[%s]: not a valid map (pid %u, hdl %x)\n", + __func__, pid, hdl); + + return addr; +} +#endif + +/* + * Fetch an address corresponding to a mapping of the pid+handle + * returns 0 (ie NULL) if no such address exists in the global map. + */ +static unsigned int vmcs_sm_usr_address_from_pid_and_usr_handle(unsigned int + pid, + unsigned int + hdl) +{ + struct sm_mmap *map = NULL; + unsigned int addr = 0; + + if (sm_state == NULL || hdl == 0) + goto out; + + mutex_lock(&(sm_state->map_lock)); + + /* Lookup the resource. */ + if (!list_empty(&sm_state->map_list)) { + list_for_each_entry(map, &sm_state->map_list, map_list) { + if (map->res_pid != pid || map->res_usr_hdl != hdl) + continue; + + pr_debug("[%s]: global map %p (pid %u, vc-hdl %x, usr-hdl %x) -> addr %lx\n", + __func__, map, map->res_pid, map->res_vc_hdl, + map->res_usr_hdl, map->res_addr); + + addr = map->res_addr; + break; + } + } + + mutex_unlock(&(sm_state->map_lock)); + +out: + /* + * Use a debug log here as it may be a valid situation that we query + * for something that is not mapped, we do not want a kernel log each + * time around. + * + * There are other error log that would pop up accordingly if someone + * subsequently tries to use something invalid after being told not to + * use it... + */ + if (addr == 0) + pr_debug("[%s]: not a valid map (pid %u, hdl %x)\n", __func__, + pid, hdl); + + return addr; +} + +/* Adds a resource mapping to the global data list. */ +static void vmcs_sm_add_map(struct sm_state_t *state, + struct sm_resource_t *resource, struct sm_mmap *map) +{ + mutex_lock(&(state->map_lock)); + + /* Add to the global list of mappings */ + list_add(&map->map_list, &state->map_list); + + /* Add to the list of mappings for this resource */ + list_add(&map->resource_map_list, &resource->map_list); + resource->map_count++; + + mutex_unlock(&(state->map_lock)); + + pr_debug("[%s]: added map %p (pid %u, vc-hdl %x, usr-hdl %x, addr %lx)\n", + __func__, map, map->res_pid, map->res_vc_hdl, + map->res_usr_hdl, map->res_addr); +} + +/* Removes a resource mapping from the global data list. */ +static void vmcs_sm_remove_map(struct sm_state_t *state, + struct sm_resource_t *resource, + struct sm_mmap *map) +{ + mutex_lock(&(state->map_lock)); + + /* Remove from the global list of mappings */ + list_del(&map->map_list); + + /* Remove from the list of mapping for this resource */ + list_del(&map->resource_map_list); + if (resource->map_count > 0) + resource->map_count--; + + mutex_unlock(&(state->map_lock)); + + pr_debug("[%s]: removed map %p (pid %d, vc-hdl %x, usr-hdl %x, addr %lx)\n", + __func__, map, map->res_pid, map->res_vc_hdl, map->res_usr_hdl, + map->res_addr); + + kfree(map); +} + +/* Read callback for the global state proc entry. */ +static int vc_sm_global_state_show(struct seq_file *s, void *v) +{ + struct sm_mmap *map = NULL; + struct sm_resource_t *resource = NULL; + int map_count = 0; + int resource_count = 0; + + if (sm_state == NULL) + return 0; + + seq_printf(s, "\nVC-ServiceHandle 0x%x\n", + (unsigned int)sm_state->sm_handle); + + /* Log all applicable mapping(s). */ + + mutex_lock(&(sm_state->map_lock)); + seq_puts(s, "\nResources\n"); + if (!list_empty(&sm_state->resource_list)) { + list_for_each_entry(resource, &sm_state->resource_list, + global_resource_list) { + resource_count++; + + seq_printf(s, "\nResource %p\n", + resource); + seq_printf(s, " PID %u\n", + resource->pid); + seq_printf(s, " RES_GUID 0x%x\n", + resource->res_guid); + seq_printf(s, " LOCK_COUNT %u\n", + resource->lock_count); + seq_printf(s, " REF_COUNT %u\n", + resource->ref_count); + seq_printf(s, " res_handle 0x%X\n", + resource->res_handle); + seq_printf(s, " res_base_mem %p\n", + resource->res_base_mem); + seq_printf(s, " SIZE %d\n", + resource->res_size); + seq_printf(s, " DMABUF %p\n", + resource->dma_buf); + seq_printf(s, " ATTACH %p\n", + resource->attach); + seq_printf(s, " SGT %p\n", + resource->sgt); + seq_printf(s, " DMA_ADDR %pad\n", + &resource->dma_addr); + } + } + seq_printf(s, "\n\nTotal resource count: %d\n\n", resource_count); + + seq_puts(s, "\nMappings\n"); + if (!list_empty(&sm_state->map_list)) { + list_for_each_entry(map, &sm_state->map_list, map_list) { + map_count++; + + seq_printf(s, "\nMapping 0x%x\n", + (unsigned int)map); + seq_printf(s, " TGID %u\n", + map->res_pid); + seq_printf(s, " VC-HDL 0x%x\n", + map->res_vc_hdl); + seq_printf(s, " USR-HDL 0x%x\n", + map->res_usr_hdl); + seq_printf(s, " USR-ADDR 0x%lx\n", + map->res_addr); + seq_printf(s, " SIZE %d\n", + map->resource->res_size); + } + } + + mutex_unlock(&(sm_state->map_lock)); + seq_printf(s, "\n\nTotal map count: %d\n\n", map_count); + + return 0; +} + +static int vc_sm_global_statistics_show(struct seq_file *s, void *v) +{ + int ix; + + /* Global state tracked statistics. */ + if (sm_state != NULL) { + seq_puts(s, "\nDeceased Resources Statistics\n"); + + seq_printf(s, "\nNatural Cause (%u occurences)\n", + sm_state->res_deceased_cnt); + for (ix = 0; ix < END_ATTEMPT; ix++) { + if (sm_state->deceased[ix] > 0) { + seq_printf(s, " %u\t%s\n", + sm_state->deceased[ix], + sm_stats_human_read[ix]); + } + } + seq_puts(s, "\n"); + for (ix = 0; ix < END_ATTEMPT; ix++) { + if (sm_state->deceased[ix + END_ATTEMPT] > 0) { + seq_printf(s, " %u\tFAILED %s\n", + sm_state->deceased[ix + END_ATTEMPT], + sm_stats_human_read[ix]); + } + } + + seq_printf(s, "\nForcefull (%u occurences)\n", + sm_state->res_terminated_cnt); + for (ix = 0; ix < END_ATTEMPT; ix++) { + if (sm_state->terminated[ix] > 0) { + seq_printf(s, " %u\t%s\n", + sm_state->terminated[ix], + sm_stats_human_read[ix]); + } + } + seq_puts(s, "\n"); + for (ix = 0; ix < END_ATTEMPT; ix++) { + if (sm_state->terminated[ix + END_ATTEMPT] > 0) { + seq_printf(s, " %u\tFAILED %s\n", + sm_state->terminated[ix + + END_ATTEMPT], + sm_stats_human_read[ix]); + } + } + } + + return 0; +} + +#if 0 +/* Read callback for the statistics proc entry. */ +static int vc_sm_statistics_show(struct seq_file *s, void *v) +{ + int ix; + struct sm_priv_data_t *file_data; + struct sm_resource_t *resource; + int res_count = 0; + struct sm_pde_t *p_pde; + + p_pde = (struct sm_pde_t *)(s->private); + file_data = (struct sm_priv_data_t *)(p_pde->priv_data); + + if (file_data == NULL) + return 0; + + /* Per process statistics. */ + + seq_printf(s, "\nStatistics for TGID %d\n", file_data->pid); + + mutex_lock(&(sm_state->map_lock)); + + if (!list_empty(&file_data->resource_list)) { + list_for_each_entry(resource, &file_data->resource_list, + resource_list) { + res_count++; + + seq_printf(s, "\nGUID: 0x%x\n\n", + resource->res_guid); + for (ix = 0; ix < END_ATTEMPT; ix++) { + if (resource->res_stats[ix] > 0) { + seq_printf(s, + " %u\t%s\n", + resource->res_stats[ix], + sm_stats_human_read[ix]); + } + } + seq_puts(s, "\n"); + for (ix = 0; ix < END_ATTEMPT; ix++) { + if (resource->res_stats[ix + END_ATTEMPT] > 0) { + seq_printf(s, + " %u\tFAILED %s\n", + resource->res_stats[ + ix + END_ATTEMPT], + sm_stats_human_read[ix]); + } + } + } + } + + mutex_unlock(&(sm_state->map_lock)); + + seq_printf(s, "\nResources Count %d\n", res_count); + + return 0; +} +#endif + +#if 0 +/* Read callback for the allocation proc entry. */ +static int vc_sm_alloc_show(struct seq_file *s, void *v) +{ + struct sm_priv_data_t *file_data; + struct sm_resource_t *resource; + int alloc_count = 0; + struct sm_pde_t *p_pde; + + p_pde = (struct sm_pde_t *)(s->private); + file_data = (struct sm_priv_data_t *)(p_pde->priv_data); + + if (!file_data) + return 0; + + /* Per process statistics. */ + seq_printf(s, "\nAllocation for TGID %d\n", file_data->pid); + + mutex_lock(&(sm_state->map_lock)); + + if (!list_empty(&file_data->resource_list)) { + list_for_each_entry(resource, &file_data->resource_list, + resource_list) { + alloc_count++; + + seq_printf(s, "\nGUID: 0x%x\n", + resource->res_guid); + seq_printf(s, "Lock Count: %u\n", + resource->lock_count); + seq_printf(s, "Mapped: %s\n", + (resource->map_count ? "yes" : "no")); + seq_printf(s, "VC-handle: 0x%x\n", + resource->res_handle); + seq_printf(s, "VC-address: 0x%p\n", + resource->res_base_mem); + seq_printf(s, "VC-size (bytes): %u\n", + resource->res_size); + seq_printf(s, "Cache: %s\n", + sm_cache_map_vector[resource->res_cached]); + } + } + + mutex_unlock(&(sm_state->map_lock)); + + seq_printf(s, "\n\nTotal allocation count: %d\n\n", alloc_count); + + return 0; +} +#endif + +static int vc_sm_seq_file_show(struct seq_file *s, void *v) +{ + struct sm_pde_t *sm_pde; + + sm_pde = (struct sm_pde_t *)(s->private); + + if (sm_pde && sm_pde->show) + sm_pde->show(s, v); + + return 0; +} + +static int vc_sm_single_open(struct inode *inode, struct file *file) +{ + return single_open(file, vc_sm_seq_file_show, inode->i_private); +} + +static const struct file_operations vc_sm_debug_fs_fops = { + .open = vc_sm_single_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* + * Adds a resource to the private data list which tracks all the allocated + * data. + */ +static void vmcs_sm_add_resource(struct sm_priv_data_t *privdata, + struct sm_resource_t *resource) +{ + mutex_lock(&(sm_state->map_lock)); + list_add(&resource->resource_list, &privdata->resource_list); + list_add(&resource->global_resource_list, &sm_state->resource_list); + mutex_unlock(&(sm_state->map_lock)); + + pr_debug("[%s]: added resource %p (base addr %p, hdl %x, size %u, cache %u)\n", + __func__, resource, resource->res_base_mem, + resource->res_handle, resource->res_size, resource->res_cached); +} + +/* + * Locates a resource and acquire a reference on it. + * The resource won't be deleted while there is a reference on it. + */ +static struct sm_resource_t *vmcs_sm_acquire_resource(struct sm_priv_data_t + *private, + unsigned int res_guid) +{ + struct sm_resource_t *resource, *ret = NULL; + + mutex_lock(&(sm_state->map_lock)); + + list_for_each_entry(resource, &private->resource_list, resource_list) { + if (resource->res_guid != res_guid) + continue; + + pr_debug("[%s]: located resource %p (guid: %x, base addr %p, hdl %x, size %u, cache %u)\n", + __func__, resource, resource->res_guid, + resource->res_base_mem, resource->res_handle, + resource->res_size, resource->res_cached); + resource->ref_count++; + ret = resource; + break; + } + + mutex_unlock(&(sm_state->map_lock)); + + return ret; +} + +/* + * Locates a resource and acquire a reference on it. + * The resource won't be deleted while there is a reference on it. + */ +static struct sm_resource_t *vmcs_sm_acquire_first_resource( + struct sm_priv_data_t *private) +{ + struct sm_resource_t *resource, *ret = NULL; + + mutex_lock(&(sm_state->map_lock)); + + list_for_each_entry(resource, &private->resource_list, resource_list) { + pr_debug("[%s]: located resource %p (guid: %x, base addr %p, hdl %x, size %u, cache %u)\n", + __func__, resource, resource->res_guid, + resource->res_base_mem, resource->res_handle, + resource->res_size, resource->res_cached); + resource->ref_count++; + ret = resource; + break; + } + + mutex_unlock(&(sm_state->map_lock)); + + return ret; +} + +/* + * Locates a resource and acquire a reference on it. + * The resource won't be deleted while there is a reference on it. + */ +static struct sm_resource_t *vmcs_sm_acquire_global_resource(unsigned int + res_guid) +{ + struct sm_resource_t *resource, *ret = NULL; + + mutex_lock(&(sm_state->map_lock)); + + list_for_each_entry(resource, &sm_state->resource_list, + global_resource_list) { + if (resource->res_guid != res_guid) + continue; + + pr_debug("[%s]: located resource %p (guid: %x, base addr %p, hdl %x, size %u, cache %u)\n", + __func__, resource, resource->res_guid, + resource->res_base_mem, resource->res_handle, + resource->res_size, resource->res_cached); + resource->ref_count++; + ret = resource; + break; + } + + mutex_unlock(&(sm_state->map_lock)); + + return ret; +} + +/* + * Release a previously acquired resource. + * The resource will be deleted when its refcount reaches 0. + */ +static void vmcs_sm_release_resource(struct sm_resource_t *resource, int force) +{ + struct sm_priv_data_t *private = resource->private; + struct sm_mmap *map, *map_tmp; + struct sm_resource_t *res_tmp; + int ret; + + mutex_lock(&(sm_state->map_lock)); + + if (--resource->ref_count) { + if (force) + pr_err("[%s]: resource %p in use\n", __func__, resource); + + mutex_unlock(&(sm_state->map_lock)); + return; + } + + /* Time to free the resource. Start by removing it from the list */ + list_del(&resource->resource_list); + list_del(&resource->global_resource_list); + + /* + * Walk the global resource list, find out if the resource is used + * somewhere else. In which case we don't want to delete it. + */ + list_for_each_entry(res_tmp, &sm_state->resource_list, + global_resource_list) { + if (res_tmp->res_handle == resource->res_handle) { + resource->res_handle = 0; + break; + } + } + + mutex_unlock(&(sm_state->map_lock)); + + pr_debug("[%s]: freeing data - guid %x, hdl %x, base address %p\n", + __func__, resource->res_guid, resource->res_handle, + resource->res_base_mem); + resource->res_stats[FREE]++; + + /* Make sure the resource we're removing is unmapped first */ + if (resource->map_count && !list_empty(&resource->map_list)) { + down_write(¤t->mm->mmap_sem); + list_for_each_entry_safe(map, map_tmp, &resource->map_list, + resource_map_list) { + ret = + do_munmap(current->mm, map->res_addr, + resource->res_size, NULL); + if (ret) { + pr_err("[%s]: could not unmap resource %p\n", + __func__, resource); + } + } + up_write(¤t->mm->mmap_sem); + } + + /* Free up the videocore allocated resource. */ + if (resource->res_handle) { + struct vc_sm_free_t free = { + resource->res_handle, (uint32_t)resource->res_base_mem + }; + int status = vc_vchi_sm_free(sm_state->sm_handle, &free, + &private->int_trans_id); + if (status != 0 && status != -EINTR) { + pr_err("[%s]: failed to free memory on videocore (status: %u, trans_id: %u)\n", + __func__, status, private->int_trans_id); + resource->res_stats[FREE_FAIL]++; + ret = -EPERM; + } + } + + if (resource->sgt) + dma_buf_unmap_attachment(resource->attach, resource->sgt, + DMA_BIDIRECTIONAL); + if (resource->attach) + dma_buf_detach(resource->dma_buf, resource->attach); + if (resource->dma_buf) + dma_buf_put(resource->dma_buf); + + /* Free up the shared resource. */ + if (resource->res_shared) + vmcs_sm_release_resource(resource->res_shared, 0); + + /* Free up the local resource tracking this allocation. */ + vc_sm_resource_deceased(resource, force); + kfree(resource); +} + +/* + * Dump the map table for the driver. If process is -1, dumps the whole table, + * if process is a valid pid (non -1) dump only the entries associated with the + * pid of interest. + */ +static void vmcs_sm_host_walk_map_per_pid(int pid) +{ + struct sm_mmap *map = NULL; + + /* Make sure the device was started properly. */ + if (sm_state == NULL) { + pr_err("[%s]: invalid device\n", __func__); + return; + } + + mutex_lock(&(sm_state->map_lock)); + + /* Log all applicable mapping(s). */ + if (!list_empty(&sm_state->map_list)) { + list_for_each_entry(map, &sm_state->map_list, map_list) { + if (pid == -1 || map->res_pid == pid) { + pr_info("[%s]: tgid: %u - vc-hdl: %x, usr-hdl: %x, usr-addr: %lx\n", + __func__, map->res_pid, map->res_vc_hdl, + map->res_usr_hdl, map->res_addr); + } + } + } + + mutex_unlock(&(sm_state->map_lock)); +} + +/* + * Dump the allocation table from host side point of view. This only dumps the + * data allocated for this process/device referenced by the file_data. + */ +static void vmcs_sm_host_walk_alloc(struct sm_priv_data_t *file_data) +{ + struct sm_resource_t *resource = NULL; + + /* Make sure the device was started properly. */ + if ((sm_state == NULL) || (file_data == NULL)) { + pr_err("[%s]: invalid device\n", __func__); + return; + } + + mutex_lock(&(sm_state->map_lock)); + + if (!list_empty(&file_data->resource_list)) { + list_for_each_entry(resource, &file_data->resource_list, + resource_list) { + pr_info("[%s]: guid: %x - hdl: %x, vc-mem: %p, size: %u, cache: %u\n", + __func__, resource->res_guid, resource->res_handle, + resource->res_base_mem, resource->res_size, + resource->res_cached); + } + } + + mutex_unlock(&(sm_state->map_lock)); +} + +/* Create support for private data tracking. */ +static struct sm_priv_data_t *vc_sm_create_priv_data(pid_t id) +{ + char alloc_name[32]; + struct sm_priv_data_t *file_data = NULL; + + /* Allocate private structure. */ + file_data = kzalloc(sizeof(*file_data), GFP_KERNEL); + + if (!file_data) { + pr_err("[%s]: cannot allocate file data\n", __func__); + goto out; + } + + snprintf(alloc_name, sizeof(alloc_name), "%d", id); + + INIT_LIST_HEAD(&file_data->resource_list); + file_data->pid = id; + file_data->dir_pid = debugfs_create_dir(alloc_name, + sm_state->dir_alloc); +#if 0 + /* TODO: fix this to support querying statistics per pid */ + + if (IS_ERR_OR_NULL(file_data->dir_pid)) { + file_data->dir_pid = NULL; + } else { + struct dentry *dir_entry; + + dir_entry = debugfs_create_file(VC_SM_RESOURCES, 0444, + file_data->dir_pid, file_data, + vc_sm_debug_fs_fops); + + file_data->dir_res.dir_entry = dir_entry; + file_data->dir_res.priv_data = file_data; + file_data->dir_res.show = &vc_sm_alloc_show; + + dir_entry = debugfs_create_file(VC_SM_STATS, 0444, + file_data->dir_pid, file_data, + vc_sm_debug_fs_fops); + + file_data->dir_res.dir_entry = dir_entry; + file_data->dir_res.priv_data = file_data; + file_data->dir_res.show = &vc_sm_statistics_show; + } + pr_debug("[%s]: private data allocated %p\n", __func__, file_data); + +#endif +out: + return file_data; +} + +/* + * Open the device. Creates a private state to help track all allocation + * associated with this device. + */ +static int vc_sm_open(struct inode *inode, struct file *file) +{ + int ret = 0; + + /* Make sure the device was started properly. */ + if (!sm_state) { + pr_err("[%s]: invalid device\n", __func__); + ret = -EPERM; + goto out; + } + + file->private_data = vc_sm_create_priv_data(current->tgid); + if (file->private_data == NULL) { + pr_err("[%s]: failed to create data tracker\n", __func__); + + ret = -ENOMEM; + goto out; + } + +out: + return ret; +} + +/* + * Close the device. Free up all resources still associated with this device + * at the time. + */ +static int vc_sm_release(struct inode *inode, struct file *file) +{ + struct sm_priv_data_t *file_data = + (struct sm_priv_data_t *)file->private_data; + struct sm_resource_t *resource; + int ret = 0; + + /* Make sure the device was started properly. */ + if (sm_state == NULL || file_data == NULL) { + pr_err("[%s]: invalid device\n", __func__); + ret = -EPERM; + goto out; + } + + pr_debug("[%s]: using private data %p\n", __func__, file_data); + + if (file_data->restart_sys == -EINTR) { + struct vc_sm_action_clean_t action_clean; + + pr_debug("[%s]: releasing following EINTR on %u (trans_id: %u) (likely due to signal)...\n", + __func__, file_data->int_action, + file_data->int_trans_id); + + action_clean.res_action = file_data->int_action; + action_clean.action_trans_id = file_data->int_trans_id; + + vc_vchi_sm_clean_up(sm_state->sm_handle, &action_clean); + } + + while ((resource = vmcs_sm_acquire_first_resource(file_data)) != NULL) { + vmcs_sm_release_resource(resource, 0); + vmcs_sm_release_resource(resource, 1); + } + + /* Remove the corresponding proc entry. */ + debugfs_remove_recursive(file_data->dir_pid); + + /* Terminate the private data. */ + kfree(file_data); + +out: + return ret; +} + +static void vcsm_vma_open(struct vm_area_struct *vma) +{ + struct sm_mmap *map = (struct sm_mmap *)vma->vm_private_data; + + pr_debug("[%s]: virt %lx-%lx, pid %i, pfn %i\n", + __func__, vma->vm_start, vma->vm_end, (int)current->tgid, + (int)vma->vm_pgoff); + + map->ref_count++; +} + +static void vcsm_vma_close(struct vm_area_struct *vma) +{ + struct sm_mmap *map = (struct sm_mmap *)vma->vm_private_data; + + pr_debug("[%s]: virt %lx-%lx, pid %i, pfn %i\n", + __func__, vma->vm_start, vma->vm_end, (int)current->tgid, + (int)vma->vm_pgoff); + + map->ref_count--; + + /* Remove from the map table. */ + if (map->ref_count == 0) + vmcs_sm_remove_map(sm_state, map->resource, map); +} + +static int vcsm_vma_fault(struct vm_fault *vmf) +{ + struct sm_mmap *map = (struct sm_mmap *)vmf->vma->vm_private_data; + struct sm_resource_t *resource = map->resource; + pgoff_t page_offset; + unsigned long pfn; + int ret = 0; + + /* Lock the resource if necessary. */ + if (!resource->lock_count) { + struct vc_sm_lock_unlock_t lock_unlock; + struct vc_sm_lock_result_t lock_result; + int status; + + lock_unlock.res_handle = resource->res_handle; + lock_unlock.res_mem = (uint32_t)resource->res_base_mem; + + pr_debug("[%s]: attempt to lock data - hdl %x, base address %p\n", + __func__, lock_unlock.res_handle, + (void *)lock_unlock.res_mem); + + /* Lock the videocore allocated resource. */ + status = vc_vchi_sm_lock(sm_state->sm_handle, + &lock_unlock, &lock_result, 0); + if (status || !lock_result.res_mem) { + pr_err("[%s]: failed to lock memory on videocore (status: %u)\n", + __func__, status); + resource->res_stats[LOCK_FAIL]++; + return VM_FAULT_SIGBUS; + } + + pfn = vcaddr_to_pfn((unsigned long)resource->res_base_mem); + outer_inv_range(__pfn_to_phys(pfn), + __pfn_to_phys(pfn) + resource->res_size); + + resource->res_stats[LOCK]++; + resource->lock_count++; + + /* Keep track of the new base memory. */ + if (lock_result.res_mem && + lock_result.res_old_mem && + (lock_result.res_mem != lock_result.res_old_mem)) { + resource->res_base_mem = (void *)lock_result.res_mem; + } + } + + /* We don't use vmf->pgoff since that has the fake offset */ + page_offset = ((unsigned long)vmf->address - vmf->vma->vm_start); + pfn = (uint32_t)resource->res_base_mem & 0x3FFFFFFF; + pfn += mm_vc_mem_phys_addr; + pfn += page_offset; + pfn >>= PAGE_SHIFT; + + /* Finally, remap it */ + ret = vm_insert_pfn(vmf->vma, (unsigned long)vmf->address, pfn); + + switch (ret) { + case 0: + case -ERESTARTSYS: + /* + * EBUSY is ok: this just means that another thread + * already did the job. + */ + case -EBUSY: + return VM_FAULT_NOPAGE; + case -ENOMEM: + case -EAGAIN: + pr_err("[%s]: failed to map page pfn:%lx virt:%lx ret:%d\n", __func__, + pfn, (unsigned long)vmf->address, ret); + return VM_FAULT_OOM; + default: + pr_err("[%s]: failed to map page pfn:%lx virt:%lx ret:%d\n", __func__, + pfn, (unsigned long)vmf->address, ret); + return VM_FAULT_SIGBUS; + } +} + +static const struct vm_operations_struct vcsm_vm_ops = { + .open = vcsm_vma_open, + .close = vcsm_vma_close, + .fault = vcsm_vma_fault, +}; + +/* Converts VCSM_CACHE_OP_* to an operating function. */ +static void (*cache_op_to_func(const unsigned cache_op)) + (const void*, const void*) +{ + switch (cache_op) { + case VCSM_CACHE_OP_NOP: + return NULL; + + case VCSM_CACHE_OP_INV: + return dmac_inv_range; + + case VCSM_CACHE_OP_CLEAN: + return dmac_clean_range; + + case VCSM_CACHE_OP_FLUSH: + return dmac_flush_range; + + default: + pr_err("[%s]: Invalid cache_op: 0x%08x\n", __func__, cache_op); + return NULL; + } +} + +/* + * Clean/invalid/flush cache of which buffer is already pinned (i.e. accessed). + */ +static int clean_invalid_contiguous_mem_2d(const void __user *addr, + const size_t block_count, const size_t block_size, const size_t stride, + const unsigned cache_op) +{ + size_t i; + void (*op_fn)(const void*, const void*); + + if (!block_size) { + pr_err("[%s]: size cannot be 0\n", __func__); + return -EINVAL; + } + + op_fn = cache_op_to_func(cache_op); + if (op_fn == NULL) + return -EINVAL; + + for (i = 0; i < block_count; i ++, addr += stride) + op_fn(addr, addr + block_size); + + return 0; +} + +/* Clean/invalid/flush cache of which buffer may be non-pinned. */ +/* The caller must lock current->mm->mmap_sem for read. */ +static int clean_invalid_mem_walk(unsigned long addr, const size_t size, + const unsigned cache_op) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + unsigned long pgd_next, pud_next, pmd_next; + const unsigned long end = ALIGN(addr + size, PAGE_SIZE); + void (*op_fn)(const void*, const void*); + + addr &= PAGE_MASK; + + if (addr >= end) + return 0; + + op_fn = cache_op_to_func(cache_op); + if (op_fn == NULL) + return -EINVAL; + + /* Walk PGD */ + pgd = pgd_offset(current->mm, addr); + do { + pgd_next = pgd_addr_end(addr, end); + + if (pgd_none(*pgd) || pgd_bad(*pgd)) + continue; + + /* Walk PUD */ + pud = pud_offset(pgd, addr); + do { + pud_next = pud_addr_end(addr, pgd_next); + if (pud_none(*pud) || pud_bad(*pud)) + continue; + + /* Walk PMD */ + pmd = pmd_offset(pud, addr); + do { + pmd_next = pmd_addr_end(addr, pud_next); + if (pmd_none(*pmd) || pmd_bad(*pmd)) + continue; + + /* Walk PTE */ + pte = pte_offset_map(pmd, addr); + do { + if (pte_none(*pte) || !pte_present(*pte)) + continue; + + op_fn((const void __user*) addr, + (const void __user*) (addr + PAGE_SIZE)); + } while (pte++, addr += PAGE_SIZE, addr != pmd_next); + pte_unmap(pte); + + } while (pmd++, addr = pmd_next, addr != pud_next); + + } while (pud++, addr = pud_next, addr != pgd_next); + + } while (pgd++, addr = pgd_next, addr != end); + + return 0; +} + +/* Clean/invalid/flush cache of buffer in resource */ +static int clean_invalid_resource_walk(const void __user *addr, + const size_t size, const unsigned cache_op, const int usr_hdl, + struct sm_resource_t *resource) +{ + int err; + enum sm_stats_t stat_attempt, stat_failure; + void __user *res_addr; + + if (resource == NULL) { + pr_err("[%s]: resource is NULL\n", __func__); + return -EINVAL; + } + if (resource->res_cached != VMCS_SM_CACHE_HOST && + resource->res_cached != VMCS_SM_CACHE_BOTH) + return 0; + + switch (cache_op) { + case VCSM_CACHE_OP_NOP: + return 0; + case VCSM_CACHE_OP_INV: + stat_attempt = INVALID; + stat_failure = INVALID_FAIL; + break; + case VCSM_CACHE_OP_CLEAN: + /* Like the original VMCS_SM_CMD_CLEAN_INVALID ioctl handler does. */ + stat_attempt = FLUSH; + stat_failure = FLUSH_FAIL; + break; + case VCSM_CACHE_OP_FLUSH: + stat_attempt = FLUSH; + stat_failure = FLUSH_FAIL; + break; + default: + pr_err("[%s]: Invalid cache_op: 0x%08x\n", __func__, cache_op); + return -EINVAL; + } + resource->res_stats[stat_attempt]++; + + if (size > resource->res_size) { + pr_err("[%s]: size (0x%08zu) is larger than res_size (0x%08zu)\n", + __func__, size, resource->res_size); + return -EFAULT; + } + res_addr = (void __user*) vmcs_sm_usr_address_from_pid_and_usr_handle( + current->tgid, usr_hdl); + if (res_addr == NULL) { + pr_err("[%s]: Failed to get user address " + "from pid (%d) and user handle (%d)\n", __func__, current->tgid, + resource->res_handle); + return -EINVAL; + } + if (!(res_addr <= addr && addr + size <= res_addr + resource->res_size)) { + pr_err("[%s]: Addr (0x%p-0x%p) out of range (0x%p-0x%p)\n", + __func__, addr, addr + size, res_addr, + res_addr + resource->res_size); + return -EFAULT; + } + + down_read(¤t->mm->mmap_sem); + err = clean_invalid_mem_walk((unsigned long) addr, size, cache_op); + up_read(¤t->mm->mmap_sem); + + if (err) + resource->res_stats[stat_failure]++; + + return err; +} + +/* Map an allocated data into something that the user space. */ +static int vc_sm_mmap(struct file *file, struct vm_area_struct *vma) +{ + int ret = 0; + struct sm_priv_data_t *file_data = + (struct sm_priv_data_t *)file->private_data; + struct sm_resource_t *resource = NULL; + struct sm_mmap *map = NULL; + + /* Make sure the device was started properly. */ + if ((sm_state == NULL) || (file_data == NULL)) { + pr_err("[%s]: invalid device\n", __func__); + return -EPERM; + } + + pr_debug("[%s]: private data %p, guid %x\n", __func__, file_data, + ((unsigned int)vma->vm_pgoff << PAGE_SHIFT)); + + /* + * We lookup to make sure that the data we are being asked to mmap is + * something that we allocated. + * + * We use the offset information as the key to tell us which resource + * we are mapping. + */ + resource = vmcs_sm_acquire_resource(file_data, + ((unsigned int)vma->vm_pgoff << + PAGE_SHIFT)); + if (resource == NULL) { + pr_err("[%s]: failed to locate resource for guid %x\n", __func__, + ((unsigned int)vma->vm_pgoff << PAGE_SHIFT)); + return -ENOMEM; + } + + pr_debug("[%s]: guid %x, tgid %u, %u, %u\n", + __func__, resource->res_guid, current->tgid, resource->pid, + file_data->pid); + + /* Check permissions. */ + if (resource->pid && (resource->pid != current->tgid)) { + pr_err("[%s]: current tgid %u != %u owner\n", + __func__, current->tgid, resource->pid); + ret = -EPERM; + goto error; + } + + /* Verify that what we are asked to mmap is proper. */ + if (resource->res_size != (unsigned int)(vma->vm_end - vma->vm_start)) { + pr_err("[%s]: size inconsistency (resource: %u - mmap: %u)\n", + __func__, + resource->res_size, + (unsigned int)(vma->vm_end - vma->vm_start)); + + ret = -EINVAL; + goto error; + } + + /* + * Keep track of the tuple in the global resource list such that one + * can do a mapping lookup for address/memory handle. + */ + map = kzalloc(sizeof(*map), GFP_KERNEL); + if (map == NULL) { + pr_err("[%s]: failed to allocate global tracking resource\n", + __func__); + ret = -ENOMEM; + goto error; + } + + map->res_pid = current->tgid; + map->res_vc_hdl = resource->res_handle; + map->res_usr_hdl = resource->res_guid; + map->res_addr = (unsigned long)vma->vm_start; + map->resource = resource; + map->vma = vma; + vmcs_sm_add_map(sm_state, resource, map); + + /* + * We are not actually mapping the pages, we just provide a fault + * handler to allow pages to be mapped when accessed + */ + vma->vm_flags |= + VM_IO | VM_PFNMAP | VM_DONTCOPY | VM_DONTEXPAND; + vma->vm_ops = &vcsm_vm_ops; + vma->vm_private_data = map; + + /* vm_pgoff is the first PFN of the mapped memory */ + vma->vm_pgoff = (unsigned long)resource->res_base_mem & 0x3FFFFFFF; + vma->vm_pgoff += mm_vc_mem_phys_addr; + vma->vm_pgoff >>= PAGE_SHIFT; + + if ((resource->res_cached == VMCS_SM_CACHE_NONE) || + (resource->res_cached == VMCS_SM_CACHE_VC)) { + /* Allocated non host cached memory, honour it. */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + } + + pr_debug("[%s]: resource %p (guid %x) - cnt %u, base address %p, handle %x, size %u (%u), cache %u\n", + __func__, + resource, resource->res_guid, resource->lock_count, + resource->res_base_mem, resource->res_handle, + resource->res_size, (unsigned int)(vma->vm_end - vma->vm_start), + resource->res_cached); + + pr_debug("[%s]: resource %p (base address %p, handle %x) - map-count %d, usr-addr %x\n", + __func__, resource, resource->res_base_mem, + resource->res_handle, resource->map_count, + (unsigned int)vma->vm_start); + + vcsm_vma_open(vma); + resource->res_stats[MAP]++; + vmcs_sm_release_resource(resource, 0); + + if (resource->map) { + /* We don't use vmf->pgoff since that has the fake offset */ + unsigned long addr; + + for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) { + /* Finally, remap it */ + unsigned long pfn = (unsigned long)resource->res_base_mem & 0x3FFFFFFF; + + pfn += mm_vc_mem_phys_addr; + pfn += addr - vma->vm_start; + pfn >>= PAGE_SHIFT; + ret = vm_insert_pfn(vma, addr, pfn); + } + } + + return 0; + +error: + resource->res_stats[MAP_FAIL]++; + vmcs_sm_release_resource(resource, 0); + return ret; +} + +/* Allocate a shared memory handle and block. */ +int vc_sm_ioctl_alloc(struct sm_priv_data_t *private, + struct vmcs_sm_ioctl_alloc *ioparam) +{ + int ret = 0; + int status; + struct sm_resource_t *resource; + struct vc_sm_alloc_t alloc = { 0 }; + struct vc_sm_alloc_result_t result = { 0 }; + enum vmcs_sm_cache_e cached = ioparam->cached; + bool map = false; + + /* flag to requst buffer is mapped up front, rather than lazily */ + if (cached & 0x80) { + map = true; + cached &= ~0x80; + } + + /* Setup our allocation parameters */ + alloc.type = ((cached == VMCS_SM_CACHE_VC) + || (cached == + VMCS_SM_CACHE_BOTH)) ? VC_SM_ALLOC_CACHED : + VC_SM_ALLOC_NON_CACHED; + alloc.base_unit = ioparam->size; + alloc.num_unit = ioparam->num; + alloc.allocator = current->tgid; + /* Align to kernel page size */ + alloc.alignement = 4096; + /* Align the size to the kernel page size */ + alloc.base_unit = + (alloc.base_unit + alloc.alignement - 1) & ~(alloc.alignement - 1); + if (*ioparam->name) { + memcpy(alloc.name, ioparam->name, sizeof(alloc.name) - 1); + } else { + memcpy(alloc.name, VMCS_SM_RESOURCE_NAME_DEFAULT, + sizeof(VMCS_SM_RESOURCE_NAME_DEFAULT)); + } + + pr_debug("[%s]: attempt to allocate \"%s\" data - type %u, base %u (%u), num %u, alignement %u\n", + __func__, alloc.name, alloc.type, ioparam->size, + alloc.base_unit, alloc.num_unit, alloc.alignement); + + /* Allocate local resource to track this allocation. */ + resource = kzalloc(sizeof(*resource), GFP_KERNEL); + if (!resource) { + ret = -ENOMEM; + goto error; + } + INIT_LIST_HEAD(&resource->map_list); + resource->ref_count++; + resource->pid = current->tgid; + + /* Allocate the videocore resource. */ + status = vc_vchi_sm_alloc(sm_state->sm_handle, &alloc, &result, + &private->int_trans_id); + if (status == -EINTR) { + pr_debug("[%s]: requesting allocate memory action restart (trans_id: %u)\n", + __func__, private->int_trans_id); + ret = -ERESTARTSYS; + private->restart_sys = -EINTR; + private->int_action = VC_SM_MSG_TYPE_ALLOC; + goto error; + } else if (status != 0 || !result.res_mem) { + pr_err("[%s]: failed to allocate memory on videocore (status: %u, trans_id: %u)\n", + __func__, status, private->int_trans_id); + ret = -ENOMEM; + resource->res_stats[ALLOC_FAIL]++; + goto error; + } + + /* Keep track of the resource we created. */ + resource->private = private; + resource->res_handle = result.res_handle; + resource->res_base_mem = (void *)result.res_mem; + resource->res_size = alloc.base_unit * alloc.num_unit; + resource->res_cached = cached; + resource->map = map; + + /* + * Kernel/user GUID. This global identifier is used for mmap'ing the + * allocated region from user space, it is passed as the mmap'ing + * offset, we use it to 'hide' the videocore handle/address. + */ + mutex_lock(&sm_state->lock); + resource->res_guid = ++sm_state->guid; + mutex_unlock(&sm_state->lock); + resource->res_guid <<= PAGE_SHIFT; + + vmcs_sm_add_resource(private, resource); + + pr_debug("[%s]: allocated data - guid %x, hdl %x, base address %p, size %d, cache %d\n", + __func__, resource->res_guid, resource->res_handle, + resource->res_base_mem, resource->res_size, + resource->res_cached); + + /* We're done */ + resource->res_stats[ALLOC]++; + ioparam->handle = resource->res_guid; + return 0; + +error: + pr_err("[%s]: failed to allocate \"%s\" data (%i) - type %u, base %u (%u), num %u, alignment %u\n", + __func__, alloc.name, ret, alloc.type, ioparam->size, + alloc.base_unit, alloc.num_unit, alloc.alignement); + if (resource != NULL) { + vc_sm_resource_deceased(resource, 1); + kfree(resource); + } + return ret; +} + +/* Share an allocate memory handle and block.*/ +int vc_sm_ioctl_alloc_share(struct sm_priv_data_t *private, + struct vmcs_sm_ioctl_alloc_share *ioparam) +{ + struct sm_resource_t *resource, *shared_resource; + int ret = 0; + + pr_debug("[%s]: attempt to share resource %u\n", __func__, + ioparam->handle); + + shared_resource = vmcs_sm_acquire_global_resource(ioparam->handle); + if (shared_resource == NULL) { + ret = -ENOMEM; + goto error; + } + + /* Allocate local resource to track this allocation. */ + resource = kzalloc(sizeof(*resource), GFP_KERNEL); + if (resource == NULL) { + pr_err("[%s]: failed to allocate local tracking resource\n", + __func__); + ret = -ENOMEM; + goto error; + } + INIT_LIST_HEAD(&resource->map_list); + resource->ref_count++; + resource->pid = current->tgid; + + /* Keep track of the resource we created. */ + resource->private = private; + resource->res_handle = shared_resource->res_handle; + resource->res_base_mem = shared_resource->res_base_mem; + resource->res_size = shared_resource->res_size; + resource->res_cached = shared_resource->res_cached; + resource->res_shared = shared_resource; + + mutex_lock(&sm_state->lock); + resource->res_guid = ++sm_state->guid; + mutex_unlock(&sm_state->lock); + resource->res_guid <<= PAGE_SHIFT; + + vmcs_sm_add_resource(private, resource); + + pr_debug("[%s]: allocated data - guid %x, hdl %x, base address %p, size %d, cache %d\n", + __func__, resource->res_guid, resource->res_handle, + resource->res_base_mem, resource->res_size, + resource->res_cached); + + /* We're done */ + resource->res_stats[ALLOC]++; + ioparam->handle = resource->res_guid; + ioparam->size = resource->res_size; + return 0; + +error: + pr_err("[%s]: failed to share %u\n", __func__, ioparam->handle); + if (shared_resource != NULL) + vmcs_sm_release_resource(shared_resource, 0); + + return ret; +} + +/* Free a previously allocated shared memory handle and block.*/ +static int vc_sm_ioctl_free(struct sm_priv_data_t *private, + struct vmcs_sm_ioctl_free *ioparam) +{ + struct sm_resource_t *resource = + vmcs_sm_acquire_resource(private, ioparam->handle); + + if (resource == NULL) { + pr_err("[%s]: resource for guid %u does not exist\n", __func__, + ioparam->handle); + return -EINVAL; + } + + /* Check permissions. */ + if (resource->pid && (resource->pid != current->tgid)) { + pr_err("[%s]: current tgid %u != %u owner\n", + __func__, current->tgid, resource->pid); + vmcs_sm_release_resource(resource, 0); + return -EPERM; + } + + vmcs_sm_release_resource(resource, 0); + vmcs_sm_release_resource(resource, 0); + return 0; +} + +/* Resize a previously allocated shared memory handle and block. */ +static int vc_sm_ioctl_resize(struct sm_priv_data_t *private, + struct vmcs_sm_ioctl_resize *ioparam) +{ + int ret = 0; + int status; + struct vc_sm_resize_t resize; + struct sm_resource_t *resource; + + /* Locate resource from GUID. */ + resource = vmcs_sm_acquire_resource(private, ioparam->handle); + if (!resource) { + pr_err("[%s]: failed resource - guid %x\n", + __func__, ioparam->handle); + ret = -EFAULT; + goto error; + } + + /* + * If the resource is locked, its reference count will be not NULL, + * in which case we will not be allowed to resize it anyways, so + * reject the attempt here. + */ + if (resource->lock_count != 0) { + pr_err("[%s]: cannot resize - guid %x, ref-cnt %d\n", + __func__, ioparam->handle, resource->lock_count); + ret = -EFAULT; + goto error; + } + + /* Check permissions. */ + if (resource->pid && (resource->pid != current->tgid)) { + pr_err("[%s]: current tgid %u != %u owner\n", __func__, + current->tgid, resource->pid); + ret = -EPERM; + goto error; + } + + if (resource->map_count != 0) { + pr_err("[%s]: cannot resize - guid %x, ref-cnt %d\n", + __func__, ioparam->handle, resource->map_count); + ret = -EFAULT; + goto error; + } + + resize.res_handle = resource->res_handle; + resize.res_mem = (uint32_t)resource->res_base_mem; + resize.res_new_size = ioparam->new_size; + + pr_debug("[%s]: attempt to resize data - guid %x, hdl %x, base address %p\n", + __func__, ioparam->handle, resize.res_handle, + (void *)resize.res_mem); + + /* Resize the videocore allocated resource. */ + status = vc_vchi_sm_resize(sm_state->sm_handle, &resize, + &private->int_trans_id); + if (status == -EINTR) { + pr_debug("[%s]: requesting resize memory action restart (trans_id: %u)\n", + __func__, private->int_trans_id); + ret = -ERESTARTSYS; + private->restart_sys = -EINTR; + private->int_action = VC_SM_MSG_TYPE_RESIZE; + goto error; + } else if (status) { + pr_err("[%s]: failed to resize memory on videocore (status: %u, trans_id: %u)\n", + __func__, status, private->int_trans_id); + ret = -EPERM; + goto error; + } + + pr_debug("[%s]: success to resize data - hdl %x, size %d -> %d\n", + __func__, resize.res_handle, resource->res_size, + resize.res_new_size); + + /* Successfully resized, save the information and inform the user. */ + ioparam->old_size = resource->res_size; + resource->res_size = resize.res_new_size; + +error: + if (resource) + vmcs_sm_release_resource(resource, 0); + + return ret; +} + +/* Lock a previously allocated shared memory handle and block. */ +static int vc_sm_ioctl_lock(struct sm_priv_data_t *private, + struct vmcs_sm_ioctl_lock_unlock *ioparam, + int change_cache, enum vmcs_sm_cache_e cache_type, + unsigned int vc_addr) +{ + int status; + struct vc_sm_lock_unlock_t lock; + struct vc_sm_lock_result_t result; + struct sm_resource_t *resource; + int ret = 0; + struct sm_mmap *map, *map_tmp; + unsigned long phys_addr; + + map = NULL; + + /* Locate resource from GUID. */ + resource = vmcs_sm_acquire_resource(private, ioparam->handle); + if (resource == NULL) { + ret = -EINVAL; + goto error; + } + + /* Check permissions. */ + if (resource->pid && (resource->pid != current->tgid)) { + pr_err("[%s]: current tgid %u != %u owner\n", __func__, + current->tgid, resource->pid); + ret = -EPERM; + goto error; + } + + lock.res_handle = resource->res_handle; + lock.res_mem = (uint32_t)resource->res_base_mem; + + /* Take the lock and get the address to be mapped. */ + if (vc_addr == 0) { + pr_debug("[%s]: attempt to lock data - guid %x, hdl %x, base address %p\n", + __func__, ioparam->handle, lock.res_handle, + (void *)lock.res_mem); + + /* Lock the videocore allocated resource. */ + status = vc_vchi_sm_lock(sm_state->sm_handle, &lock, &result, + &private->int_trans_id); + if (status == -EINTR) { + pr_debug("[%s]: requesting lock memory action restart (trans_id: %u)\n", + __func__, private->int_trans_id); + ret = -ERESTARTSYS; + private->restart_sys = -EINTR; + private->int_action = VC_SM_MSG_TYPE_LOCK; + goto error; + } else if (status || + (!status && !(void *)result.res_mem)) { + pr_err("[%s]: failed to lock memory on videocore (status: %u, trans_id: %u)\n", + __func__, status, private->int_trans_id); + ret = -EPERM; + resource->res_stats[LOCK_FAIL]++; + goto error; + } + + pr_debug("[%s]: succeed to lock data - hdl %x, base address %p (%p), ref-cnt %d\n", + __func__, lock.res_handle, (void *)result.res_mem, + (void *)lock.res_mem, resource->lock_count); + } + /* Lock assumed taken already, address to be mapped is known. */ + else + resource->res_base_mem = (void *)vc_addr; + + resource->res_stats[LOCK]++; + resource->lock_count++; + + /* Keep track of the new base memory allocation if it has changed. */ + if ((vc_addr == 0) && + ((void *)result.res_mem) && + ((void *)result.res_old_mem) && + (result.res_mem != result.res_old_mem)) { + resource->res_base_mem = (void *)result.res_mem; + + /* Kernel allocated resources. */ + if (resource->pid == 0) { + if (!list_empty(&resource->map_list)) { + list_for_each_entry_safe(map, map_tmp, + &resource->map_list, + resource_map_list) { + if (map->res_addr) { + iounmap((void *)map->res_addr); + map->res_addr = 0; + + vmcs_sm_remove_map(sm_state, + map->resource, + map); + break; + } + } + } + } + } + + if (change_cache) + resource->res_cached = cache_type; + + if (resource->map_count) { + ioparam->addr = + vmcs_sm_usr_address_from_pid_and_usr_handle( + current->tgid, ioparam->handle); + + pr_debug("[%s] map_count %d private->pid %d current->tgid %d hnd %x addr %u\n", + __func__, resource->map_count, private->pid, + current->tgid, ioparam->handle, ioparam->addr); + } else { + /* Kernel allocated resources. */ + if (resource->pid == 0) { + pr_debug("[%s]: attempt mapping kernel resource - guid %x, hdl %x\n", + __func__, ioparam->handle, lock.res_handle); + + ioparam->addr = 0; + + map = kzalloc(sizeof(*map), GFP_KERNEL); + if (map == NULL) { + pr_err("[%s]: failed allocating tracker\n", + __func__); + ret = -ENOMEM; + goto error; + } else { + phys_addr = (uint32_t)resource->res_base_mem & + 0x3FFFFFFF; + phys_addr += mm_vc_mem_phys_addr; + if (resource->res_cached + == VMCS_SM_CACHE_HOST) { + ioparam->addr = (unsigned long) + /* TODO - make cached work */ + ioremap_nocache(phys_addr, + resource->res_size); + + pr_debug("[%s]: mapping kernel - guid %x, hdl %x - cached mapping %u\n", + __func__, ioparam->handle, + lock.res_handle, ioparam->addr); + } else { + ioparam->addr = (unsigned long) + ioremap_nocache(phys_addr, + resource->res_size); + + pr_debug("[%s]: mapping kernel- guid %x, hdl %x - non cached mapping %u\n", + __func__, ioparam->handle, + lock.res_handle, ioparam->addr); + } + + map->res_pid = 0; + map->res_vc_hdl = resource->res_handle; + map->res_usr_hdl = resource->res_guid; + map->res_addr = ioparam->addr; + map->resource = resource; + map->vma = NULL; + + vmcs_sm_add_map(sm_state, resource, map); + } + } else + ioparam->addr = 0; + } + +error: + if (resource) + vmcs_sm_release_resource(resource, 0); + + return ret; +} + +/* Unlock a previously allocated shared memory handle and block.*/ +static int vc_sm_ioctl_unlock(struct sm_priv_data_t *private, + struct vmcs_sm_ioctl_lock_unlock *ioparam, + int flush, int wait_reply, int no_vc_unlock) +{ + int status; + struct vc_sm_lock_unlock_t unlock; + struct sm_mmap *map, *map_tmp; + struct sm_resource_t *resource; + int ret = 0; + + map = NULL; + + /* Locate resource from GUID. */ + resource = vmcs_sm_acquire_resource(private, ioparam->handle); + if (resource == NULL) { + ret = -EINVAL; + goto error; + } + + /* Check permissions. */ + if (resource->pid && (resource->pid != current->tgid)) { + pr_err("[%s]: current tgid %u != %u owner\n", + __func__, current->tgid, resource->pid); + ret = -EPERM; + goto error; + } + + unlock.res_handle = resource->res_handle; + unlock.res_mem = (uint32_t)resource->res_base_mem; + + pr_debug("[%s]: attempt to unlock data - guid %x, hdl %x, base address %p\n", + __func__, ioparam->handle, unlock.res_handle, + (void *)unlock.res_mem); + + /* User space allocated resources. */ + if (resource->pid) { + /* Flush if requested */ + if (resource->res_cached && flush) { + dma_addr_t phys_addr = 0; + + resource->res_stats[FLUSH]++; + + phys_addr = + (dma_addr_t)((uint32_t)resource->res_base_mem & + 0x3FFFFFFF); + phys_addr += (dma_addr_t)mm_vc_mem_phys_addr; + + /* L1 cache flush */ + down_read(¤t->mm->mmap_sem); + list_for_each_entry(map, &resource->map_list, + resource_map_list) { + if (map->vma) { + const unsigned long start = map->vma->vm_start; + const unsigned long end = map->vma->vm_end; + + ret = clean_invalid_mem_walk(start, end - start, + VCSM_CACHE_OP_FLUSH); + if (ret) + goto error; + } + } + up_read(¤t->mm->mmap_sem); + + /* L2 cache flush */ + outer_clean_range(phys_addr, + phys_addr + + (size_t) resource->res_size); + } + + /* We need to zap all the vmas associated with this resource */ + if (resource->lock_count == 1) { + down_read(¤t->mm->mmap_sem); + list_for_each_entry(map, &resource->map_list, + resource_map_list) { + if (map->vma) { + zap_vma_ptes(map->vma, + map->vma->vm_start, + map->vma->vm_end - + map->vma->vm_start); + } + } + up_read(¤t->mm->mmap_sem); + } + } + /* Kernel allocated resources. */ + else { + /* Global + Taken in this context */ + if (resource->ref_count == 2) { + if (!list_empty(&resource->map_list)) { + list_for_each_entry_safe(map, map_tmp, + &resource->map_list, + resource_map_list) { + if (map->res_addr) { + if (flush && + (resource->res_cached == + VMCS_SM_CACHE_HOST)) { + unsigned long + phys_addr; + phys_addr = (uint32_t) + resource->res_base_mem & 0x3FFFFFFF; + phys_addr += + mm_vc_mem_phys_addr; + + /* L1 cache flush */ + dmac_flush_range((const + void + *) + map->res_addr, (const void *) + (map->res_addr + resource->res_size)); + + /* L2 cache flush */ + outer_clean_range + (phys_addr, + phys_addr + + (size_t) + resource->res_size); + } + + iounmap((void *)map->res_addr); + map->res_addr = 0; + + vmcs_sm_remove_map(sm_state, + map->resource, + map); + break; + } + } + } + } + } + + if (resource->lock_count) { + /* Bypass the videocore unlock. */ + if (no_vc_unlock) + status = 0; + /* Unlock the videocore allocated resource. */ + else { + status = + vc_vchi_sm_unlock(sm_state->sm_handle, &unlock, + &private->int_trans_id, + wait_reply); + if (status == -EINTR) { + pr_debug("[%s]: requesting unlock memory action restart (trans_id: %u)\n", + __func__, private->int_trans_id); + + ret = -ERESTARTSYS; + resource->res_stats[UNLOCK]--; + private->restart_sys = -EINTR; + private->int_action = VC_SM_MSG_TYPE_UNLOCK; + goto error; + } else if (status != 0) { + pr_err("[%s]: failed to unlock vc mem (status: %u, trans_id: %u)\n", + __func__, status, private->int_trans_id); + + ret = -EPERM; + resource->res_stats[UNLOCK_FAIL]++; + goto error; + } + } + + resource->res_stats[UNLOCK]++; + resource->lock_count--; + } + + pr_debug("[%s]: success to unlock data - hdl %x, base address %p, ref-cnt %d\n", + __func__, unlock.res_handle, (void *)unlock.res_mem, + resource->lock_count); + +error: + if (resource) + vmcs_sm_release_resource(resource, 0); + + return ret; +} + +/* Import a contiguous block of memory to be shared with VC. */ +int vc_sm_ioctl_import_dmabuf(struct sm_priv_data_t *private, + struct vmcs_sm_ioctl_import_dmabuf *ioparam, + struct dma_buf *src_dma_buf) +{ + int ret = 0; + int status; + struct sm_resource_t *resource = NULL; + struct vc_sm_import import = { 0 }; + struct vc_sm_import_result result = { 0 }; + struct dma_buf *dma_buf; + struct dma_buf_attachment *attach = NULL; + struct sg_table *sgt = NULL; + + /* Setup our allocation parameters */ + if (src_dma_buf) { + get_dma_buf(src_dma_buf); + dma_buf = src_dma_buf; + } else { + dma_buf = dma_buf_get(ioparam->dmabuf_fd); + } + if (IS_ERR(dma_buf)) + return PTR_ERR(dma_buf); + + attach = dma_buf_attach(dma_buf, &sm_state->pdev->dev); + if (IS_ERR(attach)) { + ret = PTR_ERR(attach); + goto error; + } + + sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); + if (IS_ERR(sgt)) { + ret = PTR_ERR(sgt); + goto error; + } + + /* Verify that the address block is contiguous */ + if (sgt->nents != 1) { + ret = -ENOMEM; + goto error; + } + + import.type = ((ioparam->cached == VMCS_SM_CACHE_VC) || + (ioparam->cached == VMCS_SM_CACHE_BOTH)) ? + VC_SM_ALLOC_CACHED : VC_SM_ALLOC_NON_CACHED; + import.addr = (uint32_t)sg_dma_address(sgt->sgl); + import.size = sg_dma_len(sgt->sgl); + import.allocator = current->tgid; + + if (*ioparam->name) + memcpy(import.name, ioparam->name, sizeof(import.name) - 1); + else + memcpy(import.name, VMCS_SM_RESOURCE_NAME_DEFAULT, + sizeof(VMCS_SM_RESOURCE_NAME_DEFAULT)); + + pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %p, size %u\n", + __func__, import.name, import.type, + (void *)import.addr, import.size); + + /* Allocate local resource to track this allocation. */ + resource = kzalloc(sizeof(*resource), GFP_KERNEL); + if (!resource) { + ret = -ENOMEM; + goto error; + } + INIT_LIST_HEAD(&resource->map_list); + resource->ref_count++; + resource->pid = current->tgid; + + /* Allocate the videocore resource. */ + status = vc_vchi_sm_import(sm_state->sm_handle, &import, &result, + &private->int_trans_id); + if (status == -EINTR) { + pr_debug("[%s]: requesting import memory action restart (trans_id: %u)\n", + __func__, private->int_trans_id); + ret = -ERESTARTSYS; + private->restart_sys = -EINTR; + private->int_action = VC_SM_MSG_TYPE_IMPORT; + goto error; + } else if (status || !result.res_handle) { + pr_debug("[%s]: failed to import memory on videocore (status: %u, trans_id: %u)\n", + __func__, status, private->int_trans_id); + ret = -ENOMEM; + resource->res_stats[ALLOC_FAIL]++; + goto error; + } + + /* Keep track of the resource we created. */ + resource->private = private; + resource->res_handle = result.res_handle; + resource->res_size = import.size; + resource->res_cached = ioparam->cached; + + resource->dma_buf = dma_buf; + resource->attach = attach; + resource->sgt = sgt; + resource->dma_addr = sg_dma_address(sgt->sgl); + + /* + * Kernel/user GUID. This global identifier is used for mmap'ing the + * allocated region from user space, it is passed as the mmap'ing + * offset, we use it to 'hide' the videocore handle/address. + */ + mutex_lock(&sm_state->lock); + resource->res_guid = ++sm_state->guid; + mutex_unlock(&sm_state->lock); + resource->res_guid <<= PAGE_SHIFT; + + vmcs_sm_add_resource(private, resource); + + /* We're done */ + resource->res_stats[IMPORT]++; + ioparam->handle = resource->res_guid; + return 0; + +error: + resource->res_stats[IMPORT_FAIL]++; + if (resource) { + vc_sm_resource_deceased(resource, 1); + kfree(resource); + } + if (sgt) + dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); + if (attach) + dma_buf_detach(dma_buf, attach); + dma_buf_put(dma_buf); + return ret; +} + +/* Handle control from host. */ +static long vc_sm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + unsigned int cmdnr = _IOC_NR(cmd); + struct sm_priv_data_t *file_data = + (struct sm_priv_data_t *)file->private_data; + struct sm_resource_t *resource = NULL; + + /* Validate we can work with this device. */ + if ((sm_state == NULL) || (file_data == NULL)) { + pr_err("[%s]: invalid device\n", __func__); + ret = -EPERM; + goto out; + } + + pr_debug("[%s]: cmd %x tgid %u, owner %u\n", __func__, cmdnr, + current->tgid, file_data->pid); + + /* Action is a re-post of a previously interrupted action? */ + if (file_data->restart_sys == -EINTR) { + struct vc_sm_action_clean_t action_clean; + + pr_debug("[%s]: clean up of action %u (trans_id: %u) following EINTR\n", + __func__, file_data->int_action, + file_data->int_trans_id); + + action_clean.res_action = file_data->int_action; + action_clean.action_trans_id = file_data->int_trans_id; + + vc_vchi_sm_clean_up(sm_state->sm_handle, &action_clean); + + file_data->restart_sys = 0; + } + + /* Now process the command. */ + switch (cmdnr) { + /* New memory allocation. + */ + case VMCS_SM_CMD_ALLOC: + { + struct vmcs_sm_ioctl_alloc ioparam; + + /* Get the parameter data. */ + if (copy_from_user + (&ioparam, (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + ret = vc_sm_ioctl_alloc(file_data, &ioparam); + if (!ret && + (copy_to_user((void *)arg, + &ioparam, sizeof(ioparam)) != 0)) { + struct vmcs_sm_ioctl_free freeparam = { + ioparam.handle + }; + pr_err("[%s]: failed to copy-to-user for cmd %x\n", + __func__, cmdnr); + vc_sm_ioctl_free(file_data, &freeparam); + ret = -EFAULT; + } + + /* Done. */ + goto out; + } + break; + + /* Share existing memory allocation. */ + case VMCS_SM_CMD_ALLOC_SHARE: + { + struct vmcs_sm_ioctl_alloc_share ioparam; + + /* Get the parameter data. */ + if (copy_from_user + (&ioparam, (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + ret = vc_sm_ioctl_alloc_share(file_data, &ioparam); + + /* Copy result back to user. */ + if (!ret + && copy_to_user((void *)arg, &ioparam, + sizeof(ioparam)) != 0) { + struct vmcs_sm_ioctl_free freeparam = { + ioparam.handle + }; + pr_err("[%s]: failed to copy-to-user for cmd %x\n", + __func__, cmdnr); + vc_sm_ioctl_free(file_data, &freeparam); + ret = -EFAULT; + } + + /* Done. */ + goto out; + } + break; + + case VMCS_SM_CMD_IMPORT_DMABUF: + { + struct vmcs_sm_ioctl_import_dmabuf ioparam; + + /* Get the parameter data. */ + if (copy_from_user + (&ioparam, (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + ret = vc_sm_ioctl_import_dmabuf(file_data, &ioparam, + NULL); + if (!ret && + (copy_to_user((void *)arg, + &ioparam, sizeof(ioparam)) != 0)) { + struct vmcs_sm_ioctl_free freeparam = { + ioparam.handle + }; + pr_err("[%s]: failed to copy-to-user for cmd %x\n", + __func__, cmdnr); + vc_sm_ioctl_free(file_data, &freeparam); + ret = -EFAULT; + } + + /* Done. */ + goto out; + } + break; + + /* Lock (attempt to) *and* register a cache behavior change. */ + case VMCS_SM_CMD_LOCK_CACHE: + { + struct vmcs_sm_ioctl_lock_cache ioparam; + struct vmcs_sm_ioctl_lock_unlock lock; + + /* Get parameter data. */ + if (copy_from_user + (&ioparam, (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + lock.handle = ioparam.handle; + ret = + vc_sm_ioctl_lock(file_data, &lock, 1, + ioparam.cached, 0); + + /* Done. */ + goto out; + } + break; + + /* Lock (attempt to) existing memory allocation. */ + case VMCS_SM_CMD_LOCK: + { + struct vmcs_sm_ioctl_lock_unlock ioparam; + + /* Get parameter data. */ + if (copy_from_user + (&ioparam, (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + ret = vc_sm_ioctl_lock(file_data, &ioparam, 0, 0, 0); + + /* Copy result back to user. */ + if (copy_to_user((void *)arg, &ioparam, sizeof(ioparam)) + != 0) { + pr_err("[%s]: failed to copy-to-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + } + + /* Done. */ + goto out; + } + break; + + /* Unlock (attempt to) existing memory allocation. */ + case VMCS_SM_CMD_UNLOCK: + { + struct vmcs_sm_ioctl_lock_unlock ioparam; + + /* Get parameter data. */ + if (copy_from_user + (&ioparam, (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + ret = vc_sm_ioctl_unlock(file_data, &ioparam, 0, 1, 0); + + /* Done. */ + goto out; + } + break; + + /* Resize (attempt to) existing memory allocation. */ + case VMCS_SM_CMD_RESIZE: + { + struct vmcs_sm_ioctl_resize ioparam; + + /* Get parameter data. */ + if (copy_from_user + (&ioparam, (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + ret = vc_sm_ioctl_resize(file_data, &ioparam); + + /* Copy result back to user. */ + if (copy_to_user((void *)arg, &ioparam, sizeof(ioparam)) + != 0) { + pr_err("[%s]: failed to copy-to-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + } + goto out; + } + break; + + /* Terminate existing memory allocation. + */ + case VMCS_SM_CMD_FREE: + { + struct vmcs_sm_ioctl_free ioparam; + + /* Get parameter data. + */ + if (copy_from_user + (&ioparam, (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + ret = vc_sm_ioctl_free(file_data, &ioparam); + + /* Done. + */ + goto out; + } + break; + + /* Walk allocation on videocore, information shows up in the + ** videocore log. + */ + case VMCS_SM_CMD_VC_WALK_ALLOC: + { + pr_debug("[%s]: invoking walk alloc\n", __func__); + + if (vc_vchi_sm_walk_alloc(sm_state->sm_handle) != 0) + pr_err("[%s]: failed to walk-alloc on videocore\n", + __func__); + + /* Done. + */ + goto out; + } + break; + /* Walk mapping table on host, information shows up in the + ** kernel log. + */ + case VMCS_SM_CMD_HOST_WALK_MAP: + { + /* Use pid of -1 to tell to walk the whole map. */ + vmcs_sm_host_walk_map_per_pid(-1); + + /* Done. */ + goto out; + } + break; + + /* Walk mapping table per process on host. */ + case VMCS_SM_CMD_HOST_WALK_PID_ALLOC: + { + struct vmcs_sm_ioctl_walk ioparam; + + /* Get parameter data. */ + if (copy_from_user(&ioparam, + (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + vmcs_sm_host_walk_alloc(file_data); + + /* Done. */ + goto out; + } + break; + + /* Walk allocation per process on host. */ + case VMCS_SM_CMD_HOST_WALK_PID_MAP: + { + struct vmcs_sm_ioctl_walk ioparam; + + /* Get parameter data. */ + if (copy_from_user(&ioparam, + (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + vmcs_sm_host_walk_map_per_pid(ioparam.pid); + + /* Done. */ + goto out; + } + break; + + /* Gets the size of the memory associated with a user handle. */ + case VMCS_SM_CMD_SIZE_USR_HANDLE: + { + struct vmcs_sm_ioctl_size ioparam; + + /* Get parameter data. */ + if (copy_from_user(&ioparam, + (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + /* Locate resource from GUID. */ + resource = + vmcs_sm_acquire_resource(file_data, ioparam.handle); + if (resource != NULL) { + ioparam.size = resource->res_size; + vmcs_sm_release_resource(resource, 0); + } else { + ioparam.size = 0; + } + + if (copy_to_user((void *)arg, + &ioparam, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-to-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + } + + /* Done. */ + goto out; + } + break; + + /* Verify we are dealing with a valid resource. */ + case VMCS_SM_CMD_CHK_USR_HANDLE: + { + struct vmcs_sm_ioctl_chk ioparam; + + /* Get parameter data. */ + if (copy_from_user(&ioparam, + (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + + ret = -EFAULT; + goto out; + } + + /* Locate resource from GUID. */ + resource = + vmcs_sm_acquire_resource(file_data, ioparam.handle); + if (resource == NULL) + ret = -EINVAL; + /* + * If the resource is cacheable, return additional + * information that may be needed to flush the cache. + */ + else if ((resource->res_cached == VMCS_SM_CACHE_HOST) || + (resource->res_cached == VMCS_SM_CACHE_BOTH)) { + ioparam.addr = + vmcs_sm_usr_address_from_pid_and_usr_handle + (current->tgid, ioparam.handle); + ioparam.size = resource->res_size; + ioparam.cache = resource->res_cached; + } else { + ioparam.addr = 0; + ioparam.size = 0; + ioparam.cache = resource->res_cached; + } + + if (resource) + vmcs_sm_release_resource(resource, 0); + + if (copy_to_user((void *)arg, + &ioparam, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-to-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + } + + /* Done. */ + goto out; + } + break; + + /* + * Maps a user handle given the process and the virtual address. + */ + case VMCS_SM_CMD_MAPPED_USR_HANDLE: + { + struct vmcs_sm_ioctl_map ioparam; + + /* Get parameter data. */ + if (copy_from_user(&ioparam, + (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + + ret = -EFAULT; + goto out; + } + + ioparam.handle = + vmcs_sm_usr_handle_from_pid_and_address( + ioparam.pid, ioparam.addr); + + resource = + vmcs_sm_acquire_resource(file_data, ioparam.handle); + if ((resource != NULL) + && ((resource->res_cached == VMCS_SM_CACHE_HOST) + || (resource->res_cached == + VMCS_SM_CACHE_BOTH))) { + ioparam.size = resource->res_size; + } else { + ioparam.size = 0; + } + + if (resource) + vmcs_sm_release_resource(resource, 0); + + if (copy_to_user((void *)arg, + &ioparam, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-to-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + } + + /* Done. */ + goto out; + } + break; + + /* + * Maps a videocore handle given process and virtual address. + */ + case VMCS_SM_CMD_MAPPED_VC_HDL_FROM_ADDR: + { + struct vmcs_sm_ioctl_map ioparam; + + /* Get parameter data. */ + if (copy_from_user(&ioparam, + (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + ioparam.handle = vmcs_sm_vc_handle_from_pid_and_address( + ioparam.pid, ioparam.addr); + + if (copy_to_user((void *)arg, + &ioparam, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-to-user for cmd %x\n", + __func__, cmdnr); + + ret = -EFAULT; + } + + /* Done. */ + goto out; + } + break; + + /* Maps a videocore handle given process and user handle. */ + case VMCS_SM_CMD_MAPPED_VC_HDL_FROM_HDL: + { + struct vmcs_sm_ioctl_map ioparam; + + /* Get parameter data. */ + if (copy_from_user(&ioparam, + (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + /* Locate resource from GUID. */ + resource = + vmcs_sm_acquire_resource(file_data, ioparam.handle); + if (resource != NULL) { + ioparam.handle = resource->res_handle; + vmcs_sm_release_resource(resource, 0); + } else { + ioparam.handle = 0; + } + + if (copy_to_user((void *)arg, + &ioparam, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-to-user for cmd %x\n", + __func__, cmdnr); + + ret = -EFAULT; + } + + /* Done. */ + goto out; + } + break; + + /* + * Maps a videocore address given process and videocore handle. + */ + case VMCS_SM_CMD_MAPPED_VC_ADDR_FROM_HDL: + { + struct vmcs_sm_ioctl_map ioparam; + + /* Get parameter data. */ + if (copy_from_user(&ioparam, + (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + + ret = -EFAULT; + goto out; + } + + /* Locate resource from GUID. */ + resource = + vmcs_sm_acquire_resource(file_data, ioparam.handle); + if (resource != NULL) { + ioparam.addr = + (unsigned int)resource->res_base_mem; + vmcs_sm_release_resource(resource, 0); + } else { + ioparam.addr = 0; + } + + if (copy_to_user((void *)arg, + &ioparam, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-to-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + } + + /* Done. */ + goto out; + } + break; + + /* Maps a user address given process and vc handle. */ + case VMCS_SM_CMD_MAPPED_USR_ADDRESS: + { + struct vmcs_sm_ioctl_map ioparam; + + /* Get parameter data. */ + if (copy_from_user(&ioparam, + (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + /* + * Return the address information from the mapping, + * 0 (ie NULL) if it cannot locate the actual mapping. + */ + ioparam.addr = + vmcs_sm_usr_address_from_pid_and_usr_handle + (ioparam.pid, ioparam.handle); + + if (copy_to_user((void *)arg, + &ioparam, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-to-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + } + + /* Done. */ + goto out; + } + break; + + /* Flush the cache for a given mapping. */ + case VMCS_SM_CMD_FLUSH: + { + struct vmcs_sm_ioctl_cache ioparam; + + /* Get parameter data. */ + if (copy_from_user(&ioparam, + (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + /* Locate resource from GUID. */ + resource = + vmcs_sm_acquire_resource(file_data, ioparam.handle); + if (resource == NULL) { + ret = -EINVAL; + goto out; + } + + ret = clean_invalid_resource_walk((void __user*) ioparam.addr, + ioparam.size, VCSM_CACHE_OP_FLUSH, ioparam.handle, + resource); + vmcs_sm_release_resource(resource, 0); + if (ret) + goto out; + } + break; + + /* Invalidate the cache for a given mapping. */ + case VMCS_SM_CMD_INVALID: + { + struct vmcs_sm_ioctl_cache ioparam; + + /* Get parameter data. */ + if (copy_from_user(&ioparam, + (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + /* Locate resource from GUID. */ + resource = + vmcs_sm_acquire_resource(file_data, ioparam.handle); + if (resource == NULL) { + ret = -EINVAL; + goto out; + } + + ret = clean_invalid_resource_walk((void __user*) ioparam.addr, + ioparam.size, VCSM_CACHE_OP_INV, ioparam.handle, resource); + vmcs_sm_release_resource(resource, 0); + if (ret) + goto out; + } + break; + + /* Flush/Invalidate the cache for a given mapping. */ + case VMCS_SM_CMD_CLEAN_INVALID: + { + int i; + struct vmcs_sm_ioctl_clean_invalid ioparam; + + /* Get parameter data. */ + if (copy_from_user(&ioparam, + (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + for (i = 0; i < sizeof(ioparam.s) / sizeof(*ioparam.s); i++) { + if (ioparam.s[i].cmd == VCSM_CACHE_OP_NOP) + break; + + /* Locate resource from GUID. */ + resource = + vmcs_sm_acquire_resource(file_data, ioparam.s[i].handle); + if (resource == NULL) { + ret = -EINVAL; + goto out; + } + + ret = clean_invalid_resource_walk( + (void __user*) ioparam.s[i].addr, ioparam.s[i].size, + ioparam.s[i].cmd, ioparam.s[i].handle, resource); + vmcs_sm_release_resource(resource, 0); + if (ret) + goto out; + } + } + break; + /* + * Flush/Invalidate the cache for a given mapping. + * Blocks must be pinned (i.e. accessed) before this call. + */ + case VMCS_SM_CMD_CLEAN_INVALID2: + { + int i; + struct vmcs_sm_ioctl_clean_invalid2 ioparam; + struct vmcs_sm_ioctl_clean_invalid_block *block = NULL; + + /* Get parameter data. */ + if (copy_from_user(&ioparam, + (void *)arg, sizeof(ioparam)) != 0) { + pr_err("[%s]: failed to copy-from-user header for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + block = kmalloc(ioparam.op_count * + sizeof(struct vmcs_sm_ioctl_clean_invalid_block), + GFP_KERNEL); + if (!block) { + ret = -EFAULT; + goto out; + } + if (copy_from_user(block, + (void *)(arg + sizeof(ioparam)), ioparam.op_count * sizeof(struct vmcs_sm_ioctl_clean_invalid_block)) != 0) { + pr_err("[%s]: failed to copy-from-user payload for cmd %x\n", + __func__, cmdnr); + ret = -EFAULT; + goto out; + } + + for (i = 0; i < ioparam.op_count; i++) { + const struct vmcs_sm_ioctl_clean_invalid_block * const op = block + i; + + if (op->invalidate_mode == VCSM_CACHE_OP_NOP) + continue; + + ret = clean_invalid_contiguous_mem_2d( + (void __user*) op->start_address, op->block_count, + op->block_size, op->inter_block_stride, + op->invalidate_mode); + if (ret) + break; + } + kfree(block); + } + break; + + default: + { + ret = -EINVAL; + goto out; + } + break; + } + +out: + return ret; +} + +/* Device operations that we managed in this driver. */ +static const struct file_operations vmcs_sm_ops = { + .owner = THIS_MODULE, + .unlocked_ioctl = vc_sm_ioctl, + .open = vc_sm_open, + .release = vc_sm_release, + .mmap = vc_sm_mmap, +}; + +/* Creation of device. */ +static int vc_sm_create_sharedmemory(void) +{ + int ret; + + if (sm_state == NULL) { + ret = -ENOMEM; + goto out; + } + + /* Create a device class for creating dev nodes. */ + sm_state->sm_class = class_create(THIS_MODULE, "vc-sm"); + if (IS_ERR(sm_state->sm_class)) { + pr_err("[%s]: unable to create device class\n", __func__); + ret = PTR_ERR(sm_state->sm_class); + goto out; + } + + /* Create a character driver. */ + ret = alloc_chrdev_region(&sm_state->sm_devid, + DEVICE_MINOR, 1, DEVICE_NAME); + if (ret != 0) { + pr_err("[%s]: unable to allocate device number\n", __func__); + goto out_dev_class_destroy; + } + + cdev_init(&sm_state->sm_cdev, &vmcs_sm_ops); + ret = cdev_add(&sm_state->sm_cdev, sm_state->sm_devid, 1); + if (ret != 0) { + pr_err("[%s]: unable to register device\n", __func__); + goto out_chrdev_unreg; + } + + /* Create a device node. */ + sm_state->sm_dev = device_create(sm_state->sm_class, + NULL, + MKDEV(MAJOR(sm_state->sm_devid), + DEVICE_MINOR), NULL, + DEVICE_NAME); + if (IS_ERR(sm_state->sm_dev)) { + pr_err("[%s]: unable to create device node\n", __func__); + ret = PTR_ERR(sm_state->sm_dev); + goto out_chrdev_del; + } + + goto out; + +out_chrdev_del: + cdev_del(&sm_state->sm_cdev); +out_chrdev_unreg: + unregister_chrdev_region(sm_state->sm_devid, 1); +out_dev_class_destroy: + class_destroy(sm_state->sm_class); + sm_state->sm_class = NULL; +out: + return ret; +} + +/* Termination of the device. */ +static int vc_sm_remove_sharedmemory(void) +{ + int ret; + + if (sm_state == NULL) { + /* Nothing to do. */ + ret = 0; + goto out; + } + + /* Remove the sharedmemory character driver. */ + cdev_del(&sm_state->sm_cdev); + + /* Unregister region. */ + unregister_chrdev_region(sm_state->sm_devid, 1); + + ret = 0; + goto out; + +out: + return ret; +} + +/* Videocore connected. */ +static void vc_sm_connected_init(void) +{ + int ret; + VCHI_INSTANCE_T vchi_instance; + VCHI_CONNECTION_T *vchi_connection = NULL; + + pr_info("[%s]: start\n", __func__); + + /* + * Initialize and create a VCHI connection for the shared memory service + * running on videocore. + */ + ret = vchi_initialise(&vchi_instance); + if (ret != 0) { + pr_err("[%s]: failed to initialise VCHI instance (ret=%d)\n", + __func__, ret); + + ret = -EIO; + goto err_free_mem; + } + + ret = vchi_connect(NULL, 0, vchi_instance); + if (ret != 0) { + pr_err("[%s]: failed to connect VCHI instance (ret=%d)\n", + __func__, ret); + + ret = -EIO; + goto err_free_mem; + } + + /* Initialize an instance of the shared memory service. */ + sm_state->sm_handle = + vc_vchi_sm_init(vchi_instance, &vchi_connection, 1); + if (sm_state->sm_handle == NULL) { + pr_err("[%s]: failed to initialize shared memory service\n", + __func__); + + ret = -EPERM; + goto err_free_mem; + } + + /* Create a debug fs directory entry (root). */ + sm_state->dir_root = debugfs_create_dir(VC_SM_DIR_ROOT_NAME, NULL); + if (!sm_state->dir_root) { + pr_err("[%s]: failed to create \'%s\' directory entry\n", + __func__, VC_SM_DIR_ROOT_NAME); + + ret = -EPERM; + goto err_stop_sm_service; + } + + sm_state->dir_state.show = &vc_sm_global_state_show; + sm_state->dir_state.dir_entry = debugfs_create_file(VC_SM_STATE, + 0444, sm_state->dir_root, &sm_state->dir_state, + &vc_sm_debug_fs_fops); + + sm_state->dir_stats.show = &vc_sm_global_statistics_show; + sm_state->dir_stats.dir_entry = debugfs_create_file(VC_SM_STATS, + 0444, sm_state->dir_root, &sm_state->dir_stats, + &vc_sm_debug_fs_fops); + + /* Create the proc entry children. */ + sm_state->dir_alloc = debugfs_create_dir(VC_SM_DIR_ALLOC_NAME, + sm_state->dir_root); + + /* Create a shared memory device. */ + ret = vc_sm_create_sharedmemory(); + if (ret != 0) { + pr_err("[%s]: failed to create shared memory device\n", + __func__); + goto err_remove_debugfs; + } + + INIT_LIST_HEAD(&sm_state->map_list); + INIT_LIST_HEAD(&sm_state->resource_list); + + sm_state->data_knl = vc_sm_create_priv_data(0); + if (sm_state->data_knl == NULL) { + pr_err("[%s]: failed to create kernel private data tracker\n", + __func__); + goto err_remove_shared_memory; + } + + /* Done! */ + sm_inited = 1; + goto out; + +err_remove_shared_memory: + vc_sm_remove_sharedmemory(); +err_remove_debugfs: + debugfs_remove_recursive(sm_state->dir_root); +err_stop_sm_service: + vc_vchi_sm_stop(&sm_state->sm_handle); +err_free_mem: + kfree(sm_state); +out: + pr_info("[%s]: end - returning %d\n", __func__, ret); +} + +/* Driver loading. */ +static int bcm2835_vcsm_probe(struct platform_device *pdev) +{ + pr_info("vc-sm: Videocore shared memory driver\n"); + + sm_state = kzalloc(sizeof(*sm_state), GFP_KERNEL); + if (!sm_state) + return -ENOMEM; + sm_state->pdev = pdev; + mutex_init(&sm_state->lock); + mutex_init(&sm_state->map_lock); + + vchiq_add_connected_callback(vc_sm_connected_init); + return 0; +} + +/* Driver unloading. */ +static int bcm2835_vcsm_remove(struct platform_device *pdev) +{ + pr_debug("[%s]: start\n", __func__); + if (sm_inited) { + /* Remove shared memory device. */ + vc_sm_remove_sharedmemory(); + + /* Remove all proc entries. */ + debugfs_remove_recursive(sm_state->dir_root); + + /* Stop the videocore shared memory service. */ + vc_vchi_sm_stop(&sm_state->sm_handle); + + /* Free the memory for the state structure. */ + mutex_destroy(&(sm_state->map_lock)); + kfree(sm_state); + } + + pr_debug("[%s]: end\n", __func__); + return 0; +} + +#if defined(__KERNEL__) +/* Allocate a shared memory handle and block. */ +int vc_sm_alloc(struct vc_sm_alloc_t *alloc, int *handle) +{ + struct vmcs_sm_ioctl_alloc ioparam = { 0 }; + int ret; + struct sm_resource_t *resource; + + /* Validate we can work with this device. */ + if (sm_state == NULL || alloc == NULL || handle == NULL) { + pr_err("[%s]: invalid input\n", __func__); + return -EPERM; + } + + ioparam.size = alloc->base_unit; + ioparam.num = alloc->num_unit; + ioparam.cached = + alloc->type == VC_SM_ALLOC_CACHED ? VMCS_SM_CACHE_VC : 0; + + ret = vc_sm_ioctl_alloc(sm_state->data_knl, &ioparam); + + if (ret == 0) { + resource = + vmcs_sm_acquire_resource(sm_state->data_knl, + ioparam.handle); + if (resource) { + resource->pid = 0; + vmcs_sm_release_resource(resource, 0); + + /* Assign valid handle at this time. */ + *handle = ioparam.handle; + } else { + ret = -ENOMEM; + } + } + + return ret; +} +EXPORT_SYMBOL_GPL(vc_sm_alloc); + +/* Get an internal resource handle mapped from the external one. */ +int vc_sm_int_handle(int handle) +{ + struct sm_resource_t *resource; + int ret = 0; + + /* Validate we can work with this device. */ + if (sm_state == NULL || handle == 0) { + pr_err("[%s]: invalid input\n", __func__); + return 0; + } + + /* Locate resource from GUID. */ + resource = vmcs_sm_acquire_resource(sm_state->data_knl, handle); + if (resource) { + ret = resource->res_handle; + vmcs_sm_release_resource(resource, 0); + } + + return ret; +} +EXPORT_SYMBOL_GPL(vc_sm_int_handle); + +/* Free a previously allocated shared memory handle and block. */ +int vc_sm_free(int handle) +{ + struct vmcs_sm_ioctl_free ioparam = { handle }; + + /* Validate we can work with this device. */ + if (sm_state == NULL || handle == 0) { + pr_err("[%s]: invalid input\n", __func__); + return -EPERM; + } + + return vc_sm_ioctl_free(sm_state->data_knl, &ioparam); +} +EXPORT_SYMBOL_GPL(vc_sm_free); + +/* Lock a memory handle for use by kernel. */ +int vc_sm_lock(int handle, enum vc_sm_lock_cache_mode mode, + unsigned long *data) +{ + struct vmcs_sm_ioctl_lock_unlock ioparam; + int ret; + + /* Validate we can work with this device. */ + if (sm_state == NULL || handle == 0 || data == NULL) { + pr_err("[%s]: invalid input\n", __func__); + return -EPERM; + } + + *data = 0; + + ioparam.handle = handle; + ret = vc_sm_ioctl_lock(sm_state->data_knl, + &ioparam, + 1, + ((mode == + VC_SM_LOCK_CACHED) ? VMCS_SM_CACHE_HOST : + VMCS_SM_CACHE_NONE), 0); + + *data = ioparam.addr; + return ret; +} +EXPORT_SYMBOL_GPL(vc_sm_lock); + +/* Unlock a memory handle in use by kernel. */ +int vc_sm_unlock(int handle, int flush, int no_vc_unlock) +{ + struct vmcs_sm_ioctl_lock_unlock ioparam; + + /* Validate we can work with this device. */ + if (sm_state == NULL || handle == 0) { + pr_err("[%s]: invalid input\n", __func__); + return -EPERM; + } + + ioparam.handle = handle; + return vc_sm_ioctl_unlock(sm_state->data_knl, + &ioparam, flush, 0, no_vc_unlock); +} +EXPORT_SYMBOL_GPL(vc_sm_unlock); + +/* Map a shared memory region for use by kernel. */ +int vc_sm_map(int handle, unsigned int sm_addr, + enum vc_sm_lock_cache_mode mode, unsigned long *data) +{ + struct vmcs_sm_ioctl_lock_unlock ioparam; + int ret; + + /* Validate we can work with this device. */ + if (sm_state == NULL || handle == 0 || data == NULL || sm_addr == 0) { + pr_err("[%s]: invalid input\n", __func__); + return -EPERM; + } + + *data = 0; + + ioparam.handle = handle; + ret = vc_sm_ioctl_lock(sm_state->data_knl, + &ioparam, + 1, + ((mode == + VC_SM_LOCK_CACHED) ? VMCS_SM_CACHE_HOST : + VMCS_SM_CACHE_NONE), sm_addr); + + *data = ioparam.addr; + return ret; +} +EXPORT_SYMBOL_GPL(vc_sm_map); + +/* Import a dmabuf to be shared with VC. */ +int vc_sm_import_dmabuf(struct dma_buf *dmabuf, int *handle) +{ + struct vmcs_sm_ioctl_import_dmabuf ioparam = { 0 }; + int ret; + struct sm_resource_t *resource; + + /* Validate we can work with this device. */ + if (!sm_state || !dmabuf || !handle) { + pr_err("[%s]: invalid input\n", __func__); + return -EPERM; + } + + ioparam.cached = 0; + strcpy(ioparam.name, "KRNL DMABUF"); + + ret = vc_sm_ioctl_import_dmabuf(sm_state->data_knl, &ioparam, dmabuf); + + if (!ret) { + resource = vmcs_sm_acquire_resource(sm_state->data_knl, + ioparam.handle); + if (resource) { + resource->pid = 0; + vmcs_sm_release_resource(resource, 0); + + /* Assign valid handle at this time.*/ + *handle = ioparam.handle; + } else { + ret = -ENOMEM; + } + } + + return ret; +} +EXPORT_SYMBOL_GPL(vc_sm_import_dmabuf); +#endif + +/* + * Register the driver with device tree + */ + +static const struct of_device_id bcm2835_vcsm_of_match[] = { + {.compatible = "raspberrypi,bcm2835-vcsm",}, + { /* sentinel */ }, +}; + +MODULE_DEVICE_TABLE(of, bcm2835_vcsm_of_match); + +static struct platform_driver bcm2835_vcsm_driver = { + .probe = bcm2835_vcsm_probe, + .remove = bcm2835_vcsm_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = bcm2835_vcsm_of_match, + }, +}; + +module_platform_driver(bcm2835_vcsm_driver); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("VideoCore SharedMemory Driver"); +MODULE_LICENSE("GPL v2"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/hw_random/bcm2835-rng.c linux-vendor/drivers/char/hw_random/bcm2835-rng.c --- linux-4.18.16/drivers/char/hw_random/bcm2835-rng.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/char/hw_random/bcm2835-rng.c 2018-10-29 19:31:20.944762993 +0100 @@ -105,8 +105,10 @@ } /* set warm-up count & enable */ - rng_writel(priv, RNG_WARMUP_COUNT, RNG_STATUS); - rng_writel(priv, RNG_RBGEN, RNG_CTRL); + if (!(rng_readl(priv, RNG_CTRL) & RNG_RBGEN)) { + rng_writel(priv, RNG_WARMUP_COUNT, RNG_STATUS); + rng_writel(priv, RNG_RBGEN, RNG_CTRL); + } return ret; } diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/Kconfig linux-vendor/drivers/char/Kconfig --- linux-4.18.16/drivers/char/Kconfig 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/char/Kconfig 2018-10-29 19:31:20.940763193 +0100 @@ -5,6 +5,8 @@ menu "Character devices" +source "drivers/char/broadcom/Kconfig" + source "drivers/tty/Kconfig" config DEVMEM diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/Makefile linux-vendor/drivers/char/Makefile --- linux-4.18.16/drivers/char/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/char/Makefile 2018-10-29 19:31:20.940763193 +0100 @@ -58,3 +58,4 @@ obj-$(CONFIG_XILLYBUS) += xillybus/ obj-$(CONFIG_POWERNV_OP_PANEL) += powernv-op-panel.o obj-$(CONFIG_ADI) += adi.o +obj-$(CONFIG_BRCM_CHAR_DRIVERS) += broadcom/ diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/char/tpm/Kconfig linux-vendor/drivers/char/tpm/Kconfig --- linux-4.18.16/drivers/char/tpm/Kconfig 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/char/tpm/Kconfig 2018-10-29 19:31:20.950762693 +0100 @@ -5,7 +5,7 @@ menuconfig TCG_TPM tristate "TPM Hardware Support" depends on HAS_IOMEM - select SECURITYFS + imply SECURITYFS select CRYPTO select CRYPTO_HASH_INFO ---help--- diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/clk/bcm/clk-bcm2835.c linux-vendor/drivers/clk/bcm/clk-bcm2835.c --- linux-4.18.16/drivers/clk/bcm/clk-bcm2835.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/clk/bcm/clk-bcm2835.c 2018-10-29 19:31:20.952762593 +0100 @@ -44,6 +44,7 @@ #include #include #include +#include #define CM_PASSWORD 0x5a000000 @@ -298,6 +299,8 @@ #define LOCK_TIMEOUT_NS 100000000 #define BCM2835_MAX_FB_RATE 1750000000u +#define VCMSG_ID_CORE_CLOCK 4 + /* * Names of clocks used within the driver that need to be replaced * with an external parent's name. This array is in the order that @@ -316,6 +319,7 @@ struct bcm2835_cprman { struct device *dev; void __iomem *regs; + struct rpi_firmware *fw; spinlock_t regs_lock; /* spinlock for all clocks */ /* @@ -998,6 +1002,30 @@ return bcm2835_clock_rate_from_divisor(clock, parent_rate, div); } +static unsigned long bcm2835_clock_get_rate_vpu(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); + struct bcm2835_cprman *cprman = clock->cprman; + + if (cprman->fw) { + struct { + u32 id; + u32 val; + } packet; + + packet.id = VCMSG_ID_CORE_CLOCK; + packet.val = 0; + + if (!rpi_firmware_property(cprman->fw, + RPI_FIRMWARE_GET_MAX_CLOCK_RATE, + &packet, sizeof(packet))) + return packet.val; + } + + return bcm2835_clock_get_rate(hw, parent_rate); +} + static void bcm2835_clock_wait_busy(struct bcm2835_clock *clock) { struct bcm2835_cprman *cprman = clock->cprman; @@ -1286,7 +1314,7 @@ */ static const struct clk_ops bcm2835_vpu_clock_clk_ops = { .is_prepared = bcm2835_vpu_clock_is_on, - .recalc_rate = bcm2835_clock_get_rate, + .recalc_rate = bcm2835_clock_get_rate_vpu, .set_rate = bcm2835_clock_set_rate, .determine_rate = bcm2835_clock_determine_rate, .set_parent = bcm2835_clock_set_parent, @@ -1294,6 +1322,8 @@ .debug_init = bcm2835_clock_debug_init, }; +static bool bcm2835_clk_is_claimed(const char *name); + static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman, const struct bcm2835_pll_data *data) { @@ -1310,6 +1340,9 @@ init.ops = &bcm2835_pll_clk_ops; init.flags = CLK_IGNORE_UNUSED; + if (!bcm2835_clk_is_claimed(data->name)) + init.flags |= CLK_IS_CRITICAL; + pll = kzalloc(sizeof(*pll), GFP_KERNEL); if (!pll) return NULL; @@ -1362,6 +1395,13 @@ divider->div.hw.init = &init; divider->div.table = NULL; + if (!(cprman_read(cprman, data->cm_reg) & data->hold_mask)) { + if (!bcm2835_clk_is_claimed(data->source_pll)) + init.flags |= CLK_IS_CRITICAL; + if (!bcm2835_clk_is_claimed(data->name)) + divider->div.flags |= CLK_IS_CRITICAL; + } + divider->cprman = cprman; divider->data = data; @@ -1414,6 +1454,15 @@ init.flags = data->flags | CLK_IGNORE_UNUSED; /* + * Some GPIO clocks for ethernet/wifi PLLs are marked as + * critical (since some platforms use them), but if the + * firmware didn't have them turned on then they clearly + * aren't actually critical. + */ + if ((cprman_read(cprman, data->ctl_reg) & CM_ENABLE) == 0) + init.flags &= ~CLK_IS_CRITICAL; + + /* * Pass the CLK_SET_RATE_PARENT flag if we are allowed to propagate * rate changes on at least of the parents. */ @@ -2111,6 +2160,8 @@ .ctl_reg = CM_PERIICTL), }; +static bool bcm2835_clk_claimed[ARRAY_SIZE(clk_desc_array)]; + /* * Permanently take a reference on the parent of the SDRAM clock. * @@ -2130,6 +2181,19 @@ return clk_prepare_enable(parent); } +static bool bcm2835_clk_is_claimed(const char *name) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(clk_desc_array); i++) { + const char *clk_name = *(const char **)(clk_desc_array[i].data); + if (!strcmp(name, clk_name)) + return bcm2835_clk_claimed[i]; + } + + return false; +} + static int bcm2835_clk_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -2138,7 +2202,9 @@ struct resource *res; const struct bcm2835_clk_desc *desc; const size_t asize = ARRAY_SIZE(clk_desc_array); + struct device_node *fw_node; size_t i; + u32 clk_id; int ret; cprman = devm_kzalloc(dev, @@ -2154,6 +2220,21 @@ if (IS_ERR(cprman->regs)) return PTR_ERR(cprman->regs); + fw_node = of_parse_phandle(dev->of_node, "firmware", 0); + if (fw_node) { + struct rpi_firmware *fw = rpi_firmware_get(NULL); + if (!fw) + return -EPROBE_DEFER; + cprman->fw = fw; + } + + memset(bcm2835_clk_claimed, 0, sizeof(bcm2835_clk_claimed)); + for (i = 0; + !of_property_read_u32_index(pdev->dev.of_node, "claim-clocks", + i, &clk_id); + i++) + bcm2835_clk_claimed[clk_id]= true; + memcpy(cprman->real_parent_names, cprman_parent_names, sizeof(cprman_parent_names)); of_clk_parent_fill(dev->of_node, cprman->real_parent_names, @@ -2184,8 +2265,15 @@ if (ret) return ret; - return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, + ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, &cprman->onecell); + if (ret) + return ret; + + /* note that we have registered all the clocks */ + dev_dbg(dev, "registered %d clocks\n", asize); + + return 0; } static const struct of_device_id bcm2835_clk_of_match[] = { @@ -2202,7 +2290,11 @@ .probe = bcm2835_clk_probe, }; -builtin_platform_driver(bcm2835_clk_driver); +static int __init __bcm2835_clk_driver_init(void) +{ + return platform_driver_register(&bcm2835_clk_driver); +} +core_initcall(__bcm2835_clk_driver_init); MODULE_AUTHOR("Eric Anholt "); MODULE_DESCRIPTION("BCM2835 clock driver"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/clk/clk-allo-dac.c linux-vendor/drivers/clk/clk-allo-dac.c --- linux-4.18.16/drivers/clk/clk-allo-dac.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/clk/clk-allo-dac.c 2018-10-29 19:31:20.953762544 +0100 @@ -0,0 +1,161 @@ +/* + * Clock Driver for Allo DAC + * + * Author: Baswaraj K + * Copyright 2016 + * based on code by Stuart MacLean + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Clock rate of CLK44EN attached to GPIO6 pin */ +#define CLK_44EN_RATE 45158400UL +/* Clock rate of CLK48EN attached to GPIO3 pin */ +#define CLK_48EN_RATE 49152000UL + +/** + * struct allo_dac_clk - Common struct to the Allo DAC + * @hw: clk_hw for the common clk framework + * @mode: 0 => CLK44EN, 1 => CLK48EN + */ +struct clk_allo_hw { + struct clk_hw hw; + uint8_t mode; +}; + +#define to_allo_clk(_hw) container_of(_hw, struct clk_allo_hw, hw) + +static const struct of_device_id clk_allo_dac_dt_ids[] = { + { .compatible = "allo,dac-clk",}, + { } +}; +MODULE_DEVICE_TABLE(of, clk_allo_dac_dt_ids); + +static unsigned long clk_allo_dac_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return (to_allo_clk(hw)->mode == 0) ? CLK_44EN_RATE : + CLK_48EN_RATE; +} + +static long clk_allo_dac_round_rate(struct clk_hw *hw, + unsigned long rate, unsigned long *parent_rate) +{ + long actual_rate; + + if (rate <= CLK_44EN_RATE) { + actual_rate = (long)CLK_44EN_RATE; + } else if (rate >= CLK_48EN_RATE) { + actual_rate = (long)CLK_48EN_RATE; + } else { + long diff44Rate = (long)(rate - CLK_44EN_RATE); + long diff48Rate = (long)(CLK_48EN_RATE - rate); + + if (diff44Rate < diff48Rate) + actual_rate = (long)CLK_44EN_RATE; + else + actual_rate = (long)CLK_48EN_RATE; + } + return actual_rate; +} + + +static int clk_allo_dac_set_rate(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate) +{ + unsigned long actual_rate; + struct clk_allo_hw *clk = to_allo_clk(hw); + + actual_rate = (unsigned long)clk_allo_dac_round_rate(hw, rate, + &parent_rate); + clk->mode = (actual_rate == CLK_44EN_RATE) ? 0 : 1; + return 0; +} + + +const struct clk_ops clk_allo_dac_rate_ops = { + .recalc_rate = clk_allo_dac_recalc_rate, + .round_rate = clk_allo_dac_round_rate, + .set_rate = clk_allo_dac_set_rate, +}; + +static int clk_allo_dac_probe(struct platform_device *pdev) +{ + int ret; + struct clk_allo_hw *proclk; + struct clk *clk; + struct device *dev; + struct clk_init_data init; + + dev = &pdev->dev; + + proclk = kzalloc(sizeof(struct clk_allo_hw), GFP_KERNEL); + if (!proclk) + return -ENOMEM; + + init.name = "clk-allo-dac"; + init.ops = &clk_allo_dac_rate_ops; + init.flags = CLK_IS_BASIC; + init.parent_names = NULL; + init.num_parents = 0; + + proclk->mode = 0; + proclk->hw.init = &init; + + clk = devm_clk_register(dev, &proclk->hw); + if (!IS_ERR(clk)) { + ret = of_clk_add_provider(dev->of_node, of_clk_src_simple_get, + clk); + } else { + dev_err(dev, "Fail to register clock driver\n"); + kfree(proclk); + ret = PTR_ERR(clk); + } + return ret; +} + +static int clk_allo_dac_remove(struct platform_device *pdev) +{ + of_clk_del_provider(pdev->dev.of_node); + return 0; +} + +static struct platform_driver clk_allo_dac_driver = { + .probe = clk_allo_dac_probe, + .remove = clk_allo_dac_remove, + .driver = { + .name = "clk-allo-dac", + .of_match_table = clk_allo_dac_dt_ids, + }, +}; + +static int __init clk_allo_dac_init(void) +{ + return platform_driver_register(&clk_allo_dac_driver); +} +core_initcall(clk_allo_dac_init); + +static void __exit clk_allo_dac_exit(void) +{ + platform_driver_unregister(&clk_allo_dac_driver); +} +module_exit(clk_allo_dac_exit); + +MODULE_DESCRIPTION("Allo DAC clock driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:clk-allo-dac"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/clk/clk-hifiberry-dacpro.c linux-vendor/drivers/clk/clk-hifiberry-dacpro.c --- linux-4.18.16/drivers/clk/clk-hifiberry-dacpro.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/clk/clk-hifiberry-dacpro.c 2018-10-29 19:31:20.955762445 +0100 @@ -0,0 +1,160 @@ +/* + * Clock Driver for HiFiBerry DAC Pro + * + * Author: Stuart MacLean + * Copyright 2015 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Clock rate of CLK44EN attached to GPIO6 pin */ +#define CLK_44EN_RATE 22579200UL +/* Clock rate of CLK48EN attached to GPIO3 pin */ +#define CLK_48EN_RATE 24576000UL + +/** + * struct hifiberry_dacpro_clk - Common struct to the HiFiBerry DAC Pro + * @hw: clk_hw for the common clk framework + * @mode: 0 => CLK44EN, 1 => CLK48EN + */ +struct clk_hifiberry_hw { + struct clk_hw hw; + uint8_t mode; +}; + +#define to_hifiberry_clk(_hw) container_of(_hw, struct clk_hifiberry_hw, hw) + +static const struct of_device_id clk_hifiberry_dacpro_dt_ids[] = { + { .compatible = "hifiberry,dacpro-clk",}, + { } +}; +MODULE_DEVICE_TABLE(of, clk_hifiberry_dacpro_dt_ids); + +static unsigned long clk_hifiberry_dacpro_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return (to_hifiberry_clk(hw)->mode == 0) ? CLK_44EN_RATE : + CLK_48EN_RATE; +} + +static long clk_hifiberry_dacpro_round_rate(struct clk_hw *hw, + unsigned long rate, unsigned long *parent_rate) +{ + long actual_rate; + + if (rate <= CLK_44EN_RATE) { + actual_rate = (long)CLK_44EN_RATE; + } else if (rate >= CLK_48EN_RATE) { + actual_rate = (long)CLK_48EN_RATE; + } else { + long diff44Rate = (long)(rate - CLK_44EN_RATE); + long diff48Rate = (long)(CLK_48EN_RATE - rate); + + if (diff44Rate < diff48Rate) + actual_rate = (long)CLK_44EN_RATE; + else + actual_rate = (long)CLK_48EN_RATE; + } + return actual_rate; +} + + +static int clk_hifiberry_dacpro_set_rate(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate) +{ + unsigned long actual_rate; + struct clk_hifiberry_hw *clk = to_hifiberry_clk(hw); + + actual_rate = (unsigned long)clk_hifiberry_dacpro_round_rate(hw, rate, + &parent_rate); + clk->mode = (actual_rate == CLK_44EN_RATE) ? 0 : 1; + return 0; +} + + +const struct clk_ops clk_hifiberry_dacpro_rate_ops = { + .recalc_rate = clk_hifiberry_dacpro_recalc_rate, + .round_rate = clk_hifiberry_dacpro_round_rate, + .set_rate = clk_hifiberry_dacpro_set_rate, +}; + +static int clk_hifiberry_dacpro_probe(struct platform_device *pdev) +{ + int ret; + struct clk_hifiberry_hw *proclk; + struct clk *clk; + struct device *dev; + struct clk_init_data init; + + dev = &pdev->dev; + + proclk = kzalloc(sizeof(struct clk_hifiberry_hw), GFP_KERNEL); + if (!proclk) + return -ENOMEM; + + init.name = "clk-hifiberry-dacpro"; + init.ops = &clk_hifiberry_dacpro_rate_ops; + init.flags = CLK_IS_BASIC; + init.parent_names = NULL; + init.num_parents = 0; + + proclk->mode = 0; + proclk->hw.init = &init; + + clk = devm_clk_register(dev, &proclk->hw); + if (!IS_ERR(clk)) { + ret = of_clk_add_provider(dev->of_node, of_clk_src_simple_get, + clk); + } else { + dev_err(dev, "Fail to register clock driver\n"); + kfree(proclk); + ret = PTR_ERR(clk); + } + return ret; +} + +static int clk_hifiberry_dacpro_remove(struct platform_device *pdev) +{ + of_clk_del_provider(pdev->dev.of_node); + return 0; +} + +static struct platform_driver clk_hifiberry_dacpro_driver = { + .probe = clk_hifiberry_dacpro_probe, + .remove = clk_hifiberry_dacpro_remove, + .driver = { + .name = "clk-hifiberry-dacpro", + .of_match_table = clk_hifiberry_dacpro_dt_ids, + }, +}; + +static int __init clk_hifiberry_dacpro_init(void) +{ + return platform_driver_register(&clk_hifiberry_dacpro_driver); +} +core_initcall(clk_hifiberry_dacpro_init); + +static void __exit clk_hifiberry_dacpro_exit(void) +{ + platform_driver_unregister(&clk_hifiberry_dacpro_driver); +} +module_exit(clk_hifiberry_dacpro_exit); + +MODULE_DESCRIPTION("HiFiBerry DAC Pro clock driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:clk-hifiberry-dacpro"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/clk/Makefile linux-vendor/drivers/clk/Makefile --- linux-4.18.16/drivers/clk/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/clk/Makefile 2018-10-29 19:31:20.951762643 +0100 @@ -18,6 +18,7 @@ # hardware specific clock types # please keep this section sorted lexicographically by file path name +obj-$(CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC) += clk-allo-dac.o obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o @@ -30,6 +31,7 @@ obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o +obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += clk-hifiberry-dacpro.o obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/cpufreq/bcm2835-cpufreq.c linux-vendor/drivers/cpufreq/bcm2835-cpufreq.c --- linux-4.18.16/drivers/cpufreq/bcm2835-cpufreq.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/cpufreq/bcm2835-cpufreq.c 2018-10-29 19:31:20.963762045 +0100 @@ -0,0 +1,210 @@ +/* + * Copyright 2011 Broadcom Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * This driver dynamically manages the CPU Frequency of the ARM + * processor. Messages are sent to Videocore either setting or requesting the + * frequency of the ARM in order to match an appropiate frequency to the current + * usage of the processor. The policy which selects the frequency to use is + * defined in the kernel .config file, but can be changed during runtime. + */ + +/* ---------- INCLUDES ---------- */ +#include +#include +#include +#include +#include + +/* ---------- DEFINES ---------- */ +/*#define CPUFREQ_DEBUG_ENABLE*/ /* enable debugging */ +#define MODULE_NAME "bcm2835-cpufreq" + +#define VCMSG_ID_ARM_CLOCK 0x000000003 /* Clock/Voltage ID's */ + +/* debug printk macros */ +#ifdef CPUFREQ_DEBUG_ENABLE +#define print_debug(fmt,...) pr_debug("%s:%s:%d: "fmt, MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__) +#else +#define print_debug(fmt,...) +#endif +#define print_err(fmt,...) pr_err("%s:%s:%d: "fmt, MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) +#define print_info(fmt,...) pr_info("%s: "fmt, MODULE_NAME, ##__VA_ARGS__) + +/* ---------- GLOBALS ---------- */ +static struct cpufreq_driver bcm2835_cpufreq_driver; /* the cpufreq driver global */ +static unsigned int min_frequency, max_frequency; +static struct cpufreq_frequency_table bcm2835_freq_table[3]; + +/* + =============================================== + clk_rate either gets or sets the clock rates. + =============================================== +*/ + +static int bcm2835_cpufreq_clock_property(u32 tag, u32 id, u32 *val) +{ + struct rpi_firmware *fw = rpi_firmware_get(NULL); + struct { + u32 id; + u32 val; + } packet; + int ret; + + packet.id = id; + packet.val = *val; + ret = rpi_firmware_property(fw, tag, &packet, sizeof(packet)); + if (ret) + return ret; + + *val = packet.val; + + return 0; +} + +static uint32_t bcm2835_cpufreq_set_clock(int cur_rate, int arm_rate) +{ + u32 rate = arm_rate * 1000; + int ret; + + ret = bcm2835_cpufreq_clock_property(RPI_FIRMWARE_SET_CLOCK_RATE, VCMSG_ID_ARM_CLOCK, &rate); + if (ret) { + print_err("Failed to set clock: %d (%d)\n", arm_rate, ret); + return 0; + } + + rate /= 1000; + print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, rate); + + return rate; +} + +static uint32_t bcm2835_cpufreq_get_clock(int tag) +{ + u32 rate; + int ret; + + ret = bcm2835_cpufreq_clock_property(tag, VCMSG_ID_ARM_CLOCK, &rate); + if (ret) { + print_err("Failed to get clock (%d)\n", ret); + return 0; + } + + rate /= 1000; + print_debug("%s frequency = %u\n", + tag == RPI_FIRMWARE_GET_CLOCK_RATE ? "Current": + tag == RPI_FIRMWARE_GET_MIN_CLOCK_RATE ? "Min": + tag == RPI_FIRMWARE_GET_MAX_CLOCK_RATE ? "Max": + "Unexpected", rate); + + return rate; +} + +/* + ==================================================== + Module Initialisation registers the cpufreq driver + ==================================================== +*/ +static int __init bcm2835_cpufreq_module_init(void) +{ + print_debug("IN\n"); + return cpufreq_register_driver(&bcm2835_cpufreq_driver); +} + +/* + ============= + Module exit + ============= +*/ +static void __exit bcm2835_cpufreq_module_exit(void) +{ + print_debug("IN\n"); + cpufreq_unregister_driver(&bcm2835_cpufreq_driver); + return; +} + +/* + ============================================================== + Initialisation function sets up the CPU policy for first use + ============================================================== +*/ +static int bcm2835_cpufreq_driver_init(struct cpufreq_policy *policy) +{ + /* measured value of how long it takes to change frequency */ + const unsigned int transition_latency = 355000; /* ns */ + + if (!rpi_firmware_get(NULL)) { + print_err("Firmware is not available\n"); + return -ENODEV; + } + + /* now find out what the maximum and minimum frequencies are */ + min_frequency = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); + max_frequency = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE); + + if (min_frequency == max_frequency) { + bcm2835_freq_table[0].frequency = min_frequency; + bcm2835_freq_table[1].frequency = CPUFREQ_TABLE_END; + } else { + bcm2835_freq_table[0].frequency = min_frequency; + bcm2835_freq_table[1].frequency = max_frequency; + bcm2835_freq_table[2].frequency = CPUFREQ_TABLE_END; + } + + print_info("min=%d max=%d\n", min_frequency, max_frequency); + return cpufreq_generic_init(policy, bcm2835_freq_table, transition_latency); +} + +/* + ===================================================================== + Target index function chooses the requested frequency from the table + ===================================================================== +*/ + +static int bcm2835_cpufreq_driver_target_index(struct cpufreq_policy *policy, unsigned int state) +{ + unsigned int target_freq = state == 0 ? min_frequency : max_frequency; + unsigned int cur = bcm2835_cpufreq_set_clock(policy->cur, target_freq); + + if (!cur) + { + print_err("Error occurred setting a new frequency (%d)\n", target_freq); + return -EINVAL; + } + print_debug("%s: %i: freq %d->%d\n", policy->governor->name, state, policy->cur, cur); + return 0; +} + +/* + ====================================================== + Get function returns the current frequency from table + ====================================================== +*/ + +static unsigned int bcm2835_cpufreq_driver_get(unsigned int cpu) +{ + unsigned int actual_rate = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_CLOCK_RATE); + print_debug("cpu%d: freq=%d\n", cpu, actual_rate); + return actual_rate <= min_frequency ? min_frequency : max_frequency; +} + +/* the CPUFreq driver */ +static struct cpufreq_driver bcm2835_cpufreq_driver = { + .name = "BCM2835 CPUFreq", + .init = bcm2835_cpufreq_driver_init, + .verify = cpufreq_generic_frequency_table_verify, + .target_index = bcm2835_cpufreq_driver_target_index, + .get = bcm2835_cpufreq_driver_get, + .attr = cpufreq_generic_attr, +}; + +MODULE_AUTHOR("Dorian Peake and Dom Cobley"); +MODULE_DESCRIPTION("CPU frequency driver for BCM2835 chip"); +MODULE_LICENSE("GPL"); + +module_init(bcm2835_cpufreq_module_init); +module_exit(bcm2835_cpufreq_module_exit); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/cpufreq/Kconfig.arm linux-vendor/drivers/cpufreq/Kconfig.arm --- linux-4.18.16/drivers/cpufreq/Kconfig.arm 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/cpufreq/Kconfig.arm 2018-10-29 19:31:20.963762045 +0100 @@ -274,6 +274,15 @@ depends on CPUFREQ_DT && ARCH_TANGO default y +config ARM_BCM2835_CPUFREQ + depends on RASPBERRYPI_FIRMWARE + bool "BCM2835 Driver" + default y + help + This adds the CPUFreq driver for BCM2835 + + If in doubt, say N. + config ARM_TEGRA20_CPUFREQ tristate "Tegra20 CPUFreq support" depends on ARCH_TEGRA diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/cpufreq/Makefile linux-vendor/drivers/cpufreq/Makefile --- linux-4.18.16/drivers/cpufreq/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/cpufreq/Makefile 2018-10-29 19:31:20.963762045 +0100 @@ -81,6 +81,7 @@ obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o obj-$(CONFIG_ARM_STI_CPUFREQ) += sti-cpufreq.o obj-$(CONFIG_ARM_TANGO_CPUFREQ) += tango-cpufreq.o +obj-$(CONFIG_ARM_BCM2835_CPUFREQ) += bcm2835-cpufreq.o obj-$(CONFIG_ARM_TEGRA20_CPUFREQ) += tegra20-cpufreq.o obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o obj-$(CONFIG_ARM_TEGRA186_CPUFREQ) += tegra186-cpufreq.o diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/dma/bcm2708-dmaengine.c linux-vendor/drivers/dma/bcm2708-dmaengine.c --- linux-4.18.16/drivers/dma/bcm2708-dmaengine.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/dma/bcm2708-dmaengine.c 2018-10-29 19:31:21.030758702 +0100 @@ -0,0 +1,281 @@ +/* + * BCM2708 legacy DMA API + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "virt-dma.h" + +#define CACHE_LINE_MASK 31 +#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ + +/* valid only for channels 0 - 14, 15 has its own base address */ +#define BCM2708_DMA_CHAN(n) ((n) << 8) /* base address */ +#define BCM2708_DMA_CHANIO(dma_base, n) \ + ((void __iomem *)((char *)(dma_base) + BCM2708_DMA_CHAN(n))) + +struct vc_dmaman { + void __iomem *dma_base; + u32 chan_available; /* bitmap of available channels */ + u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ + struct mutex lock; +}; + +static struct device *dmaman_dev; /* we assume there's only one! */ +static struct vc_dmaman *g_dmaman; /* DMA manager */ + +/* DMA Auxiliary Functions */ + +/* A DMA buffer on an arbitrary boundary may separate a cache line into a + section inside the DMA buffer and another section outside it. + Even if we flush DMA buffers from the cache there is always the chance that + during a DMA someone will access the part of a cache line that is outside + the DMA buffer - which will then bring in unwelcome data. + Without being able to dictate our own buffer pools we must insist that + DMA buffers consist of a whole number of cache lines. +*/ +extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) +{ + int i; + + for (i = 0; i < sg_len; i++) { + if (sg_ptr[i].offset & CACHE_LINE_MASK || + sg_ptr[i].length & CACHE_LINE_MASK) + return 0; + } + + return 1; +} +EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); + +extern void bcm_dma_start(void __iomem *dma_chan_base, + dma_addr_t control_block) +{ + dsb(sy); /* ARM data synchronization (push) operation */ + + writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); + writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); +} +EXPORT_SYMBOL_GPL(bcm_dma_start); + +extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) +{ + dsb(sy); + + /* ugly busy wait only option for now */ + while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) + cpu_relax(); +} +EXPORT_SYMBOL_GPL(bcm_dma_wait_idle); + +extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) +{ + dsb(sy); + + return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; +} +EXPORT_SYMBOL_GPL(bcm_dma_is_busy); + +/* Complete an ongoing DMA (assuming its results are to be ignored) + Does nothing if there is no DMA in progress. + This routine waits for the current AXI transfer to complete before + terminating the current DMA. If the current transfer is hung on a DREQ used + by an uncooperative peripheral the AXI transfer may never complete. In this + case the routine times out and return a non-zero error code. + Use of this routine doesn't guarantee that the ongoing or aborted DMA + does not produce an interrupt. +*/ +extern int bcm_dma_abort(void __iomem *dma_chan_base) +{ + unsigned long int cs; + int rc = 0; + + cs = readl(dma_chan_base + BCM2708_DMA_CS); + + if (BCM2708_DMA_ACTIVE & cs) { + long int timeout = 10000; + + /* write 0 to the active bit - pause the DMA */ + writel(0, dma_chan_base + BCM2708_DMA_CS); + + /* wait for any current AXI transfer to complete */ + while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) + cs = readl(dma_chan_base + BCM2708_DMA_CS); + + if (0 != (cs & BCM2708_DMA_ISPAUSED)) { + /* we'll un-pause when we set of our next DMA */ + rc = -ETIMEDOUT; + + } else if (BCM2708_DMA_ACTIVE & cs) { + /* terminate the control block chain */ + writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); + + /* abort the whole DMA */ + writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, + dma_chan_base + BCM2708_DMA_CS); + } + } + + return rc; +} +EXPORT_SYMBOL_GPL(bcm_dma_abort); + + /* DMA Manager Device Methods */ + +static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, + u32 chans_available) +{ + dmaman->dma_base = dma_base; + dmaman->chan_available = chans_available; + dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* 2 & 3 */ + dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* 0 */ + dmaman->has_feature[BCM_DMA_FEATURE_NORMAL_ORD] = 0xfe; /* 1 to 7 */ + dmaman->has_feature[BCM_DMA_FEATURE_LITE_ORD] = 0x7f00; /* 8 to 14 */ +} + +static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, + unsigned required_feature_set) +{ + u32 chans; + int chan = 0; + int feature; + + chans = dmaman->chan_available; + for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) + /* select the subset of available channels with the desired + features */ + if (required_feature_set & (1 << feature)) + chans &= dmaman->has_feature[feature]; + + if (!chans) + return -ENOENT; + + /* return the ordinal of the first channel in the bitmap */ + while (chans != 0 && (chans & 1) == 0) { + chans >>= 1; + chan++; + } + /* claim the channel */ + dmaman->chan_available &= ~(1 << chan); + + return chan; +} + +static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) +{ + if (chan < 0) + return -EINVAL; + + if ((1 << chan) & dmaman->chan_available) + return -EIDRM; + + dmaman->chan_available |= (1 << chan); + + return 0; +} + +/* DMA Manager Monitor */ + +extern int bcm_dma_chan_alloc(unsigned required_feature_set, + void __iomem **out_dma_base, int *out_dma_irq) +{ + struct vc_dmaman *dmaman = g_dmaman; + struct platform_device *pdev = to_platform_device(dmaman_dev); + struct resource *r; + int chan; + + if (!dmaman_dev) + return -ENODEV; + + mutex_lock(&dmaman->lock); + chan = vc_dmaman_chan_alloc(dmaman, required_feature_set); + if (chan < 0) + goto out; + + r = platform_get_resource(pdev, IORESOURCE_IRQ, (unsigned int)chan); + if (!r) { + dev_err(dmaman_dev, "failed to get irq for DMA channel %d\n", + chan); + vc_dmaman_chan_free(dmaman, chan); + chan = -ENOENT; + goto out; + } + + *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, chan); + *out_dma_irq = r->start; + dev_dbg(dmaman_dev, + "Legacy API allocated channel=%d, base=%p, irq=%i\n", + chan, *out_dma_base, *out_dma_irq); + +out: + mutex_unlock(&dmaman->lock); + + return chan; +} +EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); + +extern int bcm_dma_chan_free(int channel) +{ + struct vc_dmaman *dmaman = g_dmaman; + int rc; + + if (!dmaman_dev) + return -ENODEV; + + mutex_lock(&dmaman->lock); + rc = vc_dmaman_chan_free(dmaman, channel); + mutex_unlock(&dmaman->lock); + + return rc; +} +EXPORT_SYMBOL_GPL(bcm_dma_chan_free); + +int bcm_dmaman_probe(struct platform_device *pdev, void __iomem *base, + u32 chans_available) +{ + struct device *dev = &pdev->dev; + struct vc_dmaman *dmaman; + + dmaman = devm_kzalloc(dev, sizeof(*dmaman), GFP_KERNEL); + if (!dmaman) + return -ENOMEM; + + mutex_init(&dmaman->lock); + vc_dmaman_init(dmaman, base, chans_available); + g_dmaman = dmaman; + dmaman_dev = dev; + + dev_info(dev, "DMA legacy API manager at %p, dmachans=0x%x\n", + base, chans_available); + + return 0; +} +EXPORT_SYMBOL(bcm_dmaman_probe); + +int bcm_dmaman_remove(struct platform_device *pdev) +{ + dmaman_dev = NULL; + + return 0; +} +EXPORT_SYMBOL(bcm_dmaman_remove); + +MODULE_LICENSE("GPL"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/dma/bcm2835-dma.c linux-vendor/drivers/dma/bcm2835-dma.c --- linux-4.18.16/drivers/dma/bcm2835-dma.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/dma/bcm2835-dma.c 2018-10-29 19:31:21.031758652 +0100 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ #define BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED 14 #define BCM2835_DMA_CHAN_NAME_SIZE 8 +#define BCM2835_DMA_BULK_MASK BIT(0) struct bcm2835_dmadev { struct dma_device ddev; @@ -932,6 +934,9 @@ base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) return PTR_ERR(base); + rc = bcm_dmaman_probe(pdev, base, BCM2835_DMA_BULK_MASK); + if (rc) + dev_err(&pdev->dev, "Failed to initialize the legacy API\n"); od->base = base; @@ -970,6 +975,9 @@ goto err_no_dma; } + /* Channel 0 is used by the legacy API */ + chans_available &= ~BCM2835_DMA_BULK_MASK; + /* get irqs for each channel that we support */ for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) { /* skip masked out channels */ @@ -1044,6 +1052,7 @@ { struct bcm2835_dmadev *od = platform_get_drvdata(pdev); + bcm_dmaman_remove(pdev); dma_async_device_unregister(&od->ddev); bcm2835_dma_free(od); @@ -1059,7 +1068,22 @@ }, }; -module_platform_driver(bcm2835_dma_driver); +static int bcm2835_dma_init(void) +{ + return platform_driver_register(&bcm2835_dma_driver); +} + +static void bcm2835_dma_exit(void) +{ + platform_driver_unregister(&bcm2835_dma_driver); +} + +/* + * Load after serial driver (arch_initcall) so we see the messages if it fails, + * but before drivers (module_init) that need a DMA channel. + */ +subsys_initcall(bcm2835_dma_init); +module_exit(bcm2835_dma_exit); MODULE_ALIAS("platform:bcm2835-dma"); MODULE_DESCRIPTION("BCM2835 DMA engine driver"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/dma/Kconfig linux-vendor/drivers/dma/Kconfig --- linux-4.18.16/drivers/dma/Kconfig 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/dma/Kconfig 2018-10-29 19:31:21.030758702 +0100 @@ -567,6 +567,10 @@ help Enable support for the Timberdale FPGA DMA engine. +config DMA_BCM2708 + tristate "BCM2708 DMA legacy API support" + depends on DMA_BCM2835 + config XGENE_DMA tristate "APM X-Gene DMA support" depends on ARCH_XGENE || COMPILE_TEST diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/dma/Makefile linux-vendor/drivers/dma/Makefile --- linux-4.18.16/drivers/dma/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/dma/Makefile 2018-10-29 19:31:21.030758702 +0100 @@ -21,6 +21,7 @@ obj-$(CONFIG_AXI_DMAC) += dma-axi-dmac.o obj-$(CONFIG_BCM_SBA_RAID) += bcm-sba-raid.o obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o +obj-$(CONFIG_DMA_BCM2708) += bcm2708-dmaengine.o obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o obj-$(CONFIG_DMA_JZ4780) += dma-jz4780.o diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/firmware/raspberrypi.c linux-vendor/drivers/firmware/raspberrypi.c --- linux-4.18.16/drivers/firmware/raspberrypi.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/firmware/raspberrypi.c 2018-10-29 19:31:21.059757256 +0100 @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) @@ -21,13 +23,50 @@ #define MBOX_DATA28(msg) ((msg) & ~0xf) #define MBOX_CHAN_PROPERTY 8 +#define UNDERVOLTAGE_BIT BIT(0) + + +/* + * This section defines some rate limited logging that prevent + * repeated messages at much lower Hz than the default kernel settings. + * It's usually 5s, this is 5 minutes. + * Burst 3 means you may get three messages 'quickly', before + * the ratelimiting kicks in. + */ +#define LOCAL_RATELIMIT_INTERVAL (5 * 60 * HZ) +#define LOCAL_RATELIMIT_BURST 3 + +#ifdef CONFIG_PRINTK +#define printk_ratelimited_local(fmt, ...) \ +({ \ + static DEFINE_RATELIMIT_STATE(_rs, \ + LOCAL_RATELIMIT_INTERVAL, \ + LOCAL_RATELIMIT_BURST); \ + \ + if (__ratelimit(&_rs)) \ + printk(fmt, ##__VA_ARGS__); \ +}) +#else +#define printk_ratelimited_local(fmt, ...) \ + no_printk(fmt, ##__VA_ARGS__) +#endif + +#define pr_crit_ratelimited_local(fmt, ...) \ + printk_ratelimited_local(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) +#define pr_info_ratelimited_local(fmt, ...) \ + printk_ratelimited_local(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) + + struct rpi_firmware { struct mbox_client cl; struct mbox_chan *chan; /* The property channel. */ struct completion c; u32 enabled; + struct delayed_work get_throttled_poll_work; }; +static struct platform_device *g_pdev; + static DEFINE_MUTEX(transaction_lock); static void response_callback(struct mbox_client *cl, void *msg) @@ -40,7 +79,7 @@ * Sends a request to the firmware through the BCM2835 mailbox driver, * and synchronously waits for the reply. */ -static int +int rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) { u32 message = MBOX_MSG(chan, data); @@ -61,6 +100,7 @@ return ret; } +EXPORT_SYMBOL_GPL(rpi_firmware_transaction); /** * rpi_firmware_property_list - Submit firmware property list @@ -112,7 +152,7 @@ * error, if there were multiple tags in the request. * But single-tag is the most common, so go with it. */ - dev_err(fw->cl.dev, "Request 0x%08x returned status 0x%08x\n", + dev_dbg(fw->cl.dev, "Request 0x%08x returned status 0x%08x\n", buf[2], buf[1]); ret = -EINVAL; } @@ -163,6 +203,138 @@ } EXPORT_SYMBOL_GPL(rpi_firmware_property); +static int rpi_firmware_get_throttled(struct rpi_firmware *fw, u32 *value) +{ + static int old_firmware; + static ktime_t old_timestamp; + static u32 old_value; + u32 new_sticky, old_sticky, new_uv, old_uv; + ktime_t new_timestamp; + s64 elapsed_ms; + int ret; + + if (!fw) + return -EBUSY; + + if (old_firmware) + return -EINVAL; + + /* + * We can't run faster than the sticky shift (100ms) since we get + * flipping in the sticky bits that are cleared. + * This happens on polling, so just return the previous value. + */ + new_timestamp = ktime_get(); + elapsed_ms = ktime_ms_delta(new_timestamp, old_timestamp); + if (elapsed_ms < 150) { + *value = old_value; + return 0; + } + old_timestamp = new_timestamp; + + /* Clear sticky bits */ + *value = 0xffff; + + ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_THROTTLED, + value, sizeof(*value)); + + if (ret) { + /* If the mailbox call fails once, then it will continue to + * fail in the future, so no point in continuing to call it + * Usual failure reason is older firmware + */ + old_firmware = 1; + dev_err(fw->cl.dev, "Get Throttled mailbox call failed"); + + return ret; + } + + new_sticky = *value >> 16; + old_sticky = old_value >> 16; + old_value = *value; + + /* Only notify about changes in the sticky bits */ + if (new_sticky == old_sticky) + return 0; + + new_uv = new_sticky & UNDERVOLTAGE_BIT; + old_uv = old_sticky & UNDERVOLTAGE_BIT; + + if (new_uv != old_uv) { + if (new_uv) + pr_crit_ratelimited_local( + "Under-voltage detected! (0x%08x)\n", + *value); + else + pr_info_ratelimited_local( + "Voltage normalised (0x%08x)\n", + *value); + } + + sysfs_notify(&fw->cl.dev->kobj, NULL, "get_throttled"); + + return 0; +} + +static int rpi_firmware_notify_reboot(struct notifier_block *nb, + unsigned long action, + void *data) +{ + struct rpi_firmware *fw; + struct platform_device *pdev = g_pdev; + + if (!pdev) + return 0; + + fw = platform_get_drvdata(pdev); + if (!fw) + return 0; + + (void)rpi_firmware_property(fw, RPI_FIRMWARE_NOTIFY_REBOOT, + 0, 0); + + return 0; +} + +static void get_throttled_poll(struct work_struct *work) +{ + struct rpi_firmware *fw = container_of(work, struct rpi_firmware, + get_throttled_poll_work.work); + u32 dummy; + int ret; + + ret = rpi_firmware_get_throttled(fw, &dummy); + + /* Only reschedule if we are getting valid responses */ + if (!ret) + schedule_delayed_work(&fw->get_throttled_poll_work, 2 * HZ); +} + +static ssize_t get_throttled_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct rpi_firmware *fw = dev_get_drvdata(dev); + u32 value; + int ret; + + ret = rpi_firmware_get_throttled(fw, &value); + if (ret) + return ret; + + return sprintf(buf, "%x\n", value); +} + +static DEVICE_ATTR_RO(get_throttled); + +static struct attribute *rpi_firmware_dev_attrs[] = { + &dev_attr_get_throttled.attr, + NULL, +}; + +static const struct attribute_group rpi_firmware_dev_group = { + .attrs = rpi_firmware_dev_attrs, +}; + static void rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) { @@ -187,6 +359,11 @@ { struct device *dev = &pdev->dev; struct rpi_firmware *fw; + int ret; + + ret = devm_device_add_group(dev, &rpi_firmware_dev_group); + if (ret) + return ret; fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL); if (!fw) @@ -205,11 +382,15 @@ } init_completion(&fw->c); + INIT_DELAYED_WORK(&fw->get_throttled_poll_work, get_throttled_poll); platform_set_drvdata(pdev, fw); + g_pdev = pdev; rpi_firmware_print_firmware_revision(fw); + schedule_delayed_work(&fw->get_throttled_poll_work, 0); + return 0; } @@ -217,7 +398,9 @@ { struct rpi_firmware *fw = platform_get_drvdata(pdev); + cancel_delayed_work_sync(&fw->get_throttled_poll_work); mbox_free_channel(fw->chan); + g_pdev = NULL; return 0; } @@ -230,7 +413,7 @@ */ struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node) { - struct platform_device *pdev = of_find_device_by_node(firmware_node); + struct platform_device *pdev = g_pdev; if (!pdev) return NULL; @@ -253,7 +436,35 @@ .probe = rpi_firmware_probe, .remove = rpi_firmware_remove, }; -module_platform_driver(rpi_firmware_driver); + +static struct notifier_block rpi_firmware_reboot_notifier = { + .notifier_call = rpi_firmware_notify_reboot, +}; + +static int __init rpi_firmware_init(void) +{ + int ret = register_reboot_notifier(&rpi_firmware_reboot_notifier); + if (ret) + goto out1; + ret = platform_driver_register(&rpi_firmware_driver); + if (ret) + goto out2; + + return 0; + +out2: + unregister_reboot_notifier(&rpi_firmware_reboot_notifier); +out1: + return ret; +} +subsys_initcall(rpi_firmware_init); + +static void __init rpi_firmware_exit(void) +{ + platform_driver_unregister(&rpi_firmware_driver); + unregister_reboot_notifier(&rpi_firmware_reboot_notifier); +} +module_exit(rpi_firmware_exit); MODULE_AUTHOR("Eric Anholt "); MODULE_DESCRIPTION("Raspberry Pi firmware driver"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/gpio/gpio-bcm-virt.c linux-vendor/drivers/gpio/gpio-bcm-virt.c --- linux-4.18.16/drivers/gpio/gpio-bcm-virt.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/gpio/gpio-bcm-virt.c 2018-10-29 19:31:21.075756458 +0100 @@ -0,0 +1,214 @@ +/* + * brcmvirt GPIO driver + * + * Copyright (C) 2012,2013 Dom Cobley + * Based on gpio-clps711x.c by Alexander Shiyan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +#define MODULE_NAME "brcmvirt-gpio" +#define NUM_GPIO 2 + +struct brcmvirt_gpio { + struct gpio_chip gc; + u32 __iomem *ts_base; + /* two packed 16-bit counts of enabled and disables + Allows host to detect a brief enable that was missed */ + u32 enables_disables[NUM_GPIO]; + dma_addr_t bus_addr; +}; + +static int brcmvirt_gpio_dir_in(struct gpio_chip *gc, unsigned off) +{ + struct brcmvirt_gpio *gpio; + gpio = container_of(gc, struct brcmvirt_gpio, gc); + return -EINVAL; +} + +static int brcmvirt_gpio_dir_out(struct gpio_chip *gc, unsigned off, int val) +{ + struct brcmvirt_gpio *gpio; + gpio = container_of(gc, struct brcmvirt_gpio, gc); + return 0; +} + +static int brcmvirt_gpio_get(struct gpio_chip *gc, unsigned off) +{ + struct brcmvirt_gpio *gpio; + unsigned v; + gpio = container_of(gc, struct brcmvirt_gpio, gc); + v = readl(gpio->ts_base + off); + return (v >> off) & 1; +} + +static void brcmvirt_gpio_set(struct gpio_chip *gc, unsigned off, int val) +{ + struct brcmvirt_gpio *gpio; + u16 enables, disables; + s16 diff; + bool lit; + gpio = container_of(gc, struct brcmvirt_gpio, gc); + enables = gpio->enables_disables[off] >> 16; + disables = gpio->enables_disables[off] >> 0; + diff = (s16)(enables - disables); + lit = diff > 0; + if ((val && lit) || (!val && !lit)) + return; + if (val) + enables++; + else + disables++; + diff = (s16)(enables - disables); + BUG_ON(diff != 0 && diff != 1); + gpio->enables_disables[off] = (enables << 16) | (disables << 0); + writel(gpio->enables_disables[off], gpio->ts_base + off); +} + +static int brcmvirt_gpio_probe(struct platform_device *pdev) +{ + int err = 0; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *fw_node; + struct rpi_firmware *fw; + struct brcmvirt_gpio *ucb; + u32 gpiovirtbuf; + + fw_node = of_parse_phandle(np, "firmware", 0); + if (!fw_node) { + dev_err(dev, "Missing firmware node\n"); + return -ENOENT; + } + + fw = rpi_firmware_get(fw_node); + if (!fw) + return -EPROBE_DEFER; + + ucb = devm_kzalloc(dev, sizeof *ucb, GFP_KERNEL); + if (!ucb) { + err = -EINVAL; + goto out; + } + + ucb->ts_base = dma_zalloc_coherent(dev, PAGE_SIZE, &ucb->bus_addr, GFP_KERNEL); + if (!ucb->ts_base) { + pr_err("[%s]: failed to dma_alloc_coherent(%ld)\n", + __func__, PAGE_SIZE); + err = -ENOMEM; + goto out; + } + + gpiovirtbuf = (u32)ucb->bus_addr; + err = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF, + &gpiovirtbuf, sizeof(gpiovirtbuf)); + + if (err || gpiovirtbuf != 0) { + dev_warn(dev, "Failed to set gpiovirtbuf, trying to get err:%x\n", err); + dma_free_coherent(dev, PAGE_SIZE, ucb->ts_base, ucb->bus_addr); + ucb->ts_base = 0; + ucb->bus_addr = 0; + } + + if (!ucb->ts_base) { + err = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF, + &gpiovirtbuf, sizeof(gpiovirtbuf)); + + if (err) { + dev_err(dev, "Failed to get gpiovirtbuf\n"); + goto out; + } + + if (!gpiovirtbuf) { + dev_err(dev, "No virtgpio buffer\n"); + err = -ENOENT; + goto out; + } + + // mmap the physical memory + gpiovirtbuf &= ~0xc0000000; + ucb->ts_base = ioremap(gpiovirtbuf, 4096); + if (ucb->ts_base == NULL) { + dev_err(dev, "Failed to map physical address\n"); + err = -ENOENT; + goto out; + } + ucb->bus_addr = 0; + } + ucb->gc.label = MODULE_NAME; + ucb->gc.owner = THIS_MODULE; + //ucb->gc.dev = dev; + ucb->gc.of_node = np; + ucb->gc.base = 100; + ucb->gc.ngpio = NUM_GPIO; + + ucb->gc.direction_input = brcmvirt_gpio_dir_in; + ucb->gc.direction_output = brcmvirt_gpio_dir_out; + ucb->gc.get = brcmvirt_gpio_get; + ucb->gc.set = brcmvirt_gpio_set; + ucb->gc.can_sleep = true; + + err = gpiochip_add(&ucb->gc); + if (err) + goto out; + + platform_set_drvdata(pdev, ucb); + + return 0; +out: + if (ucb->bus_addr) { + dma_free_coherent(dev, PAGE_SIZE, ucb->ts_base, ucb->bus_addr); + ucb->bus_addr = 0; + ucb->ts_base = NULL; + } else if (ucb->ts_base) { + iounmap(ucb->ts_base); + ucb->ts_base = NULL; + } + return err; +} + +static int brcmvirt_gpio_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + int err = 0; + struct brcmvirt_gpio *ucb = platform_get_drvdata(pdev); + + gpiochip_remove(&ucb->gc); + if (ucb->bus_addr) + dma_free_coherent(dev, PAGE_SIZE, ucb->ts_base, ucb->bus_addr); + else if (ucb->ts_base) + iounmap(ucb->ts_base); + return err; +} + +static const struct of_device_id __maybe_unused brcmvirt_gpio_ids[] = { + { .compatible = "brcm,bcm2835-virtgpio" }, + { } +}; +MODULE_DEVICE_TABLE(of, brcmvirt_gpio_ids); + +static struct platform_driver brcmvirt_gpio_driver = { + .driver = { + .name = MODULE_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(brcmvirt_gpio_ids), + }, + .probe = brcmvirt_gpio_probe, + .remove = brcmvirt_gpio_remove, +}; +module_platform_driver(brcmvirt_gpio_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Dom Cobley "); +MODULE_DESCRIPTION("brcmvirt GPIO driver"); +MODULE_ALIAS("platform:brcmvirt-gpio"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/gpio/gpiolib.c linux-vendor/drivers/gpio/gpiolib.c --- linux-4.18.16/drivers/gpio/gpiolib.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/gpio/gpiolib.c 2018-10-29 19:31:21.092755610 +0100 @@ -53,6 +53,8 @@ #define extra_checks 0 #endif +#define dont_test_bit(b,d) (0) + /* Device and char device-related information */ static DEFINE_IDA(gpio_ida); static dev_t gpio_devt; @@ -2592,7 +2594,7 @@ value = !!value; /* GPIOs used for IRQs shall not be set as output */ - if (test_bit(FLAG_USED_AS_IRQ, &desc->flags)) { + if (dont_test_bit(FLAG_USED_AS_IRQ, &desc->flags)) { gpiod_err(desc, "%s: tried to set a GPIO tied to an IRQ as output\n", __func__); @@ -3257,7 +3259,7 @@ set_bit(FLAG_IS_OUT, &desc->flags); } - if (test_bit(FLAG_IS_OUT, &desc->flags)) { + if (dont_test_bit(FLAG_IS_OUT, &desc->flags)) { chip_err(chip, "%s: tried to flag a GPIO set as output for IRQ\n", __func__); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/gpio/Kconfig linux-vendor/drivers/gpio/Kconfig --- linux-4.18.16/drivers/gpio/Kconfig 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/gpio/Kconfig 2018-10-29 19:31:21.073756558 +0100 @@ -151,6 +151,12 @@ help Turn on GPIO support for Broadcom "Kona" chips. +config GPIO_BCM_VIRT + bool "Broadcom Virt GPIO" + depends on OF_GPIO && RASPBERRYPI_FIRMWARE && (ARCH_BCM2835 || COMPILE_TEST) + help + Turn on virtual GPIO support for Broadcom BCM283X chips. + config GPIO_BRCMSTB tristate "BRCMSTB GPIO support" default y if (ARCH_BRCMSTB || BMIPS_GENERIC) diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/gpio/Makefile linux-vendor/drivers/gpio/Makefile --- linux-4.18.16/drivers/gpio/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/gpio/Makefile 2018-10-29 19:31:21.073756558 +0100 @@ -35,6 +35,7 @@ obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o +obj-$(CONFIG_GPIO_BCM_VIRT) += gpio-bcm-virt.o obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/gpu/drm/vc4/Makefile linux-vendor/drivers/gpu/drm/vc4/Makefile --- linux-4.18.16/drivers/gpu/drm/vc4/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/gpu/drm/vc4/Makefile 2018-10-29 19:31:21.257747378 +0100 @@ -9,6 +9,7 @@ vc4_dpi.o \ vc4_dsi.o \ vc4_fence.o \ + vc4_firmware_kms.o \ vc4_kms.o \ vc4_gem.o \ vc4_hdmi.o \ diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/gpu/drm/vc4/vc4_crtc.c linux-vendor/drivers/gpu/drm/vc4/vc4_crtc.c --- linux-4.18.16/drivers/gpu/drm/vc4/vc4_crtc.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/gpu/drm/vc4/vc4_crtc.c 2018-10-29 19:31:21.258747328 +0100 @@ -131,6 +131,9 @@ int vblank_lines; bool ret = false; + if (vc4->firmware_kms) + return 0; + /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ /* Get optional system timestamp before query. */ diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/gpu/drm/vc4/vc4_drv.c linux-vendor/drivers/gpu/drm/vc4/vc4_drv.c --- linux-4.18.16/drivers/gpu/drm/vc4/vc4_drv.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/gpu/drm/vc4/vc4_drv.c 2018-10-29 19:31:21.258747328 +0100 @@ -346,6 +346,7 @@ &vc4_dsi_driver, &vc4_hvs_driver, &vc4_crtc_driver, + &vc4_firmware_kms_driver, &vc4_v3d_driver, }; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/gpu/drm/vc4/vc4_drv.h linux-vendor/drivers/gpu/drm/vc4/vc4_drv.h --- linux-4.18.16/drivers/gpu/drm/vc4/vc4_drv.h 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/gpu/drm/vc4/vc4_drv.h 2018-10-29 19:31:21.259747278 +0100 @@ -66,6 +66,9 @@ struct vc4_dev { struct drm_device *dev; + bool firmware_kms; + struct rpi_firmware *firmware; + struct vc4_hdmi *hdmi; struct vc4_hvs *hvs; struct vc4_v3d *v3d; @@ -715,6 +718,10 @@ /* vc4_fence.c */ extern const struct dma_fence_ops vc4_fence_ops; +/* vc4_firmware_kms.c */ +extern struct platform_driver vc4_firmware_kms_driver; +void vc4_fkms_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file); + /* vc4_gem.c */ void vc4_gem_init(struct drm_device *dev); void vc4_gem_destroy(struct drm_device *dev); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/gpu/drm/vc4/vc4_firmware_kms.c linux-vendor/drivers/gpu/drm/vc4/vc4_firmware_kms.c --- linux-4.18.16/drivers/gpu/drm/vc4/vc4_firmware_kms.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/gpu/drm/vc4/vc4_firmware_kms.c 2018-10-29 19:31:21.260747228 +0100 @@ -0,0 +1,772 @@ +/* + * Copyright (C) 2016 Broadcom + * + * 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. + */ + +/** + * DOC: VC4 firmware KMS module. + * + * As a hack to get us from the current closed source driver world + * toward a totally open stack, implement KMS on top of the Raspberry + * Pi's firmware display stack. + */ + +#include "drm/drm_atomic_helper.h" +#include "drm/drm_plane_helper.h" +#include "drm/drm_crtc_helper.h" +#include "drm/drm_fourcc.h" +#include "linux/clk.h" +#include "linux/debugfs.h" +#include "drm/drm_fb_cma_helper.h" +#include "linux/component.h" +#include "linux/of_device.h" +#include "vc4_drv.h" +#include "vc4_regs.h" +#include + +/* The firmware delivers a vblank interrupt to us through the SMI + * hardware, which has only this one register. + */ +#define SMICS 0x0 +#define SMICS_INTERRUPTS (BIT(9) | BIT(10) | BIT(11)) + +#define vc4_crtc vc4_kms_crtc +#define to_vc4_crtc to_vc4_kms_crtc +struct vc4_crtc { + struct drm_crtc base; + struct drm_encoder *encoder; + struct drm_connector *connector; + void __iomem *regs; + + struct drm_pending_vblank_event *event; + u32 overscan[4]; + bool vblank_enabled; +}; + +static inline struct vc4_crtc *to_vc4_crtc(struct drm_crtc *crtc) +{ + return container_of(crtc, struct vc4_crtc, base); +} + +struct vc4_fkms_encoder { + struct drm_encoder base; +}; + +static inline struct vc4_fkms_encoder * +to_vc4_fkms_encoder(struct drm_encoder *encoder) +{ + return container_of(encoder, struct vc4_fkms_encoder, base); +} + +/* VC4 FKMS connector KMS struct */ +struct vc4_fkms_connector { + struct drm_connector base; + + /* Since the connector is attached to just the one encoder, + * this is the reference to it so we can do the best_encoder() + * hook. + */ + struct drm_encoder *encoder; +}; + +static inline struct vc4_fkms_connector * +to_vc4_fkms_connector(struct drm_connector *connector) +{ + return container_of(connector, struct vc4_fkms_connector, base); +} + +/* Firmware's structure for making an FB mbox call. */ +struct fbinfo_s { + u32 xres, yres, xres_virtual, yres_virtual; + u32 pitch, bpp; + u32 xoffset, yoffset; + u32 base; + u32 screen_size; + u16 cmap[256]; +}; + +struct vc4_fkms_plane { + struct drm_plane base; + struct fbinfo_s *fbinfo; + dma_addr_t fbinfo_bus_addr; + u32 pitch; +}; + +static inline struct vc4_fkms_plane *to_vc4_fkms_plane(struct drm_plane *plane) +{ + return (struct vc4_fkms_plane *)plane; +} + +/* Turns the display on/off. */ +static int vc4_plane_set_primary_blank(struct drm_plane *plane, bool blank) +{ + struct vc4_dev *vc4 = to_vc4_dev(plane->dev); + + u32 packet = blank; + + DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary plane %s", + plane->base.id, plane->name, + blank ? "blank" : "unblank"); + + return rpi_firmware_property(vc4->firmware, + RPI_FIRMWARE_FRAMEBUFFER_BLANK, + &packet, sizeof(packet)); +} + +static void vc4_primary_plane_atomic_update(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ + struct vc4_dev *vc4 = to_vc4_dev(plane->dev); + struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); + struct drm_plane_state *state = plane->state; + struct drm_framebuffer *fb = state->fb; + struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); + volatile struct fbinfo_s *fbinfo = vc4_plane->fbinfo; + u32 bpp = 32; + int ret; + + fbinfo->xres = state->crtc_w; + fbinfo->yres = state->crtc_h; + fbinfo->xres_virtual = state->crtc_w; + fbinfo->yres_virtual = state->crtc_h; + fbinfo->bpp = bpp; + fbinfo->xoffset = state->crtc_x; + fbinfo->yoffset = state->crtc_y; + fbinfo->base = bo->paddr + fb->offsets[0]; + fbinfo->pitch = fb->pitches[0]; + + if (fb->modifier == DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED) + fbinfo->bpp |= BIT(31); + + /* A bug in the firmware makes it so that if the fb->base is + * set to nonzero, the configured pitch gets overwritten with + * the previous pitch. So, to get the configured pitch + * recomputed, we have to make it allocate itself a new buffer + * in VC memory, first. + */ + if (vc4_plane->pitch != fb->pitches[0]) { + u32 saved_base = fbinfo->base; + fbinfo->base = 0; + + ret = rpi_firmware_transaction(vc4->firmware, + RPI_FIRMWARE_CHAN_FB, + vc4_plane->fbinfo_bus_addr); + fbinfo->base = saved_base; + + vc4_plane->pitch = fbinfo->pitch; + WARN_ON_ONCE(vc4_plane->pitch != fb->pitches[0]); + } + + DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary update %dx%d@%d +%d,%d 0x%08x/%d\n", + plane->base.id, plane->name, + state->crtc_w, + state->crtc_h, + bpp, + state->crtc_x, + state->crtc_y, + bo->paddr + fb->offsets[0], + fb->pitches[0]); + + ret = rpi_firmware_transaction(vc4->firmware, + RPI_FIRMWARE_CHAN_FB, + vc4_plane->fbinfo_bus_addr); + WARN_ON_ONCE(fbinfo->pitch != fb->pitches[0]); + WARN_ON_ONCE(fbinfo->base != bo->paddr + fb->offsets[0]); + + /* If the CRTC is on (or going to be on) and we're enabled, + * then unblank. Otherwise, stay blank until CRTC enable. + */ + if (state->crtc->state->active) + vc4_plane_set_primary_blank(plane, false); +} + +static void vc4_primary_plane_atomic_disable(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ + vc4_plane_set_primary_blank(plane, true); +} + +static void vc4_cursor_plane_atomic_update(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ + struct vc4_dev *vc4 = to_vc4_dev(plane->dev); + struct vc4_crtc *vc4_crtc = to_vc4_crtc(plane->crtc); + struct drm_plane_state *state = plane->state; + struct drm_framebuffer *fb = state->fb; + struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); + int ret; + u32 packet_state[] = { + state->crtc->state->active, + state->crtc_x, + state->crtc_y, + 0 + }; + WARN_ON_ONCE(fb->pitches[0] != state->crtc_w * 4); + + DRM_DEBUG_ATOMIC("[PLANE:%d:%s] update %dx%d cursor at %d,%d (0x%08x/%d)", + plane->base.id, plane->name, + state->crtc_w, + state->crtc_h, + state->crtc_x, + state->crtc_y, + bo->paddr + fb->offsets[0], + fb->pitches[0]); + + /* add on the top/left offsets when overscan is active */ + if (vc4_crtc) { + packet_state[1] += vc4_crtc->overscan[0]; + packet_state[2] += vc4_crtc->overscan[1]; + } + + ret = rpi_firmware_property(vc4->firmware, + RPI_FIRMWARE_SET_CURSOR_STATE, + &packet_state, + sizeof(packet_state)); + if (ret || packet_state[0] != 0) + DRM_ERROR("Failed to set cursor state: 0x%08x\n", packet_state[0]); + + /* Note: When the cursor contents change, the modesetting + * driver calls drm_mode_cursor_univeral() with + * DRM_MODE_CURSOR_BO, which means a new fb will be allocated. + */ + if (!old_state || + state->crtc_w != old_state->crtc_w || + state->crtc_h != old_state->crtc_h || + fb != old_state->fb) { + u32 packet_info[] = { state->crtc_w, state->crtc_h, + 0, /* unused */ + bo->paddr + fb->offsets[0], + 0, 0, /* hotx, hoty */}; + + ret = rpi_firmware_property(vc4->firmware, + RPI_FIRMWARE_SET_CURSOR_INFO, + &packet_info, + sizeof(packet_info)); + if (ret || packet_info[0] != 0) + DRM_ERROR("Failed to set cursor info: 0x%08x\n", packet_info[0]); + } +} + +static void vc4_cursor_plane_atomic_disable(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ + struct vc4_dev *vc4 = to_vc4_dev(plane->dev); + u32 packet_state[] = { false, 0, 0, 0 }; + int ret; + + DRM_DEBUG_ATOMIC("[PLANE:%d:%s] disabling cursor", plane->base.id, plane->name); + + ret = rpi_firmware_property(vc4->firmware, + RPI_FIRMWARE_SET_CURSOR_STATE, + &packet_state, + sizeof(packet_state)); + if (ret || packet_state[0] != 0) + DRM_ERROR("Failed to set cursor state: 0x%08x\n", packet_state[0]); +} + +static int vc4_plane_atomic_check(struct drm_plane *plane, + struct drm_plane_state *state) +{ + return 0; +} + +static void vc4_plane_destroy(struct drm_plane *plane) +{ + drm_plane_helper_disable(plane); + drm_plane_cleanup(plane); +} + +static const struct drm_plane_funcs vc4_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy = vc4_plane_destroy, + .set_property = NULL, + .reset = drm_atomic_helper_plane_reset, + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, +}; + +static const struct drm_plane_helper_funcs vc4_primary_plane_helper_funcs = { + .prepare_fb = NULL, + .cleanup_fb = NULL, + .atomic_check = vc4_plane_atomic_check, + .atomic_update = vc4_primary_plane_atomic_update, + .atomic_disable = vc4_primary_plane_atomic_disable, +}; + +static const struct drm_plane_helper_funcs vc4_cursor_plane_helper_funcs = { + .prepare_fb = NULL, + .cleanup_fb = NULL, + .atomic_check = vc4_plane_atomic_check, + .atomic_update = vc4_cursor_plane_atomic_update, + .atomic_disable = vc4_cursor_plane_atomic_disable, +}; + +static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev, + enum drm_plane_type type) +{ + struct drm_plane *plane = NULL; + struct vc4_fkms_plane *vc4_plane; + u32 xrgb8888 = DRM_FORMAT_XRGB8888; + u32 argb8888 = DRM_FORMAT_ARGB8888; + int ret = 0; + bool primary = (type == DRM_PLANE_TYPE_PRIMARY); + + vc4_plane = devm_kzalloc(dev->dev, sizeof(*vc4_plane), + GFP_KERNEL); + if (!vc4_plane) { + ret = -ENOMEM; + goto fail; + } + + plane = &vc4_plane->base; + ret = drm_universal_plane_init(dev, plane, 0xff, + &vc4_plane_funcs, + primary ? &xrgb8888 : &argb8888, 1, NULL, + type, primary ? "primary" : "cursor"); + + if (type == DRM_PLANE_TYPE_PRIMARY) { + vc4_plane->fbinfo = + dma_alloc_coherent(dev->dev, + sizeof(*vc4_plane->fbinfo), + &vc4_plane->fbinfo_bus_addr, + GFP_KERNEL); + memset(vc4_plane->fbinfo, 0, sizeof(*vc4_plane->fbinfo)); + + drm_plane_helper_add(plane, &vc4_primary_plane_helper_funcs); + } else { + drm_plane_helper_add(plane, &vc4_cursor_plane_helper_funcs); + } + + return plane; +fail: + if (plane) + vc4_plane_destroy(plane); + + return ERR_PTR(ret); +} + +static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc) +{ + /* Everyting is handled in the planes. */ +} + +static void vc4_crtc_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) +{ + /* Always turn the planes off on CRTC disable. In DRM, planes + * are enabled/disabled through the update/disable hooks + * above, and the CRTC enable/disable independently controls + * whether anything scans out at all, but the firmware doesn't + * give us a CRTC-level control for that. + */ + vc4_cursor_plane_atomic_disable(crtc->cursor, crtc->cursor->state); + vc4_plane_set_primary_blank(crtc->primary, true); +} + +static void vc4_crtc_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) +{ + /* Unblank the planes (if they're supposed to be displayed). */ + if (crtc->primary->state->fb) + vc4_plane_set_primary_blank(crtc->primary, false); + if (crtc->cursor->state->fb) { + vc4_cursor_plane_atomic_update(crtc->cursor, + crtc->cursor->state); + } +} + +static int vc4_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + return 0; +} + +static void vc4_crtc_atomic_flush(struct drm_crtc *crtc, + struct drm_crtc_state *old_state) +{ + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + struct drm_device *dev = crtc->dev; + + if (crtc->state->event) { + unsigned long flags; + + crtc->state->event->pipe = drm_crtc_index(crtc); + + WARN_ON(drm_crtc_vblank_get(crtc) != 0); + + spin_lock_irqsave(&dev->event_lock, flags); + vc4_crtc->event = crtc->state->event; + crtc->state->event = NULL; + spin_unlock_irqrestore(&dev->event_lock, flags); + } +} + +static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc) +{ + struct drm_crtc *crtc = &vc4_crtc->base; + struct drm_device *dev = crtc->dev; + unsigned long flags; + + spin_lock_irqsave(&dev->event_lock, flags); + if (vc4_crtc->event) { + drm_crtc_send_vblank_event(crtc, vc4_crtc->event); + vc4_crtc->event = NULL; + drm_crtc_vblank_put(crtc); + } + spin_unlock_irqrestore(&dev->event_lock, flags); +} + +static irqreturn_t vc4_crtc_irq_handler(int irq, void *data) +{ + struct vc4_crtc *vc4_crtc = data; + u32 stat = readl(vc4_crtc->regs + SMICS); + irqreturn_t ret = IRQ_NONE; + + if (stat & SMICS_INTERRUPTS) { + writel(0, vc4_crtc->regs + SMICS); + if (vc4_crtc->vblank_enabled) + drm_crtc_handle_vblank(&vc4_crtc->base); + vc4_crtc_handle_page_flip(vc4_crtc); + ret = IRQ_HANDLED; + } + + return ret; +} + +static int vc4_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t flags, struct drm_modeset_acquire_ctx *ctx) +{ + if (flags & DRM_MODE_PAGE_FLIP_ASYNC) { + DRM_ERROR("Async flips aren't allowed\n"); + return -EINVAL; + } + + return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx); +} + +static int vc4_fkms_enable_vblank(struct drm_crtc *crtc) +{ + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + + vc4_crtc->vblank_enabled = true; + + return 0; +} + +static void vc4_fkms_disable_vblank(struct drm_crtc *crtc) +{ +} + +static const struct drm_crtc_funcs vc4_crtc_funcs = { + .set_config = drm_atomic_helper_set_config, + .destroy = drm_crtc_cleanup, + .page_flip = vc4_page_flip, + .set_property = NULL, + .cursor_set = NULL, /* handled by drm_mode_cursor_universal */ + .cursor_move = NULL, /* handled by drm_mode_cursor_universal */ + .reset = drm_atomic_helper_crtc_reset, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, + .enable_vblank = vc4_fkms_enable_vblank, + .disable_vblank = vc4_fkms_disable_vblank, +}; + +static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = { + .mode_set_nofb = vc4_crtc_mode_set_nofb, + .atomic_disable = vc4_crtc_disable, + .atomic_enable = vc4_crtc_enable, + .atomic_check = vc4_crtc_atomic_check, + .atomic_flush = vc4_crtc_atomic_flush, +}; + +/* Frees the page flip event when the DRM device is closed with the + * event still outstanding. + */ +void vc4_fkms_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) +{ + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + struct drm_device *dev = crtc->dev; + unsigned long flags; + + spin_lock_irqsave(&dev->event_lock, flags); + + if (vc4_crtc->event && vc4_crtc->event->base.file_priv == file) { + kfree(&vc4_crtc->event->base); + drm_crtc_vblank_put(crtc); + vc4_crtc->event = NULL; + } + + spin_unlock_irqrestore(&dev->event_lock, flags); +} + +static const struct of_device_id vc4_firmware_kms_dt_match[] = { + { .compatible = "raspberrypi,rpi-firmware-kms" }, + {} +}; + +static enum drm_connector_status +vc4_fkms_connector_detect(struct drm_connector *connector, bool force) +{ + return connector_status_connected; +} + +static int vc4_fkms_connector_get_modes(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct vc4_dev *vc4 = to_vc4_dev(dev); + u32 wh[2] = {0, 0}; + int ret; + struct drm_display_mode *mode; + + ret = rpi_firmware_property(vc4->firmware, + RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT, + &wh, sizeof(wh)); + if (ret) { + DRM_ERROR("Failed to get screen size: %d (0x%08x 0x%08x)\n", + ret, wh[0], wh[1]); + return 0; + } + + mode = drm_cvt_mode(dev, wh[0], wh[1], 60 /* vrefresh */, + 0, 0, false); + drm_mode_probed_add(connector, mode); + + return 1; +} + +static struct drm_encoder * +vc4_fkms_connector_best_encoder(struct drm_connector *connector) +{ + struct vc4_fkms_connector *fkms_connector = + to_vc4_fkms_connector(connector); + return fkms_connector->encoder; +} + +static void vc4_fkms_connector_destroy(struct drm_connector *connector) +{ + drm_connector_unregister(connector); + drm_connector_cleanup(connector); +} + +static const struct drm_connector_funcs vc4_fkms_connector_funcs = { + .detect = vc4_fkms_connector_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = vc4_fkms_connector_destroy, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static const struct drm_connector_helper_funcs vc4_fkms_connector_helper_funcs = { + .get_modes = vc4_fkms_connector_get_modes, + .best_encoder = vc4_fkms_connector_best_encoder, +}; + +static struct drm_connector *vc4_fkms_connector_init(struct drm_device *dev, + struct drm_encoder *encoder) +{ + struct drm_connector *connector = NULL; + struct vc4_fkms_connector *fkms_connector; + int ret = 0; + + fkms_connector = devm_kzalloc(dev->dev, sizeof(*fkms_connector), + GFP_KERNEL); + if (!fkms_connector) { + ret = -ENOMEM; + goto fail; + } + connector = &fkms_connector->base; + + fkms_connector->encoder = encoder; + + drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA); + drm_connector_helper_add(connector, &vc4_fkms_connector_helper_funcs); + + connector->polled = (DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT); + + connector->interlace_allowed = 0; + connector->doublescan_allowed = 0; + + drm_mode_connector_attach_encoder(connector, encoder); + + return connector; + + fail: + if (connector) + vc4_fkms_connector_destroy(connector); + + return ERR_PTR(ret); +} + +static void vc4_fkms_encoder_destroy(struct drm_encoder *encoder) +{ + drm_encoder_cleanup(encoder); +} + +static const struct drm_encoder_funcs vc4_fkms_encoder_funcs = { + .destroy = vc4_fkms_encoder_destroy, +}; + +static void vc4_fkms_encoder_enable(struct drm_encoder *encoder) +{ +} + +static void vc4_fkms_encoder_disable(struct drm_encoder *encoder) +{ +} + +static const struct drm_encoder_helper_funcs vc4_fkms_encoder_helper_funcs = { + .enable = vc4_fkms_encoder_enable, + .disable = vc4_fkms_encoder_disable, +}; + +static int vc4_fkms_bind(struct device *dev, struct device *master, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct drm_device *drm = dev_get_drvdata(master); + struct vc4_dev *vc4 = to_vc4_dev(drm); + struct vc4_crtc *vc4_crtc; + struct vc4_fkms_encoder *vc4_encoder; + struct drm_crtc *crtc; + struct drm_plane *primary_plane, *cursor_plane, *destroy_plane, *temp; + struct device_node *firmware_node; + int ret; + + vc4->firmware_kms = true; + + vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL); + if (!vc4_crtc) + return -ENOMEM; + crtc = &vc4_crtc->base; + + firmware_node = of_parse_phandle(dev->of_node, "brcm,firmware", 0); + vc4->firmware = rpi_firmware_get(firmware_node); + if (!vc4->firmware) { + DRM_DEBUG("Failed to get Raspberry Pi firmware reference.\n"); + return -EPROBE_DEFER; + } + of_node_put(firmware_node); + + /* Map the SMI interrupt reg */ + vc4_crtc->regs = vc4_ioremap_regs(pdev, 0); + if (IS_ERR(vc4_crtc->regs)) + return PTR_ERR(vc4_crtc->regs); + + /* For now, we create just the primary and the legacy cursor + * planes. We should be able to stack more planes on easily, + * but to do that we would need to compute the bandwidth + * requirement of the plane configuration, and reject ones + * that will take too much. + */ + primary_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_PRIMARY); + if (IS_ERR(primary_plane)) { + dev_err(dev, "failed to construct primary plane\n"); + ret = PTR_ERR(primary_plane); + goto err; + } + + cursor_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_CURSOR); + if (IS_ERR(cursor_plane)) { + dev_err(dev, "failed to construct cursor plane\n"); + ret = PTR_ERR(cursor_plane); + goto err; + } + + drm_crtc_init_with_planes(drm, crtc, primary_plane, cursor_plane, + &vc4_crtc_funcs, NULL); + drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs); + primary_plane->crtc = crtc; + cursor_plane->crtc = crtc; + + vc4_encoder = devm_kzalloc(dev, sizeof(*vc4_encoder), GFP_KERNEL); + if (!vc4_encoder) + return -ENOMEM; + vc4_crtc->encoder = &vc4_encoder->base; + vc4_encoder->base.possible_crtcs |= drm_crtc_mask(crtc) ; + drm_encoder_init(drm, &vc4_encoder->base, &vc4_fkms_encoder_funcs, + DRM_MODE_ENCODER_TMDS, NULL); + drm_encoder_helper_add(&vc4_encoder->base, + &vc4_fkms_encoder_helper_funcs); + + vc4_crtc->connector = vc4_fkms_connector_init(drm, &vc4_encoder->base); + if (IS_ERR(vc4_crtc->connector)) { + ret = PTR_ERR(vc4_crtc->connector); + goto err_destroy_encoder; + } + + writel(0, vc4_crtc->regs + SMICS); + ret = devm_request_irq(dev, platform_get_irq(pdev, 0), + vc4_crtc_irq_handler, 0, "vc4 firmware kms", + vc4_crtc); + if (ret) + goto err_destroy_connector; + + ret = rpi_firmware_property(vc4->firmware, + RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN, + &vc4_crtc->overscan, + sizeof(vc4_crtc->overscan)); + if (ret) { + DRM_ERROR("Failed to get overscan state: 0x%08x\n", vc4_crtc->overscan[0]); + memset(&vc4_crtc->overscan, 0, sizeof(vc4_crtc->overscan)); + } + + platform_set_drvdata(pdev, vc4_crtc); + + return 0; + +err_destroy_connector: + vc4_fkms_connector_destroy(vc4_crtc->connector); +err_destroy_encoder: + vc4_fkms_encoder_destroy(vc4_crtc->encoder); + list_for_each_entry_safe(destroy_plane, temp, + &drm->mode_config.plane_list, head) { + if (destroy_plane->possible_crtcs == 1 << drm_crtc_index(crtc)) + destroy_plane->funcs->destroy(destroy_plane); + } +err: + return ret; +} + +static void vc4_fkms_unbind(struct device *dev, struct device *master, + void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct vc4_crtc *vc4_crtc = dev_get_drvdata(dev); + + vc4_fkms_connector_destroy(vc4_crtc->connector); + vc4_fkms_encoder_destroy(vc4_crtc->encoder); + drm_crtc_cleanup(&vc4_crtc->base); + + platform_set_drvdata(pdev, NULL); +} + +static const struct component_ops vc4_fkms_ops = { + .bind = vc4_fkms_bind, + .unbind = vc4_fkms_unbind, +}; + +static int vc4_fkms_probe(struct platform_device *pdev) +{ + return component_add(&pdev->dev, &vc4_fkms_ops); +} + +static int vc4_fkms_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &vc4_fkms_ops); + return 0; +} + +struct platform_driver vc4_firmware_kms_driver = { + .probe = vc4_fkms_probe, + .remove = vc4_fkms_remove, + .driver = { + .name = "vc4_firmware_kms", + .of_match_table = vc4_firmware_kms_dt_match, + }, +}; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/gpu/drm/vc4/vc4_kms.c linux-vendor/drivers/gpu/drm/vc4/vc4_kms.c --- linux-4.18.16/drivers/gpu/drm/vc4/vc4_kms.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/gpu/drm/vc4/vc4_kms.c 2018-10-29 19:31:21.261747178 +0100 @@ -160,7 +160,8 @@ * display lists before we free it and potentially reallocate * and overwrite the dlist memory with a new modeset. */ - state->legacy_cursor_update = false; + if (!vc4->firmware_kms) + state->legacy_cursor_update = false; drm_atomic_helper_commit_hw_done(state); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/hid/usbhid/hid-core.c linux-vendor/drivers/hid/usbhid/hid-core.c --- linux-4.18.16/drivers/hid/usbhid/hid-core.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/hid/usbhid/hid-core.c 2018-10-29 19:31:21.279746280 +0100 @@ -48,7 +48,7 @@ * Module parameters. */ -static unsigned int hid_mousepoll_interval; +static unsigned int hid_mousepoll_interval = ~0; module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); @@ -1103,7 +1103,9 @@ */ switch (hid->collection->usage) { case HID_GD_MOUSE: - if (hid_mousepoll_interval > 0) + if (hid_mousepoll_interval == ~0 && interval < 16) + interval = 16; + else if (hid_mousepoll_interval != ~0 && hid_mousepoll_interval != 0) interval = hid_mousepoll_interval; break; case HID_GD_JOYSTICK: diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/hwmon/Kconfig linux-vendor/drivers/hwmon/Kconfig --- linux-4.18.16/drivers/hwmon/Kconfig 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/hwmon/Kconfig 2018-10-29 19:31:21.285745982 +0100 @@ -1298,6 +1298,17 @@ This driver can also be built as a module. If so, the module will be called pwm-fan. +config SENSORS_RPI_POE_FAN + tristate "Raspberry Pi PoE HAT fan" + depends on RASPBERRYPI_FIRMWARE + depends on THERMAL || THERMAL=n + help + If you say yes here you get support for Raspberry Pi PoE (Power over + Ethernet) HAT fan. + + This driver can also be built as a module. If so, the module + will be called rpi-poe-fan. + config SENSORS_SHT15 tristate "Sensiron humidity and temperature sensors. SHT15 and compat." depends on GPIOLIB || COMPILE_TEST diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/hwmon/Makefile linux-vendor/drivers/hwmon/Makefile --- linux-4.18.16/drivers/hwmon/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/hwmon/Makefile 2018-10-29 19:31:21.286745932 +0100 @@ -141,6 +141,7 @@ obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o obj-$(CONFIG_SENSORS_POWR1220) += powr1220.o obj-$(CONFIG_SENSORS_PWM_FAN) += pwm-fan.o +obj-$(CONFIG_SENSORS_RPI_POE_FAN) += rpi-poe-fan.o obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/hwmon/rpi-poe-fan.c linux-vendor/drivers/hwmon/rpi-poe-fan.c --- linux-4.18.16/drivers/hwmon/rpi-poe-fan.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/hwmon/rpi-poe-fan.c 2018-10-29 19:31:21.295745482 +0100 @@ -0,0 +1,436 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * rpi-poe-fan.c - Hwmon driver for Raspberry Pi PoE HAT fan. + * + * Copyright (C) 2018 Raspberry Pi (Trading) Ltd. + * Based on pwm-fan.c by Kamil Debski + * + * Author: Serge Schneider + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_PWM 255 + +#define POE_CUR_PWM 0x0 +#define POE_DEF_PWM 0x1 + +struct rpi_poe_fan_ctx { + struct mutex lock; + struct rpi_firmware *fw; + unsigned int pwm_value; + unsigned int def_pwm_value; + unsigned int rpi_poe_fan_state; + unsigned int rpi_poe_fan_max_state; + unsigned int *rpi_poe_fan_cooling_levels; + struct thermal_cooling_device *cdev; + struct notifier_block nb; +}; + +struct fw_tag_data_s{ + u32 reg; + u32 val; + u32 ret; +}; + +static int write_reg(struct rpi_firmware *fw, u32 reg, u32 *val){ + struct fw_tag_data_s fw_tag_data = { + .reg = reg, + .val = *val + }; + int ret; + ret = rpi_firmware_property(fw, RPI_FIRMWARE_SET_POE_HAT_VAL, + &fw_tag_data, sizeof(fw_tag_data)); + if (ret) { + return ret; + } else if (fw_tag_data.ret) { + return -EIO; + } + return 0; +} + +static int read_reg(struct rpi_firmware *fw, u32 reg, u32 *val){ + struct fw_tag_data_s fw_tag_data = { + .reg = reg, + }; + int ret; + ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_POE_HAT_VAL, + &fw_tag_data, sizeof(fw_tag_data)); + if (ret) { + return ret; + } else if (fw_tag_data.ret) { + return -EIO; + } + *val = fw_tag_data.val; + return 0; +} + +static int rpi_poe_reboot(struct notifier_block *nb, unsigned long code, + void *unused) +{ + struct rpi_poe_fan_ctx *ctx = container_of(nb, struct rpi_poe_fan_ctx, + nb); + + if (ctx->pwm_value != ctx->def_pwm_value) + write_reg(ctx->fw, POE_CUR_PWM, &ctx->def_pwm_value); + + return NOTIFY_DONE; +} + +static int __set_pwm(struct rpi_poe_fan_ctx *ctx, u32 pwm) +{ + int ret = 0; + + mutex_lock(&ctx->lock); + if (ctx->pwm_value == pwm) + goto exit_set_pwm_err; + + ret = write_reg(ctx->fw, POE_CUR_PWM, &pwm); + if (!ret) + ctx->pwm_value = pwm; +exit_set_pwm_err: + mutex_unlock(&ctx->lock); + return ret; +} + +static int __set_def_pwm(struct rpi_poe_fan_ctx *ctx, u32 def_pwm) +{ + int ret = 0; + mutex_lock(&ctx->lock); + if (ctx->def_pwm_value == def_pwm) + goto exit_set_def_pwm_err; + + ret = write_reg(ctx->fw, POE_CUR_PWM, &def_pwm); + if (!ret) + ctx->def_pwm_value = def_pwm; +exit_set_def_pwm_err: + mutex_unlock(&ctx->lock); + return ret; +} + +static void rpi_poe_fan_update_state(struct rpi_poe_fan_ctx *ctx, + unsigned long pwm) +{ + int i; + + for (i = 0; i < ctx->rpi_poe_fan_max_state; ++i) + if (pwm < ctx->rpi_poe_fan_cooling_levels[i + 1]) + break; + + ctx->rpi_poe_fan_state = i; +} + +static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct rpi_poe_fan_ctx *ctx = dev_get_drvdata(dev); + unsigned long pwm; + int ret; + + if (kstrtoul(buf, 10, &pwm) || pwm > MAX_PWM) + return -EINVAL; + + ret = __set_pwm(ctx, pwm); + if (ret) + return ret; + + rpi_poe_fan_update_state(ctx, pwm); + return count; +} + +static ssize_t set_def_pwm(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct rpi_poe_fan_ctx *ctx = dev_get_drvdata(dev); + unsigned long def_pwm; + int ret; + + if (kstrtoul(buf, 10, &def_pwm) || def_pwm > MAX_PWM) + return -EINVAL; + + ret = __set_def_pwm(ctx, def_pwm); + if (ret) + return ret; + return count; +} + +static ssize_t show_pwm(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct rpi_poe_fan_ctx *ctx = dev_get_drvdata(dev); + + return sprintf(buf, "%u\n", ctx->pwm_value); +} + +static ssize_t show_def_pwm(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct rpi_poe_fan_ctx *ctx = dev_get_drvdata(dev); + + return sprintf(buf, "%u\n", ctx->def_pwm_value); +} + + +static SENSOR_DEVICE_ATTR(pwm1, 0644, show_pwm, set_pwm, 0); +static SENSOR_DEVICE_ATTR(def_pwm1, 0644, show_def_pwm, set_def_pwm, 1); + +static struct attribute *rpi_poe_fan_attrs[] = { + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_def_pwm1.dev_attr.attr, + NULL, +}; + +ATTRIBUTE_GROUPS(rpi_poe_fan); + +/* thermal cooling device callbacks */ +static int rpi_poe_fan_get_max_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct rpi_poe_fan_ctx *ctx = cdev->devdata; + + if (!ctx) + return -EINVAL; + + *state = ctx->rpi_poe_fan_max_state; + + return 0; +} + +static int rpi_poe_fan_get_cur_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct rpi_poe_fan_ctx *ctx = cdev->devdata; + + if (!ctx) + return -EINVAL; + + *state = ctx->rpi_poe_fan_state; + + return 0; +} + +static int rpi_poe_fan_set_cur_state(struct thermal_cooling_device *cdev, + unsigned long state) +{ + struct rpi_poe_fan_ctx *ctx = cdev->devdata; + int ret; + + if (!ctx || (state > ctx->rpi_poe_fan_max_state)) + return -EINVAL; + + if (state == ctx->rpi_poe_fan_state) + return 0; + + ret = __set_pwm(ctx, ctx->rpi_poe_fan_cooling_levels[state]); + if (ret) { + dev_err(&cdev->device, "Cannot set pwm!\n"); + return ret; + } + + ctx->rpi_poe_fan_state = state; + + return ret; +} + +static const struct thermal_cooling_device_ops rpi_poe_fan_cooling_ops = { + .get_max_state = rpi_poe_fan_get_max_state, + .get_cur_state = rpi_poe_fan_get_cur_state, + .set_cur_state = rpi_poe_fan_set_cur_state, +}; + +static int rpi_poe_fan_of_get_cooling_data(struct device *dev, + struct rpi_poe_fan_ctx *ctx) +{ + struct device_node *np = dev->of_node; + int num, i, ret; + + if (!of_find_property(np, "cooling-levels", NULL)) + return 0; + + ret = of_property_count_u32_elems(np, "cooling-levels"); + if (ret <= 0) { + dev_err(dev, "cooling-levels property missing or invalid: %d\n", + ret); + return ret ? : -EINVAL; + } + + num = ret; + ctx->rpi_poe_fan_cooling_levels = devm_kzalloc(dev, num * sizeof(u32), + GFP_KERNEL); + if (!ctx->rpi_poe_fan_cooling_levels) + return -ENOMEM; + + ret = of_property_read_u32_array(np, "cooling-levels", + ctx->rpi_poe_fan_cooling_levels, num); + if (ret) { + dev_err(dev, "Property 'cooling-levels' cannot be read!\n"); + return ret; + } + + for (i = 0; i < num; i++) { + if (ctx->rpi_poe_fan_cooling_levels[i] > MAX_PWM) { + dev_err(dev, "PWM fan state[%d]:%d > %d\n", i, + ctx->rpi_poe_fan_cooling_levels[i], MAX_PWM); + return -EINVAL; + } + } + + ctx->rpi_poe_fan_max_state = num - 1; + + return 0; +} + +static int rpi_poe_fan_probe(struct platform_device *pdev) +{ + struct thermal_cooling_device *cdev; + struct rpi_poe_fan_ctx *ctx; + struct device *hwmon; + struct device_node *np = pdev->dev.of_node; + struct device_node *fw_node; + int ret; + + fw_node = of_parse_phandle(np, "firmware", 0); + if (!fw_node) { + dev_err(&pdev->dev, "Missing firmware node\n"); + return -ENOENT; + } + + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + mutex_init(&ctx->lock); + + ctx->fw = rpi_firmware_get(fw_node); + if (!ctx->fw) + return -EPROBE_DEFER; + + platform_set_drvdata(pdev, ctx); + + ctx->nb.notifier_call = rpi_poe_reboot; + ret = register_reboot_notifier(&ctx->nb); + if (ret) { + dev_err(&pdev->dev, "Failed to register reboot notifier: %i\n", + ret); + return ret; + } + ret = read_reg(ctx->fw, POE_DEF_PWM, &ctx->def_pwm_value); + if (ret) { + dev_err(&pdev->dev, "Failed to get default PWM value: %i\n", + ret); + goto err; + } + ret = read_reg(ctx->fw, POE_CUR_PWM, &ctx->pwm_value); + if (ret) { + dev_err(&pdev->dev, "Failed to get current PWM value: %i\n", + ret); + goto err; + } + + hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, "rpipoefan", + ctx, rpi_poe_fan_groups); + if (IS_ERR(hwmon)) { + dev_err(&pdev->dev, "Failed to register hwmon device\n"); + ret = PTR_ERR(hwmon); + goto err; + } + + ret = rpi_poe_fan_of_get_cooling_data(&pdev->dev, ctx); + if (ret) + return ret; + + rpi_poe_fan_update_state(ctx, ctx->pwm_value); + if (!IS_ENABLED(CONFIG_THERMAL)) + return 0; + + cdev = thermal_of_cooling_device_register(np, + "rpi-poe-fan", ctx, + &rpi_poe_fan_cooling_ops); + if (IS_ERR(cdev)) { + dev_err(&pdev->dev, + "Failed to register rpi-poe-fan as cooling device"); + ret = PTR_ERR(cdev); + goto err; + } + ctx->cdev = cdev; + thermal_cdev_update(cdev); + + return 0; +err: + unregister_reboot_notifier(&ctx->nb); + return ret; +} + +static int rpi_poe_fan_remove(struct platform_device *pdev) +{ + struct rpi_poe_fan_ctx *ctx = platform_get_drvdata(pdev); + u32 value = ctx->def_pwm_value; + + unregister_reboot_notifier(&ctx->nb); + thermal_cooling_device_unregister(ctx->cdev); + if (ctx->pwm_value != value) { + write_reg(ctx->fw, POE_CUR_PWM, &value); + } + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int rpi_poe_fan_suspend(struct device *dev) +{ + struct rpi_poe_fan_ctx *ctx = dev_get_drvdata(dev); + u32 value = 0; + int ret = 0; + + if (ctx->pwm_value != value) + ret = write_reg(ctx->fw, POE_CUR_PWM, &value); + return ret; +} + +static int rpi_poe_fan_resume(struct device *dev) +{ + struct rpi_poe_fan_ctx *ctx = dev_get_drvdata(dev); + u32 value = ctx->pwm_value; + int ret = 0; + + if (value != 0) + ret = write_reg(ctx->fw, POE_CUR_PWM, &value); + + return ret; +} +#endif + +static SIMPLE_DEV_PM_OPS(rpi_poe_fan_pm, rpi_poe_fan_suspend, + rpi_poe_fan_resume); + +static const struct of_device_id of_rpi_poe_fan_match[] = { + { .compatible = "raspberrypi,rpi-poe-fan", }, + {}, +}; +MODULE_DEVICE_TABLE(of, of_rpi_poe_fan_match); + +static struct platform_driver rpi_poe_fan_driver = { + .probe = rpi_poe_fan_probe, + .remove = rpi_poe_fan_remove, + .driver = { + .name = "rpi-poe-fan", + .pm = &rpi_poe_fan_pm, + .of_match_table = of_rpi_poe_fan_match, + }, +}; + +module_platform_driver(rpi_poe_fan_driver); + +MODULE_AUTHOR("Serge Schneider "); +MODULE_ALIAS("platform:rpi-poe-fan"); +MODULE_DESCRIPTION("Raspberry Pi PoE HAT fan driver"); +MODULE_LICENSE("GPL"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/i2c/busses/i2c-bcm2708.c linux-vendor/drivers/i2c/busses/i2c-bcm2708.c --- linux-4.18.16/drivers/i2c/busses/i2c-bcm2708.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/i2c/busses/i2c-bcm2708.c 2018-10-29 19:31:21.314744534 +0100 @@ -0,0 +1,512 @@ +/* + * Driver for Broadcom BCM2708 BSC Controllers + * + * Copyright (C) 2012 Chris Boot & Frank Buss + * + * This driver is inspired by: + * i2c-ocores.c, by Peter Korsgaard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BSC register offsets */ +#define BSC_C 0x00 +#define BSC_S 0x04 +#define BSC_DLEN 0x08 +#define BSC_A 0x0c +#define BSC_FIFO 0x10 +#define BSC_DIV 0x14 +#define BSC_DEL 0x18 +#define BSC_CLKT 0x1c + +/* Bitfields in BSC_C */ +#define BSC_C_I2CEN 0x00008000 +#define BSC_C_INTR 0x00000400 +#define BSC_C_INTT 0x00000200 +#define BSC_C_INTD 0x00000100 +#define BSC_C_ST 0x00000080 +#define BSC_C_CLEAR_1 0x00000020 +#define BSC_C_CLEAR_2 0x00000010 +#define BSC_C_READ 0x00000001 + +/* Bitfields in BSC_S */ +#define BSC_S_CLKT 0x00000200 +#define BSC_S_ERR 0x00000100 +#define BSC_S_RXF 0x00000080 +#define BSC_S_TXE 0x00000040 +#define BSC_S_RXD 0x00000020 +#define BSC_S_TXD 0x00000010 +#define BSC_S_RXR 0x00000008 +#define BSC_S_TXW 0x00000004 +#define BSC_S_DONE 0x00000002 +#define BSC_S_TA 0x00000001 + +#define I2C_WAIT_LOOP_COUNT 200 + +#define DRV_NAME "bcm2708_i2c" + +static unsigned int baudrate; +module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); +MODULE_PARM_DESC(baudrate, "The I2C baudrate"); + +static bool combined = false; +module_param(combined, bool, 0644); +MODULE_PARM_DESC(combined, "Use combined transactions"); + +struct bcm2708_i2c { + struct i2c_adapter adapter; + + spinlock_t lock; + void __iomem *base; + int irq; + struct clk *clk; + u32 cdiv; + u32 clk_tout; + + struct completion done; + + struct i2c_msg *msg; + int pos; + int nmsgs; + bool error; +}; + +static inline u32 bcm2708_rd(struct bcm2708_i2c *bi, unsigned reg) +{ + return readl(bi->base + reg); +} + +static inline void bcm2708_wr(struct bcm2708_i2c *bi, unsigned reg, u32 val) +{ + writel(val, bi->base + reg); +} + +static inline void bcm2708_bsc_reset(struct bcm2708_i2c *bi) +{ + bcm2708_wr(bi, BSC_C, 0); + bcm2708_wr(bi, BSC_S, BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE); +} + +static inline void bcm2708_bsc_fifo_drain(struct bcm2708_i2c *bi) +{ + while ((bi->pos < bi->msg->len) && (bcm2708_rd(bi, BSC_S) & BSC_S_RXD)) + bi->msg->buf[bi->pos++] = bcm2708_rd(bi, BSC_FIFO); +} + +static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi) +{ + while ((bi->pos < bi->msg->len) && (bcm2708_rd(bi, BSC_S) & BSC_S_TXD)) + bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); +} + +static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi) +{ + u32 cdiv, s, clk_tout; + u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1; + int wait_loops = I2C_WAIT_LOOP_COUNT; + + /* Can't call clk_get_rate as it locks a mutex and here we are spinlocked. + * Use the value that we cached in the probe. + */ + cdiv = bi->cdiv; + clk_tout = bi->clk_tout; + + if (bi->msg->flags & I2C_M_RD) + c |= BSC_C_INTR | BSC_C_READ; + else + c |= BSC_C_INTT; + + bcm2708_wr(bi, BSC_CLKT, clk_tout); + bcm2708_wr(bi, BSC_DIV, cdiv); + bcm2708_wr(bi, BSC_A, bi->msg->addr); + bcm2708_wr(bi, BSC_DLEN, bi->msg->len); + if (combined) + { + /* Do the next two messages meet combined transaction criteria? + - Current message is a write, next message is a read + - Both messages to same slave address + - Write message can fit inside FIFO (16 bytes or less) */ + if ( (bi->nmsgs > 1) && + !(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) && + (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) { + + /* Clear FIFO */ + bcm2708_wr(bi, BSC_C, BSC_C_CLEAR_1); + + /* Fill FIFO with entire write message (16 byte FIFO) */ + while (bi->pos < bi->msg->len) { + bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); + } + /* Start write transfer (no interrupts, don't clear FIFO) */ + bcm2708_wr(bi, BSC_C, BSC_C_I2CEN | BSC_C_ST); + + /* poll for transfer start bit (should only take 1-20 polls) */ + do { + s = bcm2708_rd(bi, BSC_S); + } while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE)) && --wait_loops >= 0); + + /* did we time out or some error occured? */ + if (wait_loops < 0 || (s & (BSC_S_ERR | BSC_S_CLKT))) { + return -1; + } + + /* Send next read message before the write transfer finishes. */ + bi->nmsgs--; + bi->msg++; + bi->pos = 0; + bcm2708_wr(bi, BSC_DLEN, bi->msg->len); + c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_INTR | BSC_C_ST | BSC_C_READ; + } + } + bcm2708_wr(bi, BSC_C, c); + + return 0; +} + +static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id) +{ + struct bcm2708_i2c *bi = dev_id; + bool handled = true; + u32 s; + int ret; + + spin_lock(&bi->lock); + + /* we may see camera interrupts on the "other" I2C channel + Just return if we've not sent anything */ + if (!bi->nmsgs || !bi->msg) { + goto early_exit; + } + + s = bcm2708_rd(bi, BSC_S); + + if (s & (BSC_S_CLKT | BSC_S_ERR)) { + bcm2708_bsc_reset(bi); + bi->error = true; + + bi->msg = 0; /* to inform the that all work is done */ + bi->nmsgs = 0; + /* wake up our bh */ + complete(&bi->done); + } else if (s & BSC_S_DONE) { + bi->nmsgs--; + + if (bi->msg->flags & I2C_M_RD) { + bcm2708_bsc_fifo_drain(bi); + } + + bcm2708_bsc_reset(bi); + + if (bi->nmsgs) { + /* advance to next message */ + bi->msg++; + bi->pos = 0; + ret = bcm2708_bsc_setup(bi); + if (ret < 0) { + bcm2708_bsc_reset(bi); + bi->error = true; + bi->msg = 0; /* to inform the that all work is done */ + bi->nmsgs = 0; + /* wake up our bh */ + complete(&bi->done); + goto early_exit; + } + } else { + bi->msg = 0; /* to inform the that all work is done */ + bi->nmsgs = 0; + /* wake up our bh */ + complete(&bi->done); + } + } else if (s & BSC_S_TXW) { + bcm2708_bsc_fifo_fill(bi); + } else if (s & BSC_S_RXR) { + bcm2708_bsc_fifo_drain(bi); + } else { + handled = false; + } + +early_exit: + spin_unlock(&bi->lock); + + return handled ? IRQ_HANDLED : IRQ_NONE; +} + +static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct bcm2708_i2c *bi = adap->algo_data; + unsigned long flags; + int ret; + + spin_lock_irqsave(&bi->lock, flags); + + reinit_completion(&bi->done); + bi->msg = msgs; + bi->pos = 0; + bi->nmsgs = num; + bi->error = false; + + ret = bcm2708_bsc_setup(bi); + + spin_unlock_irqrestore(&bi->lock, flags); + + /* check the result of the setup */ + if (ret < 0) + { + dev_err(&adap->dev, "transfer setup timed out\n"); + goto error_timeout; + } + + ret = wait_for_completion_timeout(&bi->done, adap->timeout); + if (ret == 0) { + dev_err(&adap->dev, "transfer timed out\n"); + goto error_timeout; + } + + ret = bi->error ? -EIO : num; + return ret; + +error_timeout: + spin_lock_irqsave(&bi->lock, flags); + bcm2708_bsc_reset(bi); + bi->msg = 0; /* to inform the interrupt handler that there's nothing else to be done */ + bi->nmsgs = 0; + spin_unlock_irqrestore(&bi->lock, flags); + return -ETIMEDOUT; +} + +static u32 bcm2708_i2c_functionality(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | /*I2C_FUNC_10BIT_ADDR |*/ I2C_FUNC_SMBUS_EMUL; +} + +static struct i2c_algorithm bcm2708_i2c_algorithm = { + .master_xfer = bcm2708_i2c_master_xfer, + .functionality = bcm2708_i2c_functionality, +}; + +static int bcm2708_i2c_probe(struct platform_device *pdev) +{ + struct resource *regs; + int irq, err = -ENOMEM; + struct clk *clk; + struct bcm2708_i2c *bi; + struct i2c_adapter *adap; + unsigned long bus_hz; + u32 cdiv, clk_tout; + u32 baud; + + baud = CONFIG_I2C_BCM2708_BAUDRATE; + + if (pdev->dev.of_node) { + u32 bus_clk_rate; + pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); + if (pdev->id < 0) { + dev_err(&pdev->dev, "alias is missing\n"); + return -EINVAL; + } + if (!of_property_read_u32(pdev->dev.of_node, + "clock-frequency", &bus_clk_rate)) + baud = bus_clk_rate; + else + dev_warn(&pdev->dev, + "Could not read clock-frequency property\n"); + } + + if (baudrate) + baud = baudrate; + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(&pdev->dev, "could not get IO memory\n"); + return -ENXIO; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "could not get IRQ\n"); + return irq; + } + + clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "could not find clk: %ld\n", PTR_ERR(clk)); + return PTR_ERR(clk); + } + + err = clk_prepare_enable(clk); + if (err) { + dev_err(&pdev->dev, "could not enable clk: %d\n", err); + goto out_clk_put; + } + + bi = kzalloc(sizeof(*bi), GFP_KERNEL); + if (!bi) + goto out_clk_disable; + + platform_set_drvdata(pdev, bi); + + adap = &bi->adapter; + adap->class = I2C_CLASS_HWMON | I2C_CLASS_DDC; + adap->algo = &bcm2708_i2c_algorithm; + adap->algo_data = bi; + adap->dev.parent = &pdev->dev; + adap->nr = pdev->id; + strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); + adap->dev.of_node = pdev->dev.of_node; + + switch (pdev->id) { + case 0: + adap->class = I2C_CLASS_HWMON; + break; + case 1: + adap->class = I2C_CLASS_DDC; + break; + case 2: + adap->class = I2C_CLASS_DDC; + break; + default: + dev_err(&pdev->dev, "can only bind to BSC 0, 1 or 2\n"); + err = -ENXIO; + goto out_free_bi; + } + + spin_lock_init(&bi->lock); + init_completion(&bi->done); + + bi->base = ioremap(regs->start, resource_size(regs)); + if (!bi->base) { + dev_err(&pdev->dev, "could not remap memory\n"); + goto out_free_bi; + } + + bi->irq = irq; + bi->clk = clk; + + err = request_irq(irq, bcm2708_i2c_interrupt, IRQF_SHARED, + dev_name(&pdev->dev), bi); + if (err) { + dev_err(&pdev->dev, "could not request IRQ: %d\n", err); + goto out_iounmap; + } + + bcm2708_bsc_reset(bi); + + err = i2c_add_numbered_adapter(adap); + if (err < 0) { + dev_err(&pdev->dev, "could not add I2C adapter: %d\n", err); + goto out_free_irq; + } + + bus_hz = clk_get_rate(bi->clk); + cdiv = bus_hz / baud; + if (cdiv > 0xffff) { + cdiv = 0xffff; + baud = bus_hz / cdiv; + } + + clk_tout = 35/1000*baud; //35ms timeout as per SMBus specs. + if (clk_tout > 0xffff) + clk_tout = 0xffff; + + bi->cdiv = cdiv; + bi->clk_tout = clk_tout; + + dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n", + pdev->id, (unsigned long)regs->start, irq, baud); + + return 0; + +out_free_irq: + free_irq(bi->irq, bi); +out_iounmap: + iounmap(bi->base); +out_free_bi: + kfree(bi); +out_clk_disable: + clk_disable_unprepare(clk); +out_clk_put: + clk_put(clk); + return err; +} + +static int bcm2708_i2c_remove(struct platform_device *pdev) +{ + struct bcm2708_i2c *bi = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + + i2c_del_adapter(&bi->adapter); + free_irq(bi->irq, bi); + iounmap(bi->base); + clk_disable_unprepare(bi->clk); + clk_put(bi->clk); + kfree(bi); + + return 0; +} + +static const struct of_device_id bcm2708_i2c_of_match[] = { + { .compatible = "brcm,bcm2708-i2c" }, + {}, +}; +MODULE_DEVICE_TABLE(of, bcm2708_i2c_of_match); + +static struct platform_driver bcm2708_i2c_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = bcm2708_i2c_of_match, + }, + .probe = bcm2708_i2c_probe, + .remove = bcm2708_i2c_remove, +}; + +// module_platform_driver(bcm2708_i2c_driver); + + +static int __init bcm2708_i2c_init(void) +{ + return platform_driver_register(&bcm2708_i2c_driver); +} + +static void __exit bcm2708_i2c_exit(void) +{ + platform_driver_unregister(&bcm2708_i2c_driver); +} + +module_init(bcm2708_i2c_init); +module_exit(bcm2708_i2c_exit); + + + +MODULE_DESCRIPTION("BSC controller driver for Broadcom BCM2708"); +MODULE_AUTHOR("Chris Boot "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/i2c/busses/i2c-bcm2835.c linux-vendor/drivers/i2c/busses/i2c-bcm2835.c --- linux-4.18.16/drivers/i2c/busses/i2c-bcm2835.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/i2c/busses/i2c-bcm2835.c 2018-10-29 19:31:21.315744484 +0100 @@ -56,6 +56,18 @@ #define BCM2835_I2C_CDIV_MIN 0x0002 #define BCM2835_I2C_CDIV_MAX 0xFFFE +static unsigned int debug; +module_param(debug, uint, 0644); +MODULE_PARM_DESC(debug, "1=err, 2=isr, 3=xfer"); + +#define BCM2835_DEBUG_MAX 512 +struct bcm2835_debug { + struct i2c_msg *msg; + int msg_idx; + size_t remain; + u32 status; +}; + struct bcm2835_i2c_dev { struct device *dev; void __iomem *regs; @@ -69,8 +81,78 @@ u32 msg_err; u8 *msg_buf; size_t msg_buf_remaining; + struct bcm2835_debug debug[BCM2835_DEBUG_MAX]; + unsigned int debug_num; + unsigned int debug_num_msgs; }; +static inline void bcm2835_debug_add(struct bcm2835_i2c_dev *i2c_dev, u32 s) +{ + if (!i2c_dev->debug_num_msgs || i2c_dev->debug_num >= BCM2835_DEBUG_MAX) + return; + + i2c_dev->debug[i2c_dev->debug_num].msg = i2c_dev->curr_msg; + i2c_dev->debug[i2c_dev->debug_num].msg_idx = + i2c_dev->debug_num_msgs - i2c_dev->num_msgs; + i2c_dev->debug[i2c_dev->debug_num].remain = i2c_dev->msg_buf_remaining; + i2c_dev->debug[i2c_dev->debug_num].status = s; + i2c_dev->debug_num++; +} + +static void bcm2835_debug_print_status(struct bcm2835_i2c_dev *i2c_dev, + struct bcm2835_debug *d) +{ + u32 s = d->status; + + pr_info("isr: remain=%zu, status=0x%x : %s%s%s%s%s%s%s%s%s%s [i2c%d]\n", + d->remain, s, + s & BCM2835_I2C_S_TA ? "TA " : "", + s & BCM2835_I2C_S_DONE ? "DONE " : "", + s & BCM2835_I2C_S_TXW ? "TXW " : "", + s & BCM2835_I2C_S_RXR ? "RXR " : "", + s & BCM2835_I2C_S_TXD ? "TXD " : "", + s & BCM2835_I2C_S_RXD ? "RXD " : "", + s & BCM2835_I2C_S_TXE ? "TXE " : "", + s & BCM2835_I2C_S_RXF ? "RXF " : "", + s & BCM2835_I2C_S_ERR ? "ERR " : "", + s & BCM2835_I2C_S_CLKT ? "CLKT " : "", + i2c_dev->adapter.nr); +} + +static void bcm2835_debug_print_msg(struct bcm2835_i2c_dev *i2c_dev, + struct i2c_msg *msg, int i, int total, + const char *fname) +{ + pr_info("%s: msg(%d/%d) %s addr=0x%02x, len=%u flags=%s%s%s%s%s%s%s [i2c%d]\n", + fname, i, total, + msg->flags & I2C_M_RD ? "read" : "write", msg->addr, msg->len, + msg->flags & I2C_M_TEN ? "TEN" : "", + msg->flags & I2C_M_RECV_LEN ? "RECV_LEN" : "", + msg->flags & I2C_M_NO_RD_ACK ? "NO_RD_ACK" : "", + msg->flags & I2C_M_IGNORE_NAK ? "IGNORE_NAK" : "", + msg->flags & I2C_M_REV_DIR_ADDR ? "REV_DIR_ADDR" : "", + msg->flags & I2C_M_NOSTART ? "NOSTART" : "", + msg->flags & I2C_M_STOP ? "STOP" : "", + i2c_dev->adapter.nr); +} + +static void bcm2835_debug_print(struct bcm2835_i2c_dev *i2c_dev) +{ + struct bcm2835_debug *d; + unsigned int i; + + for (i = 0; i < i2c_dev->debug_num; i++) { + d = &i2c_dev->debug[i]; + if (d->status == ~0) + bcm2835_debug_print_msg(i2c_dev, d->msg, d->msg_idx, + i2c_dev->debug_num_msgs, "start_transfer"); + else + bcm2835_debug_print_status(i2c_dev, d); + } + if (i2c_dev->debug_num >= BCM2835_DEBUG_MAX) + pr_info("BCM2835_DEBUG_MAX reached\n"); +} + static inline void bcm2835_i2c_writel(struct bcm2835_i2c_dev *i2c_dev, u32 reg, u32 val) { @@ -189,6 +271,7 @@ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_A, msg->addr); bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DLEN, msg->len); bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, c); + bcm2835_debug_add(i2c_dev, ~0); } /* @@ -206,6 +289,7 @@ u32 val, err; val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); + bcm2835_debug_add(i2c_dev, val); err = val & (BCM2835_I2C_S_CLKT | BCM2835_I2C_S_ERR); if (err) { @@ -272,6 +356,13 @@ unsigned long time_left; int i, ret; + if (debug) + i2c_dev->debug_num_msgs = num; + + if (debug > 2) + for (i = 0; i < num; i++) + bcm2835_debug_print_msg(i2c_dev, &msgs[i], i + 1, num, __func__); + for (i = 0; i < (num - 1); i++) if (msgs[i].flags & I2C_M_RD) { dev_warn_once(i2c_dev->dev, @@ -291,6 +382,10 @@ time_left = wait_for_completion_timeout(&i2c_dev->completion, adap->timeout); + if (debug > 1 || (debug && (!time_left || i2c_dev->msg_err))) + bcm2835_debug_print(i2c_dev); + i2c_dev->debug_num_msgs = 0; + i2c_dev->debug_num = 0; if (!time_left) { bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, BCM2835_I2C_C_CLEAR); @@ -301,7 +396,9 @@ if (!i2c_dev->msg_err) return num; - dev_dbg(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err); + if (debug) + dev_err(i2c_dev->dev, "i2c transfer failed: %x\n", + i2c_dev->msg_err); if (i2c_dev->msg_err & BCM2835_I2C_S_ERR) return -EREMOTEIO; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/i2c/busses/i2c-gpio.c linux-vendor/drivers/i2c/busses/i2c-gpio.c --- linux-4.18.16/drivers/i2c/busses/i2c-gpio.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/i2c/busses/i2c-gpio.c 2018-10-29 19:31:21.315744484 +0100 @@ -321,7 +321,9 @@ adap->dev.parent = dev; adap->dev.of_node = np; - adap->nr = pdev->id; + if (pdev->id != PLATFORM_DEVID_NONE || !pdev->dev.of_node || + of_property_read_u32(pdev->dev.of_node, "reg", &adap->nr)) + adap->nr = pdev->id; ret = i2c_bit_add_numbered_bus(adap); if (ret) return ret; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/i2c/busses/Kconfig linux-vendor/drivers/i2c/busses/Kconfig --- linux-4.18.16/drivers/i2c/busses/Kconfig 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/i2c/busses/Kconfig 2018-10-29 19:31:21.312744634 +0100 @@ -8,6 +8,25 @@ comment "PC SMBus host controller drivers" depends on PCI +config I2C_BCM2708 + tristate "BCM2708 BSC" + depends on ARCH_BCM2835 + help + Enabling this option will add BSC (Broadcom Serial Controller) + support for the BCM2708. BSC is a Broadcom proprietary bus compatible + with I2C/TWI/SMBus. + +config I2C_BCM2708_BAUDRATE + prompt "BCM2708 I2C baudrate" + depends on I2C_BCM2708 + int + default 100000 + help + Set the I2C baudrate. This will alter the default value. A + different baudrate can be set by using a module parameter as well. If + no parameter is provided when loading, this is the value that will be + used. + config I2C_ALI1535 tristate "ALI 1535" depends on PCI diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/i2c/busses/Makefile linux-vendor/drivers/i2c/busses/Makefile --- linux-4.18.16/drivers/i2c/busses/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/i2c/busses/Makefile 2018-10-29 19:31:21.313744584 +0100 @@ -3,6 +3,8 @@ # Makefile for the i2c bus drivers. # +obj-$(CONFIG_I2C_BCM2708) += i2c-bcm2708.o + # ACPI drivers obj-$(CONFIG_I2C_SCMI) += i2c-scmi.o diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/input/joystick/Kconfig linux-vendor/drivers/input/joystick/Kconfig --- linux-4.18.16/drivers/input/joystick/Kconfig 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/input/joystick/Kconfig 2018-10-29 19:31:21.434738548 +0100 @@ -361,4 +361,12 @@ To compile this driver as a module, choose M here: the module will be called pxrc. +config JOYSTICK_RPISENSE + tristate "Raspberry Pi Sense HAT joystick" + depends on GPIOLIB && INPUT + select MFD_RPISENSE_CORE + + help + This is the joystick driver for the Raspberry Pi Sense HAT + endif diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/input/joystick/Makefile linux-vendor/drivers/input/joystick/Makefile --- linux-4.18.16/drivers/input/joystick/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/input/joystick/Makefile 2018-10-29 19:31:21.434738548 +0100 @@ -35,4 +35,5 @@ obj-$(CONFIG_JOYSTICK_XPAD) += xpad.o obj-$(CONFIG_JOYSTICK_ZHENHUA) += zhenhua.o obj-$(CONFIG_JOYSTICK_WALKERA0701) += walkera0701.o +obj-$(CONFIG_JOYSTICK_RPISENSE) += rpisense-js.o diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/input/joystick/rpisense-js.c linux-vendor/drivers/input/joystick/rpisense-js.c --- linux-4.18.16/drivers/input/joystick/rpisense-js.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/input/joystick/rpisense-js.c 2018-10-29 19:31:21.435738498 +0100 @@ -0,0 +1,153 @@ +/* + * Raspberry Pi Sense HAT joystick driver + * http://raspberrypi.org + * + * Copyright (C) 2015 Raspberry Pi + * + * Author: Serge Schneider + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include + +#include +#include + +static struct rpisense *rpisense; +static unsigned char keymap[5] = {KEY_DOWN, KEY_RIGHT, KEY_UP, KEY_ENTER, KEY_LEFT,}; + +static void keys_work_fn(struct work_struct *work) +{ + int i; + static s32 prev_keys; + struct rpisense_js *rpisense_js = &rpisense->joystick; + s32 keys = rpisense_reg_read(rpisense, RPISENSE_KEYS); + s32 changes = keys ^ prev_keys; + + prev_keys = keys; + for (i = 0; i < 5; i++) { + if (changes & 1) { + input_report_key(rpisense_js->keys_dev, + keymap[i], keys & 1); + } + changes >>= 1; + keys >>= 1; + } + input_sync(rpisense_js->keys_dev); +} + +static irqreturn_t keys_irq_handler(int irq, void *pdev) +{ + struct rpisense_js *rpisense_js = &rpisense->joystick; + + schedule_work(&rpisense_js->keys_work_s); + return IRQ_HANDLED; +} + +static int rpisense_js_probe(struct platform_device *pdev) +{ + int ret; + int i; + struct rpisense_js *rpisense_js; + + rpisense = rpisense_get_dev(); + rpisense_js = &rpisense->joystick; + + INIT_WORK(&rpisense_js->keys_work_s, keys_work_fn); + + rpisense_js->keys_dev = input_allocate_device(); + if (!rpisense_js->keys_dev) { + dev_err(&pdev->dev, "Could not allocate input device.\n"); + return -ENOMEM; + } + + rpisense_js->keys_dev->evbit[0] = BIT_MASK(EV_KEY); + for (i = 0; i < ARRAY_SIZE(keymap); i++) { + set_bit(keymap[i], + rpisense_js->keys_dev->keybit); + } + + rpisense_js->keys_dev->name = "Raspberry Pi Sense HAT Joystick"; + rpisense_js->keys_dev->phys = "rpi-sense-joy/input0"; + rpisense_js->keys_dev->id.bustype = BUS_I2C; + rpisense_js->keys_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + rpisense_js->keys_dev->keycode = keymap; + rpisense_js->keys_dev->keycodesize = sizeof(unsigned char); + rpisense_js->keys_dev->keycodemax = ARRAY_SIZE(keymap); + + ret = input_register_device(rpisense_js->keys_dev); + if (ret) { + dev_err(&pdev->dev, "Could not register input device.\n"); + goto err_keys_alloc; + } + + ret = gpiod_direction_input(rpisense_js->keys_desc); + if (ret) { + dev_err(&pdev->dev, "Could not set keys-int direction.\n"); + goto err_keys_reg; + } + + rpisense_js->keys_irq = gpiod_to_irq(rpisense_js->keys_desc); + if (rpisense_js->keys_irq < 0) { + dev_err(&pdev->dev, "Could not determine keys-int IRQ.\n"); + ret = rpisense_js->keys_irq; + goto err_keys_reg; + } + + ret = devm_request_irq(&pdev->dev, rpisense_js->keys_irq, + keys_irq_handler, IRQF_TRIGGER_RISING, + "keys", &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "IRQ request failed.\n"); + goto err_keys_reg; + } + return 0; +err_keys_reg: + input_unregister_device(rpisense_js->keys_dev); +err_keys_alloc: + input_free_device(rpisense_js->keys_dev); + return ret; +} + +static int rpisense_js_remove(struct platform_device *pdev) +{ + struct rpisense_js *rpisense_js = &rpisense->joystick; + + input_unregister_device(rpisense_js->keys_dev); + input_free_device(rpisense_js->keys_dev); + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id rpisense_js_id[] = { + { .compatible = "rpi,rpi-sense-js" }, + { }, +}; +MODULE_DEVICE_TABLE(of, rpisense_js_id); +#endif + +static struct platform_device_id rpisense_js_device_id[] = { + { .name = "rpi-sense-js" }, + { }, +}; +MODULE_DEVICE_TABLE(platform, rpisense_js_device_id); + +static struct platform_driver rpisense_js_driver = { + .probe = rpisense_js_probe, + .remove = rpisense_js_remove, + .driver = { + .name = "rpi-sense-js", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(rpisense_js_driver); + +MODULE_DESCRIPTION("Raspberry Pi Sense HAT joystick driver"); +MODULE_AUTHOR("Serge Schneider "); +MODULE_LICENSE("GPL"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/input/touchscreen/Kconfig linux-vendor/drivers/input/touchscreen/Kconfig --- linux-4.18.16/drivers/input/touchscreen/Kconfig 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/input/touchscreen/Kconfig 2018-10-29 19:31:21.448737850 +0100 @@ -671,6 +671,13 @@ To compile this driver as a module, choose M here: the module will be called edt-ft5x06. +config TOUCHSCREEN_RPI_FT5406 + tristate "Raspberry Pi FT5406 driver" + depends on RASPBERRYPI_FIRMWARE + help + Say Y here to enable the Raspberry Pi memory based FT5406 device + + config TOUCHSCREEN_MIGOR tristate "Renesas MIGO-R touchscreen" depends on (SH_MIGOR || COMPILE_TEST) && I2C diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/input/touchscreen/Makefile linux-vendor/drivers/input/touchscreen/Makefile --- linux-4.18.16/drivers/input/touchscreen/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/input/touchscreen/Makefile 2018-10-29 19:31:21.448737850 +0100 @@ -31,6 +31,7 @@ obj-$(CONFIG_TOUCHSCREEN_DA9052) += da9052_tsi.o obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o +obj-$(CONFIG_TOUCHSCREEN_RPI_FT5406) += rpi-ft5406.o obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/input/touchscreen/rpi-ft5406.c linux-vendor/drivers/input/touchscreen/rpi-ft5406.c --- linux-4.18.16/drivers/input/touchscreen/rpi-ft5406.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/input/touchscreen/rpi-ft5406.c 2018-10-29 19:31:21.453737600 +0100 @@ -0,0 +1,364 @@ +/* + * Driver for memory based ft5406 touchscreen + * + * Copyright (C) 2015, 2017 Raspberry Pi + * + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXIMUM_SUPPORTED_POINTS 10 +#define FTS_TOUCH_DOWN 0 +#define FTS_TOUCH_UP 1 +#define FTS_TOUCH_CONTACT 2 + +struct ft5406_regs { + uint8_t device_mode; + uint8_t gesture_id; + uint8_t num_points; + struct ft5406_touch { + uint8_t xh; + uint8_t xl; + uint8_t yh; + uint8_t yl; + uint8_t pressure; /* Not supported */ + uint8_t area; /* Not supported */ + } point[MAXIMUM_SUPPORTED_POINTS]; +}; + +/* These are defaults if the DT entries are missing */ +#define DEFAULT_SCREEN_WIDTH 800 +#define DEFAULT_SCREEN_HEIGHT 480 + +struct ft5406 { + struct platform_device *pdev; + struct input_dev *input_dev; + void __iomem *ts_base; + dma_addr_t bus_addr; + struct task_struct *thread; + + uint16_t max_x; + uint16_t max_y; + uint8_t hflip; + uint8_t vflip; + uint8_t xyswap; +}; + +/* Thread to poll for touchscreen events + * + * This thread polls the memory based register copy of the ft5406 registers + * using the number of points register to know whether the copy has been + * updated (we write 99 to the memory copy, the GPU will write between + * 0 - 10 points) + */ +#define ID_TO_BIT(a) (1 << a) + +static int ft5406_thread(void *arg) +{ + struct ft5406 *ts = (struct ft5406 *) arg; + struct ft5406_regs regs; + int known_ids = 0; + + while (!kthread_should_stop()) { + /* 60fps polling */ + msleep_interruptible(17); + memcpy_fromio(®s, ts->ts_base, sizeof(struct ft5406_regs)); + iowrite8(99, + ts->ts_base + + offsetof(struct ft5406_regs, num_points)); + + /* + * Do not output if theres no new information (num_points is 99) + * or we have no touch points and don't need to release any + */ + if (!(regs.num_points == 99 || + (regs.num_points == 0 && known_ids == 0))) { + int i; + int modified_ids = 0, released_ids; + + for (i = 0; i < regs.num_points; i++) { + int x = (((int) regs.point[i].xh & 0xf) << 8) + + regs.point[i].xl; + int y = (((int) regs.point[i].yh & 0xf) << 8) + + regs.point[i].yl; + int touchid = (regs.point[i].yh >> 4) & 0xf; + int event_type = (regs.point[i].xh >> 6) & 0x03; + + modified_ids |= ID_TO_BIT(touchid); + + if (event_type == FTS_TOUCH_DOWN || + event_type == FTS_TOUCH_CONTACT) { + if (ts->hflip) + x = ts->max_x - 1 - x; + + if (ts->vflip) + y = ts->max_y - 1 - y; + + if (ts->xyswap) + swap(x, y); + + if (!((ID_TO_BIT(touchid)) & known_ids)) + dev_dbg(&ts->pdev->dev, + "x = %d, y = %d, press = %d, touchid = %d\n", + x, y, + regs.point[i].pressure, + touchid); + + input_mt_slot(ts->input_dev, touchid); + input_mt_report_slot_state( + ts->input_dev, + MT_TOOL_FINGER, + 1); + + input_report_abs(ts->input_dev, + ABS_MT_POSITION_X, x); + input_report_abs(ts->input_dev, + ABS_MT_POSITION_Y, y); + } + } + + released_ids = known_ids & ~modified_ids; + for (i = 0; + released_ids && i < MAXIMUM_SUPPORTED_POINTS; + i++) { + if (released_ids & (1<pdev->dev, + "Released %d, known = %x, modified = %x\n", + i, known_ids, modified_ids); + input_mt_slot(ts->input_dev, i); + input_mt_report_slot_state( + ts->input_dev, + MT_TOOL_FINGER, + 0); + modified_ids &= ~(ID_TO_BIT(i)); + } + } + known_ids = modified_ids; + + input_mt_report_pointer_emulation(ts->input_dev, true); + input_sync(ts->input_dev); + } + } + + return 0; +} + +static int ft5406_probe(struct platform_device *pdev) +{ + int err = 0; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct ft5406 *ts; + struct device_node *fw_node; + struct rpi_firmware *fw; + u32 touchbuf; + u32 val; + + dev_info(dev, "Probing device\n"); + + fw_node = of_parse_phandle(np, "firmware", 0); + if (!fw_node) { + dev_err(dev, "Missing firmware node\n"); + return -ENOENT; + } + + fw = rpi_firmware_get(fw_node); + if (!fw) + return -EPROBE_DEFER; + + ts = devm_kzalloc(dev, sizeof(struct ft5406), GFP_KERNEL); + if (!ts) { + dev_err(dev, "Failed to allocate memory\n"); + return -ENOMEM; + } + + ts->input_dev = input_allocate_device(); + if (!ts->input_dev) { + dev_err(dev, "Failed to allocate input device\n"); + return -ENOMEM; + } + + ts->ts_base = dma_zalloc_coherent(dev, PAGE_SIZE, &ts->bus_addr, + GFP_KERNEL); + if (!ts->ts_base) { + pr_err("[%s]: failed to dma_alloc_coherent(%ld)\n", + __func__, PAGE_SIZE); + err = -ENOMEM; + goto out; + } + + touchbuf = (u32)ts->bus_addr; + err = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF, + &touchbuf, sizeof(touchbuf)); + + if (err || touchbuf != 0) { + dev_warn(dev, "Failed to set touchbuf, trying to get err:%x\n", + err); + dma_free_coherent(dev, PAGE_SIZE, ts->ts_base, ts->bus_addr); + ts->ts_base = 0; + ts->bus_addr = 0; + } + + if (!ts->ts_base) { + dev_warn(dev, + "set failed, trying get (err:%d touchbuf:%x virt:%p bus:%x)\n", + err, touchbuf, ts->ts_base, ts->bus_addr); + + err = rpi_firmware_property( + fw, + RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF, + &touchbuf, sizeof(touchbuf)); + if (err) { + dev_err(dev, "Failed to get touch buffer\n"); + goto out; + } + + if (!touchbuf) { + dev_err(dev, "Touchscreen not detected\n"); + err = -ENODEV; + goto out; + } + + dev_dbg(dev, "Got TS buffer 0x%x\n", touchbuf); + + /* mmap the physical memory */ + touchbuf &= ~0xc0000000; + ts->ts_base = ioremap(touchbuf, sizeof(struct ft5406_regs)); + if (ts->ts_base == NULL) { + dev_err(dev, "Failed to map physical address\n"); + err = -ENOMEM; + goto out; + } + } + platform_set_drvdata(pdev, ts); + ts->pdev = pdev; + + ts->input_dev->name = "FT5406 memory based driver"; + + if (of_property_read_u32(np, "touchscreen-size-x", &val) >= 0) + ts->max_x = val; + else + ts->max_x = DEFAULT_SCREEN_WIDTH; + + if (of_property_read_u32(np, "touchscreen-size-y", &val) >= 0) + ts->max_y = val; + else + ts->max_y = DEFAULT_SCREEN_HEIGHT; + + if (of_property_read_u32(np, "touchscreen-inverted-x", &val) >= 0) + ts->hflip = val; + + if (of_property_read_u32(np, "touchscreen-inverted-y", &val) >= 0) + ts->vflip = val; + + if (of_property_read_u32(np, "touchscreen-swapped-x-y", &val) >= 0) + ts->xyswap = val; + + dev_dbg(dev, + "Touchscreen parameters (%d,%d), hflip=%d, vflip=%d, xyswap=%d", + ts->max_x, ts->max_y, ts->hflip, ts->vflip, ts->xyswap); + + __set_bit(EV_KEY, ts->input_dev->evbit); + __set_bit(EV_SYN, ts->input_dev->evbit); + __set_bit(EV_ABS, ts->input_dev->evbit); + + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, + ts->xyswap ? ts->max_y : ts->max_x, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, + ts->xyswap ? ts->max_x : ts->max_y, 0, 0); + + input_mt_init_slots(ts->input_dev, + MAXIMUM_SUPPORTED_POINTS, INPUT_MT_DIRECT); + + input_set_drvdata(ts->input_dev, ts); + + err = input_register_device(ts->input_dev); + if (err) { + dev_err(dev, "could not register input device, %d\n", + err); + goto out; + } + + /* create thread that polls the touch events */ + ts->thread = kthread_run(ft5406_thread, ts, "ft5406"); + if (ts->thread == NULL) { + dev_err(dev, "Failed to create kernel thread"); + err = -ENOMEM; + goto out; + } + + return 0; + +out: + if (ts->bus_addr) { + dma_free_coherent(dev, PAGE_SIZE, ts->ts_base, ts->bus_addr); + ts->bus_addr = 0; + ts->ts_base = NULL; + } else if (ts->ts_base) { + iounmap(ts->ts_base); + ts->ts_base = NULL; + } + if (ts->input_dev) { + input_unregister_device(ts->input_dev); + ts->input_dev = NULL; + } + return err; +} + +static int ft5406_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ft5406 *ts = (struct ft5406 *) platform_get_drvdata(pdev); + + dev_info(dev, "Removing rpi-ft5406\n"); + + kthread_stop(ts->thread); + + if (ts->bus_addr) + dma_free_coherent(dev, PAGE_SIZE, ts->ts_base, ts->bus_addr); + else if (ts->ts_base) + iounmap(ts->ts_base); + if (ts->input_dev) + input_unregister_device(ts->input_dev); + + return 0; +} + +static const struct of_device_id ft5406_match[] = { + { .compatible = "rpi,rpi-ft5406", }, + {}, +}; +MODULE_DEVICE_TABLE(of, ft5406_match); + +static struct platform_driver ft5406_driver = { + .driver = { + .name = "rpi-ft5406", + .owner = THIS_MODULE, + .of_match_table = ft5406_match, + }, + .probe = ft5406_probe, + .remove = ft5406_remove, +}; + +module_platform_driver(ft5406_driver); + +MODULE_AUTHOR("Gordon Hollingworth"); +MODULE_DESCRIPTION("Touchscreen driver for memory based FT5406"); +MODULE_LICENSE("GPL"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/irqchip/irq-bcm2835.c linux-vendor/drivers/irqchip/irq-bcm2835.c --- linux-4.18.16/drivers/irqchip/irq-bcm2835.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/irqchip/irq-bcm2835.c 2018-10-29 19:31:21.468736852 +0100 @@ -52,9 +52,12 @@ #include #include +#ifndef CONFIG_ARM64 +#include +#endif /* Put the bank and irq (32 bits) into the hwirq */ -#define MAKE_HWIRQ(b, n) ((b << 5) | (n)) +#define MAKE_HWIRQ(b, n) (((b) << 5) | (n)) #define HWIRQ_BANK(i) (i >> 5) #define HWIRQ_BIT(i) BIT(i & 0x1f) @@ -69,10 +72,16 @@ #define BANK0_VALID_MASK (BANK0_HWIRQ_MASK | BANK1_HWIRQ | BANK2_HWIRQ \ | SHORTCUT1_MASK | SHORTCUT2_MASK) +#undef ARM_LOCAL_GPU_INT_ROUTING +#define ARM_LOCAL_GPU_INT_ROUTING 0x0c + #define REG_FIQ_CONTROL 0x0c +#define REG_FIQ_ENABLE 0x80 +#define REG_FIQ_DISABLE 0 #define NR_BANKS 3 #define IRQS_PER_BANK 32 +#define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0) static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; static const int reg_enable[] __initconst = { 0x18, 0x10, 0x14 }; @@ -90,6 +99,7 @@ void __iomem *enable[NR_BANKS]; void __iomem *disable[NR_BANKS]; struct irq_domain *domain; + void __iomem *local_base; }; static struct armctrl_ic intc __read_mostly; @@ -97,20 +107,76 @@ struct pt_regs *regs); static void bcm2836_chained_handle_irq(struct irq_desc *desc); +static inline unsigned int hwirq_to_fiq(unsigned long hwirq) +{ + hwirq -= NUMBER_IRQS; + /* + * The hwirq numbering used in this driver is: + * BASE (0-7) GPU1 (32-63) GPU2 (64-95). + * This differ from the one used in the FIQ register: + * GPU1 (0-31) GPU2 (32-63) BASE (64-71) + */ + if (hwirq >= 32) + return hwirq - 32; + + return hwirq + 64; +} + static void armctrl_mask_irq(struct irq_data *d) { - writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]); + if (d->hwirq >= NUMBER_IRQS) + writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL); + else + writel_relaxed(HWIRQ_BIT(d->hwirq), + intc.disable[HWIRQ_BANK(d->hwirq)]); } static void armctrl_unmask_irq(struct irq_data *d) { - writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]); + if (d->hwirq >= NUMBER_IRQS) { + if (num_online_cpus() > 1) { + unsigned int data; + + if (!intc.local_base) { + pr_err("FIQ is disabled due to missing arm_local_intc\n"); + return; + } + + data = readl_relaxed(intc.local_base + + ARM_LOCAL_GPU_INT_ROUTING); + + data &= ~0xc; + data |= (1 << 2); + writel_relaxed(data, + intc.local_base + + ARM_LOCAL_GPU_INT_ROUTING); + } + + writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq), + intc.base + REG_FIQ_CONTROL); + } else { + writel_relaxed(HWIRQ_BIT(d->hwirq), + intc.enable[HWIRQ_BANK(d->hwirq)]); + } +} + +#ifdef CONFIG_ARM64 +void bcm2836_arm_irqchip_spin_gpu_irq(void); + +static void armctrl_ack_irq(struct irq_data *d) +{ + bcm2836_arm_irqchip_spin_gpu_irq(); } +#endif + static struct irq_chip armctrl_chip = { .name = "ARMCTRL-level", .irq_mask = armctrl_mask_irq, - .irq_unmask = armctrl_unmask_irq + .irq_unmask = armctrl_unmask_irq, +#ifdef CONFIG_ARM64 + .irq_ack = armctrl_ack_irq +#endif }; static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr, @@ -143,14 +209,15 @@ bool is_2836) { void __iomem *base; - int irq, b, i; + int irq = 0, last_irq, b, i; base = of_iomap(node, 0); if (!base) panic("%pOF: unable to map IC registers\n", node); - intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0), - &armctrl_ops, NULL); + intc.base = base; + intc.domain = irq_domain_add_linear(node, NUMBER_IRQS * 2, + &armctrl_ops, NULL); if (!intc.domain) panic("%pOF: unable to create IRQ domain\n", node); @@ -168,6 +235,8 @@ } } + last_irq = irq; + if (is_2836) { int parent_irq = irq_of_parse_and_map(node, 0); @@ -180,6 +249,27 @@ set_handle_irq(bcm2835_handle_irq); } + if (is_2836) { + extern void __iomem * __attribute__((weak)) arm_local_intc; + intc.local_base = arm_local_intc; + if (!intc.local_base) + pr_err("Failed to get local intc base. FIQ is disabled for cpus > 1\n"); + } + + /* Make a duplicate irq range which is used to enable FIQ */ + for (b = 0; b < NR_BANKS; b++) { + for (i = 0; i < bank_irqs[b]; i++) { + irq = irq_create_mapping(intc.domain, + MAKE_HWIRQ(b, i) + NUMBER_IRQS); + BUG_ON(irq <= 0); + irq_set_chip(irq, &armctrl_chip); + irq_set_probe(irq); + } + } +#ifndef CONFIG_ARM64 + init_FIQ(irq - last_irq); +#endif + return 0; } diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/irqchip/irq-bcm2836.c linux-vendor/drivers/irqchip/irq-bcm2836.c --- linux-4.18.16/drivers/irqchip/irq-bcm2836.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/irqchip/irq-bcm2836.c 2018-10-29 19:31:21.468736852 +0100 @@ -30,6 +30,9 @@ static struct bcm2836_arm_irqchip_intc intc __read_mostly; +void __iomem *arm_local_intc; +EXPORT_SYMBOL_GPL(arm_local_intc); + static void bcm2836_arm_irqchip_mask_per_cpu_irq(unsigned int reg_offset, unsigned int bit, int cpu) @@ -92,6 +95,27 @@ { } +#ifdef CONFIG_ARM64 + +void bcm2836_arm_irqchip_spin_gpu_irq(void) +{ + u32 i; + void __iomem *gpurouting = (intc.base + LOCAL_GPU_ROUTING); + u32 routing_val = readl(gpurouting); + + for (i = 1; i <= 3; i++) { + u32 new_routing_val = (routing_val + i) & 3; + + if (cpu_active(new_routing_val)) { + writel(new_routing_val, gpurouting); + return; + } + } +} +EXPORT_SYMBOL(bcm2836_arm_irqchip_spin_gpu_irq); + +#endif + static struct irq_chip bcm2836_arm_irqchip_gpu = { .name = "bcm2836-gpu", .irq_mask = bcm2836_arm_irqchip_mask_gpu_irq, @@ -124,7 +148,7 @@ irq_set_percpu_devid(irq); irq_domain_set_info(d, irq, hw, chip, d->host_data, handle_percpu_devid_irq, NULL, NULL); - irq_set_status_flags(irq, IRQ_NOAUTOEN); + irq_set_status_flags(irq, IRQ_NOAUTOEN | IRQ_TYPE_LEVEL_LOW); return 0; } @@ -144,6 +168,7 @@ u32 ipi = ffs(mbox_val) - 1; writel(1 << ipi, mailbox0); + dsb(sy); handle_IPI(ipi, regs); #endif } else if (stat) { @@ -233,6 +258,8 @@ panic("%pOF: unable to map local interrupt registers\n", node); } + arm_local_intc = intc.base; + bcm2835_init_local_timer_frequency(); intc.domain = irq_domain_add_linear(node, LAST_IRQ + 1, diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/leds/leds-gpio.c linux-vendor/drivers/leds/leds-gpio.c --- linux-4.18.16/drivers/leds/leds-gpio.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/leds/leds-gpio.c 2018-10-29 19:31:21.470736752 +0100 @@ -50,8 +50,15 @@ led_dat->platform_gpio_blink_set(led_dat->gpiod, level, NULL, NULL); led_dat->blinking = 0; + } else if (led_dat->cdev.flags & SET_GPIO_INPUT) { + gpiod_direction_input(led_dat->gpiod); + led_dat->cdev.flags &= ~SET_GPIO_INPUT; + } else if (led_dat->cdev.flags & SET_GPIO_OUTPUT) { + gpiod_direction_output(led_dat->gpiod, level); + led_dat->cdev.flags &= ~SET_GPIO_OUTPUT; } else { - if (led_dat->can_sleep) + if (led_dat->can_sleep || + (led_dat->cdev.flags & (SET_GPIO_INPUT | SET_GPIO_OUTPUT) )) gpiod_set_value_cansleep(led_dat->gpiod, level); else gpiod_set_value(led_dat->gpiod, level); @@ -65,6 +72,13 @@ return 0; } +static enum led_brightness gpio_led_get(struct led_classdev *led_cdev) +{ + struct gpio_led_data *led_dat = + container_of(led_cdev, struct gpio_led_data, cdev); + return gpiod_get_value_cansleep(led_dat->gpiod) ? LED_FULL : LED_OFF; +} + static int gpio_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off) { @@ -122,6 +136,7 @@ led_dat->platform_gpio_blink_set = blink_set; led_dat->cdev.blink_set = gpio_blink_set; } + led_dat->cdev.brightness_get = gpio_led_get; if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) { state = gpiod_get_value_cansleep(led_dat->gpiod); if (state < 0) diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/leds/trigger/Kconfig linux-vendor/drivers/leds/trigger/Kconfig --- linux-4.18.16/drivers/leds/trigger/Kconfig 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/leds/trigger/Kconfig 2018-10-29 19:31:21.471736702 +0100 @@ -125,6 +125,13 @@ This enables direct flash/torch on/off by the driver, kernel space. If unsure, say Y. +config LEDS_TRIGGER_INPUT + tristate "LED Input Trigger" + depends on LEDS_TRIGGERS + help + This allows the GPIOs assigned to be LEDs to be initialised to inputs. + If unsure, say Y. + config LEDS_TRIGGER_PANIC bool "LED Panic Trigger" depends on LEDS_TRIGGERS diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/leds/trigger/ledtrig-input.c linux-vendor/drivers/leds/trigger/ledtrig-input.c --- linux-4.18.16/drivers/leds/trigger/ledtrig-input.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/leds/trigger/ledtrig-input.c 2018-10-29 19:31:21.471736702 +0100 @@ -0,0 +1,54 @@ +/* + * Set LED GPIO to Input "Trigger" + * + * Copyright 2015 Phil Elwell + * + * Based on Nick Forbes's ledtrig-default-on.c. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include "../leds.h" + +static void input_trig_activate(struct led_classdev *led_cdev) +{ + led_cdev->flags |= SET_GPIO_INPUT; + led_set_brightness(led_cdev, 0); +} + +static void input_trig_deactivate(struct led_classdev *led_cdev) +{ + led_cdev->flags |= SET_GPIO_OUTPUT; + led_set_brightness(led_cdev, 0); +} + +static struct led_trigger input_led_trigger = { + .name = "input", + .activate = input_trig_activate, + .deactivate = input_trig_deactivate, +}; + +static int __init input_trig_init(void) +{ + return led_trigger_register(&input_led_trigger); +} + +static void __exit input_trig_exit(void) +{ + led_trigger_unregister(&input_led_trigger); +} + +module_init(input_trig_init); +module_exit(input_trig_exit); + +MODULE_AUTHOR("Phil Elwell "); +MODULE_DESCRIPTION("Set LED GPIO to Input \"trigger\""); +MODULE_LICENSE("GPL"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/leds/trigger/Makefile linux-vendor/drivers/leds/trigger/Makefile --- linux-4.18.16/drivers/leds/trigger/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/leds/trigger/Makefile 2018-10-29 19:31:21.471736702 +0100 @@ -11,5 +11,6 @@ obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o obj-$(CONFIG_LEDS_TRIGGER_TRANSIENT) += ledtrig-transient.o obj-$(CONFIG_LEDS_TRIGGER_CAMERA) += ledtrig-camera.o +obj-$(CONFIG_LEDS_TRIGGER_INPUT) += ledtrig-input.o obj-$(CONFIG_LEDS_TRIGGER_PANIC) += ledtrig-panic.o obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/mailbox/bcm2835-mailbox.c linux-vendor/drivers/mailbox/bcm2835-mailbox.c --- linux-4.18.16/drivers/mailbox/bcm2835-mailbox.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/mailbox/bcm2835-mailbox.c 2018-10-29 19:31:21.477736403 +0100 @@ -51,12 +51,15 @@ #define MAIL1_WRT (ARM_0_MAIL1 + 0x00) #define MAIL1_STA (ARM_0_MAIL1 + 0x18) +/* On ARCH_BCM270x these come through (arm_control.h ) */ +#ifndef ARM_MS_FULL /* Status register: FIFO state. */ #define ARM_MS_FULL BIT(31) #define ARM_MS_EMPTY BIT(30) /* Configuration register: Enable interrupts. */ #define ARM_MC_IHAVEDATAIRQEN BIT(0) +#endif struct bcm2835_mbox { void __iomem *regs; @@ -151,7 +154,7 @@ return -ENOMEM; spin_lock_init(&mbox->lock); - ret = devm_request_irq(dev, irq_of_parse_and_map(dev->of_node, 0), + ret = devm_request_irq(dev, platform_get_irq(pdev, 0), bcm2835_mbox_irq, 0, dev_name(dev), mbox); if (ret) { dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n", @@ -209,7 +212,18 @@ .probe = bcm2835_mbox_probe, .remove = bcm2835_mbox_remove, }; -module_platform_driver(bcm2835_mbox_driver); + +static int __init bcm2835_mbox_init(void) +{ + return platform_driver_register(&bcm2835_mbox_driver); +} +arch_initcall(bcm2835_mbox_init); + +static void __init bcm2835_mbox_exit(void) +{ + platform_driver_unregister(&bcm2835_mbox_driver); +} +module_exit(bcm2835_mbox_exit); MODULE_AUTHOR("Lubomir Rintel "); MODULE_DESCRIPTION("BCM2835 mailbox IPC driver"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/media/spi/Kconfig linux-vendor/drivers/media/spi/Kconfig --- linux-4.18.16/drivers/media/spi/Kconfig 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/media/spi/Kconfig 2018-10-29 19:31:21.572731663 +0100 @@ -19,6 +19,7 @@ config CXD2880_SPI_DRV tristate "Sony CXD2880 SPI support" depends on DVB_CORE && SPI + select DVB_CXD2880 if MEDIA_SUBDRV_AUTOSELECT default m if !MEDIA_SUBDRV_AUTOSELECT help Choose if you would like to have SPI interface support for Sony CXD2880. diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/media/usb/dvb-usb-v2/rtl28xxu.c linux-vendor/drivers/media/usb/dvb-usb-v2/rtl28xxu.c --- linux-4.18.16/drivers/media/usb/dvb-usb-v2/rtl28xxu.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/media/usb/dvb-usb-v2/rtl28xxu.c 2018-10-29 19:31:21.580731265 +0100 @@ -1917,6 +1917,10 @@ &rtl28xxu_props, "Compro VideoMate U650F", NULL) }, { DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd394, &rtl28xxu_props, "MaxMedia HU394-T", NULL) }, + { DVB_USB_DEVICE(USB_VID_GTEK, 0xb803 /*USB_PID_AUGUST_DVBT205*/, + &rtl28xxu_props, "August DVB-T 205", NULL) }, + { DVB_USB_DEVICE(USB_VID_GTEK, 0xa803 /*USB_PID_AUGUST_DVBT205*/, + &rtl28xxu_props, "August DVB-T 205", NULL) }, { DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a03, &rtl28xxu_props, "Leadtek WinFast DTV Dongle mini", NULL) }, { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_CPYTO_REDI_PC50A, diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/mfd/Kconfig linux-vendor/drivers/mfd/Kconfig --- linux-4.18.16/drivers/mfd/Kconfig 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/mfd/Kconfig 2018-10-29 19:31:21.600730267 +0100 @@ -10,6 +10,14 @@ select IRQ_DOMAIN default n +config MFD_RPISENSE_CORE + tristate "Raspberry Pi Sense HAT core functions" + depends on I2C + select MFD_CORE + help + This is the core driver for the Raspberry Pi Sense HAT. This provides + the necessary functions to communicate with the hardware. + config MFD_CS5535 tristate "AMD CS5535 and CS5536 southbridge core functions" select MFD_CORE diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/mfd/Makefile linux-vendor/drivers/mfd/Makefile --- linux-4.18.16/drivers/mfd/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/mfd/Makefile 2018-10-29 19:31:21.601730217 +0100 @@ -227,4 +227,5 @@ obj-$(CONFIG_MFD_MXS_LRADC) += mxs-lradc.o obj-$(CONFIG_MFD_SC27XX_PMIC) += sprd-sc27xx-spi.o obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o +obj-$(CONFIG_MFD_RPISENSE_CORE) += rpisense-core.o diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/mfd/rpisense-core.c linux-vendor/drivers/mfd/rpisense-core.c --- linux-4.18.16/drivers/mfd/rpisense-core.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/mfd/rpisense-core.c 2018-10-29 19:31:21.604730067 +0100 @@ -0,0 +1,157 @@ +/* + * Raspberry Pi Sense HAT core driver + * http://raspberrypi.org + * + * Copyright (C) 2015 Raspberry Pi + * + * Author: Serge Schneider + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This driver is based on wm8350 implementation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct rpisense *rpisense; + +static void rpisense_client_dev_register(struct rpisense *rpisense, + const char *name, + struct platform_device **pdev) +{ + int ret; + + *pdev = platform_device_alloc(name, -1); + if (*pdev == NULL) { + dev_err(rpisense->dev, "Failed to allocate %s\n", name); + return; + } + + (*pdev)->dev.parent = rpisense->dev; + platform_set_drvdata(*pdev, rpisense); + ret = platform_device_add(*pdev); + if (ret != 0) { + dev_err(rpisense->dev, "Failed to register %s: %d\n", + name, ret); + platform_device_put(*pdev); + *pdev = NULL; + } +} + +static int rpisense_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + int ret; + struct rpisense_js *rpisense_js; + + rpisense = devm_kzalloc(&i2c->dev, sizeof(struct rpisense), GFP_KERNEL); + if (rpisense == NULL) + return -ENOMEM; + + i2c_set_clientdata(i2c, rpisense); + rpisense->dev = &i2c->dev; + rpisense->i2c_client = i2c; + + ret = rpisense_reg_read(rpisense, RPISENSE_WAI); + if (ret > 0) { + if (ret != 's') + return -EINVAL; + } else { + return ret; + } + ret = rpisense_reg_read(rpisense, RPISENSE_VER); + if (ret < 0) + return ret; + + dev_info(rpisense->dev, + "Raspberry Pi Sense HAT firmware version %i\n", ret); + + rpisense_js = &rpisense->joystick; + rpisense_js->keys_desc = devm_gpiod_get(&i2c->dev, + "keys-int", GPIOD_IN); + if (IS_ERR(rpisense_js->keys_desc)) { + dev_warn(&i2c->dev, "Failed to get keys-int descriptor.\n"); + rpisense_js->keys_desc = gpio_to_desc(23); + if (rpisense_js->keys_desc == NULL) { + dev_err(&i2c->dev, "GPIO23 fallback failed.\n"); + return PTR_ERR(rpisense_js->keys_desc); + } + } + rpisense_client_dev_register(rpisense, "rpi-sense-js", + &(rpisense->joystick.pdev)); + rpisense_client_dev_register(rpisense, "rpi-sense-fb", + &(rpisense->framebuffer.pdev)); + + return 0; +} + +static int rpisense_remove(struct i2c_client *i2c) +{ + struct rpisense *rpisense = i2c_get_clientdata(i2c); + + platform_device_unregister(rpisense->joystick.pdev); + return 0; +} + +struct rpisense *rpisense_get_dev(void) +{ + return rpisense; +} +EXPORT_SYMBOL_GPL(rpisense_get_dev); + +s32 rpisense_reg_read(struct rpisense *rpisense, int reg) +{ + int ret = i2c_smbus_read_byte_data(rpisense->i2c_client, reg); + + if (ret < 0) + dev_err(rpisense->dev, "Read from reg %d failed\n", reg); + /* Due to the BCM270x I2C clock stretching bug, some values + * may have MSB set. Clear it to avoid incorrect values. + * */ + return ret & 0x7F; +} +EXPORT_SYMBOL_GPL(rpisense_reg_read); + +int rpisense_block_write(struct rpisense *rpisense, const char *buf, int count) +{ + int ret = i2c_master_send(rpisense->i2c_client, buf, count); + + if (ret < 0) + dev_err(rpisense->dev, "Block write failed\n"); + return ret; +} +EXPORT_SYMBOL_GPL(rpisense_block_write); + +static const struct i2c_device_id rpisense_i2c_id[] = { + { "rpi-sense", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, rpisense_i2c_id); + + +static struct i2c_driver rpisense_driver = { + .driver = { + .name = "rpi-sense", + .owner = THIS_MODULE, + }, + .probe = rpisense_probe, + .remove = rpisense_remove, + .id_table = rpisense_i2c_id, +}; + +module_i2c_driver(rpisense_driver); + +MODULE_DESCRIPTION("Raspberry Pi Sense HAT core driver"); +MODULE_AUTHOR("Serge Schneider "); +MODULE_LICENSE("GPL"); + diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/misc/bcm2835_smi.c linux-vendor/drivers/misc/bcm2835_smi.c --- linux-4.18.16/drivers/misc/bcm2835_smi.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/misc/bcm2835_smi.c 2018-10-29 19:31:21.607729917 +0100 @@ -0,0 +1,955 @@ +/** + * Broadcom Secondary Memory Interface driver + * + * Written by Luke Wren + * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2, as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BCM2835_SMI_IMPLEMENTATION +#include + +#define DRIVER_NAME "smi-bcm2835" + +#define N_PAGES_FROM_BYTES(n) ((n + PAGE_SIZE-1) / PAGE_SIZE) + +#define DMA_WRITE_TO_MEM true +#define DMA_READ_FROM_MEM false + +struct bcm2835_smi_instance { + struct device *dev; + struct smi_settings settings; + __iomem void *smi_regs_ptr; + dma_addr_t smi_regs_busaddr; + + struct dma_chan *dma_chan; + struct dma_slave_config dma_config; + + struct bcm2835_smi_bounce_info bounce; + + struct scatterlist buffer_sgl; + + struct clk *clk; + + /* Sometimes we are called into in an atomic context (e.g. by + JFFS2 + MTD) so we can't use a mutex */ + spinlock_t transaction_lock; +}; + +/**************************************************************************** +* +* SMI peripheral setup +* +***************************************************************************/ + +static inline void write_smi_reg(struct bcm2835_smi_instance *inst, + u32 val, unsigned reg) +{ + writel(val, inst->smi_regs_ptr + reg); +} + +static inline u32 read_smi_reg(struct bcm2835_smi_instance *inst, unsigned reg) +{ + return readl(inst->smi_regs_ptr + reg); +} + +/* Token-paste macro for e.g SMIDSR_RSTROBE -> value of SMIDSR_RSTROBE_MASK */ +#define _CONCAT(x, y) x##y +#define CONCAT(x, y) _CONCAT(x, y) + +#define SET_BIT_FIELD(dest, field, bits) ((dest) = \ + ((dest) & ~CONCAT(field, _MASK)) | (((bits) << CONCAT(field, _OFFS))& \ + CONCAT(field, _MASK))) +#define GET_BIT_FIELD(src, field) (((src) & \ + CONCAT(field, _MASK)) >> CONCAT(field, _OFFS)) + +static void smi_dump_context_labelled(struct bcm2835_smi_instance *inst, + const char *label) +{ + dev_err(inst->dev, "SMI context dump: %s", label); + dev_err(inst->dev, "SMICS: 0x%08x", read_smi_reg(inst, SMICS)); + dev_err(inst->dev, "SMIL: 0x%08x", read_smi_reg(inst, SMIL)); + dev_err(inst->dev, "SMIDSR: 0x%08x", read_smi_reg(inst, SMIDSR0)); + dev_err(inst->dev, "SMIDSW: 0x%08x", read_smi_reg(inst, SMIDSW0)); + dev_err(inst->dev, "SMIDC: 0x%08x", read_smi_reg(inst, SMIDC)); + dev_err(inst->dev, "SMIFD: 0x%08x", read_smi_reg(inst, SMIFD)); + dev_err(inst->dev, " "); +} + +static inline void smi_dump_context(struct bcm2835_smi_instance *inst) +{ + smi_dump_context_labelled(inst, ""); +} + +static void smi_get_default_settings(struct bcm2835_smi_instance *inst) +{ + struct smi_settings *settings = &inst->settings; + + settings->data_width = SMI_WIDTH_16BIT; + settings->pack_data = true; + + settings->read_setup_time = 1; + settings->read_hold_time = 1; + settings->read_pace_time = 1; + settings->read_strobe_time = 3; + + settings->write_setup_time = settings->read_setup_time; + settings->write_hold_time = settings->read_hold_time; + settings->write_pace_time = settings->read_pace_time; + settings->write_strobe_time = settings->read_strobe_time; + + settings->dma_enable = true; + settings->dma_passthrough_enable = false; + settings->dma_read_thresh = 0x01; + settings->dma_write_thresh = 0x3f; + settings->dma_panic_read_thresh = 0x20; + settings->dma_panic_write_thresh = 0x20; +} + +void bcm2835_smi_set_regs_from_settings(struct bcm2835_smi_instance *inst) +{ + struct smi_settings *settings = &inst->settings; + int smidsr_temp = 0, smidsw_temp = 0, smics_temp, + smidcs_temp, smidc_temp = 0; + + spin_lock(&inst->transaction_lock); + + /* temporarily disable the peripheral: */ + smics_temp = read_smi_reg(inst, SMICS); + write_smi_reg(inst, 0, SMICS); + smidcs_temp = read_smi_reg(inst, SMIDCS); + write_smi_reg(inst, 0, SMIDCS); + + if (settings->pack_data) + smics_temp |= SMICS_PXLDAT; + else + smics_temp &= ~SMICS_PXLDAT; + + SET_BIT_FIELD(smidsr_temp, SMIDSR_RWIDTH, settings->data_width); + SET_BIT_FIELD(smidsr_temp, SMIDSR_RSETUP, settings->read_setup_time); + SET_BIT_FIELD(smidsr_temp, SMIDSR_RHOLD, settings->read_hold_time); + SET_BIT_FIELD(smidsr_temp, SMIDSR_RPACE, settings->read_pace_time); + SET_BIT_FIELD(smidsr_temp, SMIDSR_RSTROBE, settings->read_strobe_time); + write_smi_reg(inst, smidsr_temp, SMIDSR0); + + SET_BIT_FIELD(smidsw_temp, SMIDSW_WWIDTH, settings->data_width); + if (settings->data_width == SMI_WIDTH_8BIT) + smidsw_temp |= SMIDSW_WSWAP; + else + smidsw_temp &= ~SMIDSW_WSWAP; + SET_BIT_FIELD(smidsw_temp, SMIDSW_WSETUP, settings->write_setup_time); + SET_BIT_FIELD(smidsw_temp, SMIDSW_WHOLD, settings->write_hold_time); + SET_BIT_FIELD(smidsw_temp, SMIDSW_WPACE, settings->write_pace_time); + SET_BIT_FIELD(smidsw_temp, SMIDSW_WSTROBE, + settings->write_strobe_time); + write_smi_reg(inst, smidsw_temp, SMIDSW0); + + SET_BIT_FIELD(smidc_temp, SMIDC_REQR, settings->dma_read_thresh); + SET_BIT_FIELD(smidc_temp, SMIDC_REQW, settings->dma_write_thresh); + SET_BIT_FIELD(smidc_temp, SMIDC_PANICR, + settings->dma_panic_read_thresh); + SET_BIT_FIELD(smidc_temp, SMIDC_PANICW, + settings->dma_panic_write_thresh); + if (settings->dma_passthrough_enable) { + smidc_temp |= SMIDC_DMAP; + smidsr_temp |= SMIDSR_RDREQ; + write_smi_reg(inst, smidsr_temp, SMIDSR0); + smidsw_temp |= SMIDSW_WDREQ; + write_smi_reg(inst, smidsw_temp, SMIDSW0); + } else + smidc_temp &= ~SMIDC_DMAP; + if (settings->dma_enable) + smidc_temp |= SMIDC_DMAEN; + else + smidc_temp &= ~SMIDC_DMAEN; + + write_smi_reg(inst, smidc_temp, SMIDC); + + /* re-enable (if was previously enabled) */ + write_smi_reg(inst, smics_temp, SMICS); + write_smi_reg(inst, smidcs_temp, SMIDCS); + + spin_unlock(&inst->transaction_lock); +} +EXPORT_SYMBOL(bcm2835_smi_set_regs_from_settings); + +struct smi_settings *bcm2835_smi_get_settings_from_regs + (struct bcm2835_smi_instance *inst) +{ + struct smi_settings *settings = &inst->settings; + int smidsr, smidsw, smidc; + + spin_lock(&inst->transaction_lock); + + smidsr = read_smi_reg(inst, SMIDSR0); + smidsw = read_smi_reg(inst, SMIDSW0); + smidc = read_smi_reg(inst, SMIDC); + + settings->pack_data = (read_smi_reg(inst, SMICS) & SMICS_PXLDAT) ? + true : false; + + settings->data_width = GET_BIT_FIELD(smidsr, SMIDSR_RWIDTH); + settings->read_setup_time = GET_BIT_FIELD(smidsr, SMIDSR_RSETUP); + settings->read_hold_time = GET_BIT_FIELD(smidsr, SMIDSR_RHOLD); + settings->read_pace_time = GET_BIT_FIELD(smidsr, SMIDSR_RPACE); + settings->read_strobe_time = GET_BIT_FIELD(smidsr, SMIDSR_RSTROBE); + + settings->write_setup_time = GET_BIT_FIELD(smidsw, SMIDSW_WSETUP); + settings->write_hold_time = GET_BIT_FIELD(smidsw, SMIDSW_WHOLD); + settings->write_pace_time = GET_BIT_FIELD(smidsw, SMIDSW_WPACE); + settings->write_strobe_time = GET_BIT_FIELD(smidsw, SMIDSW_WSTROBE); + + settings->dma_read_thresh = GET_BIT_FIELD(smidc, SMIDC_REQR); + settings->dma_write_thresh = GET_BIT_FIELD(smidc, SMIDC_REQW); + settings->dma_panic_read_thresh = GET_BIT_FIELD(smidc, SMIDC_PANICR); + settings->dma_panic_write_thresh = GET_BIT_FIELD(smidc, SMIDC_PANICW); + settings->dma_passthrough_enable = (smidc & SMIDC_DMAP) ? true : false; + settings->dma_enable = (smidc & SMIDC_DMAEN) ? true : false; + + spin_unlock(&inst->transaction_lock); + + return settings; +} +EXPORT_SYMBOL(bcm2835_smi_get_settings_from_regs); + +static inline void smi_set_address(struct bcm2835_smi_instance *inst, + unsigned int address) +{ + int smia_temp = 0, smida_temp = 0; + + SET_BIT_FIELD(smia_temp, SMIA_ADDR, address); + SET_BIT_FIELD(smida_temp, SMIDA_ADDR, address); + + /* Write to both address registers - user doesn't care whether we're + doing programmed or direct transfers. */ + write_smi_reg(inst, smia_temp, SMIA); + write_smi_reg(inst, smida_temp, SMIDA); +} + +static void smi_setup_regs(struct bcm2835_smi_instance *inst) +{ + + dev_dbg(inst->dev, "Initialising SMI registers..."); + /* Disable the peripheral if already enabled */ + write_smi_reg(inst, 0, SMICS); + write_smi_reg(inst, 0, SMIDCS); + + smi_get_default_settings(inst); + bcm2835_smi_set_regs_from_settings(inst); + smi_set_address(inst, 0); + + write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_ENABLE, SMICS); + write_smi_reg(inst, read_smi_reg(inst, SMIDCS) | SMIDCS_ENABLE, + SMIDCS); +} + +/**************************************************************************** +* +* Low-level SMI access functions +* Other modules should use the exported higher-level functions e.g. +* bcm2835_smi_write_buf() unless they have a good reason to use these +* +***************************************************************************/ + +static inline uint32_t smi_read_single_word(struct bcm2835_smi_instance *inst) +{ + int timeout = 0; + + write_smi_reg(inst, SMIDCS_ENABLE, SMIDCS); + write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_START, SMIDCS); + /* Make sure things happen in the right order...*/ + mb(); + while (!(read_smi_reg(inst, SMIDCS) & SMIDCS_DONE) && + ++timeout < 10000) + ; + if (timeout < 10000) + return read_smi_reg(inst, SMIDD); + + dev_err(inst->dev, + "SMI direct read timed out (is the clock set up correctly?)"); + return 0; +} + +static inline void smi_write_single_word(struct bcm2835_smi_instance *inst, + uint32_t data) +{ + int timeout = 0; + + write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_WRITE, SMIDCS); + write_smi_reg(inst, data, SMIDD); + write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_WRITE | SMIDCS_START, + SMIDCS); + + while (!(read_smi_reg(inst, SMIDCS) & SMIDCS_DONE) && + ++timeout < 10000) + ; + if (timeout >= 10000) + dev_err(inst->dev, + "SMI direct write timed out (is the clock set up correctly?)"); +} + +/* Initiates a programmed read into the read FIFO. It is up to the caller to + * read data from the FIFO - either via paced DMA transfer, + * or polling SMICS_RXD to check whether data is available. + * SMICS_ACTIVE will go low upon completion. */ +static void smi_init_programmed_read(struct bcm2835_smi_instance *inst, + int num_transfers) +{ + int smics_temp; + + /* Disable the peripheral: */ + smics_temp = read_smi_reg(inst, SMICS) & ~(SMICS_ENABLE | SMICS_WRITE); + write_smi_reg(inst, smics_temp, SMICS); + while (read_smi_reg(inst, SMICS) & SMICS_ENABLE) + ; + + /* Program the transfer count: */ + write_smi_reg(inst, num_transfers, SMIL); + + /* re-enable and start: */ + smics_temp |= SMICS_ENABLE; + write_smi_reg(inst, smics_temp, SMICS); + smics_temp |= SMICS_CLEAR; + /* Just to be certain: */ + mb(); + while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) + ; + write_smi_reg(inst, smics_temp, SMICS); + smics_temp |= SMICS_START; + write_smi_reg(inst, smics_temp, SMICS); +} + +/* Initiates a programmed write sequence, using data from the write FIFO. + * It is up to the caller to initiate a DMA transfer before calling, + * or use another method to keep the write FIFO topped up. + * SMICS_ACTIVE will go low upon completion. + */ +static void smi_init_programmed_write(struct bcm2835_smi_instance *inst, + int num_transfers) +{ + int smics_temp; + + /* Disable the peripheral: */ + smics_temp = read_smi_reg(inst, SMICS) & ~SMICS_ENABLE; + write_smi_reg(inst, smics_temp, SMICS); + while (read_smi_reg(inst, SMICS) & SMICS_ENABLE) + ; + + /* Program the transfer count: */ + write_smi_reg(inst, num_transfers, SMIL); + + /* setup, re-enable and start: */ + smics_temp |= SMICS_WRITE | SMICS_ENABLE; + write_smi_reg(inst, smics_temp, SMICS); + smics_temp |= SMICS_START; + write_smi_reg(inst, smics_temp, SMICS); +} + +/* Initiate a read and then poll FIFO for data, reading out as it appears. */ +static void smi_read_fifo(struct bcm2835_smi_instance *inst, + uint32_t *dest, int n_bytes) +{ + if (read_smi_reg(inst, SMICS) & SMICS_RXD) { + smi_dump_context_labelled(inst, + "WARNING: read FIFO not empty at start of read call."); + while (read_smi_reg(inst, SMICS)) + ; + } + + /* Dispatch the read: */ + if (inst->settings.data_width == SMI_WIDTH_8BIT) + smi_init_programmed_read(inst, n_bytes); + else if (inst->settings.data_width == SMI_WIDTH_16BIT) + smi_init_programmed_read(inst, n_bytes / 2); + else { + dev_err(inst->dev, "Unsupported data width for read."); + return; + } + + /* Poll FIFO to keep it empty */ + while (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) + if (read_smi_reg(inst, SMICS) & SMICS_RXD) + *dest++ = read_smi_reg(inst, SMID); + + /* Ensure that the FIFO is emptied */ + if (read_smi_reg(inst, SMICS) & SMICS_RXD) { + int fifo_count; + + fifo_count = GET_BIT_FIELD(read_smi_reg(inst, SMIFD), + SMIFD_FCNT); + while (fifo_count--) + *dest++ = read_smi_reg(inst, SMID); + } + + if (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) + smi_dump_context_labelled(inst, + "WARNING: transaction finished but done bit not set."); + + if (read_smi_reg(inst, SMICS) & SMICS_RXD) + smi_dump_context_labelled(inst, + "WARNING: read FIFO not empty at end of read call."); + +} + +/* Initiate a write, and then keep the FIFO topped up. */ +static void smi_write_fifo(struct bcm2835_smi_instance *inst, + uint32_t *src, int n_bytes) +{ + int i, timeout = 0; + + /* Empty FIFOs if not already so */ + if (!(read_smi_reg(inst, SMICS) & SMICS_TXE)) { + smi_dump_context_labelled(inst, + "WARNING: write fifo not empty at start of write call."); + write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_CLEAR, + SMICS); + } + + /* Initiate the transfer */ + if (inst->settings.data_width == SMI_WIDTH_8BIT) + smi_init_programmed_write(inst, n_bytes); + else if (inst->settings.data_width == SMI_WIDTH_16BIT) + smi_init_programmed_write(inst, n_bytes / 2); + else { + dev_err(inst->dev, "Unsupported data width for write."); + return; + } + /* Fill the FIFO: */ + for (i = 0; i < (n_bytes - 1) / 4 + 1; ++i) { + while (!(read_smi_reg(inst, SMICS) & SMICS_TXD)) + ; + write_smi_reg(inst, *src++, SMID); + } + /* Busy wait... */ + while (!(read_smi_reg(inst, SMICS) & SMICS_DONE) && ++timeout < + 1000000) + ; + if (timeout >= 1000000) + smi_dump_context_labelled(inst, + "Timed out on write operation!"); + if (!(read_smi_reg(inst, SMICS) & SMICS_TXE)) + smi_dump_context_labelled(inst, + "WARNING: FIFO not empty at end of write operation."); +} + +/**************************************************************************** +* +* SMI DMA operations +* +***************************************************************************/ + +/* Disable SMI and put it into the correct direction before doing DMA setup. + Stops spurious DREQs during setup. Peripheral is re-enabled by init_*() */ +static void smi_disable(struct bcm2835_smi_instance *inst, + enum dma_transfer_direction direction) +{ + int smics_temp = read_smi_reg(inst, SMICS) & ~SMICS_ENABLE; + + if (direction == DMA_DEV_TO_MEM) + smics_temp &= ~SMICS_WRITE; + else + smics_temp |= SMICS_WRITE; + write_smi_reg(inst, smics_temp, SMICS); + while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) + ; +} + +static struct scatterlist *smi_scatterlist_from_buffer( + struct bcm2835_smi_instance *inst, + dma_addr_t buf, + size_t len, + struct scatterlist *sg) +{ + sg_init_table(sg, 1); + sg_dma_address(sg) = buf; + sg_dma_len(sg) = len; + return sg; +} + +static void smi_dma_callback_user_copy(void *param) +{ + /* Notify the bottom half that a chunk is ready for user copy */ + struct bcm2835_smi_instance *inst = + (struct bcm2835_smi_instance *)param; + + up(&inst->bounce.callback_sem); +} + +/* Creates a descriptor, assigns the given callback, and submits the + descriptor to dmaengine. Does not block - can queue up multiple + descriptors and then wait for them all to complete. + sg_len is the number of control blocks, NOT the number of bytes. + dir can be DMA_MEM_TO_DEV or DMA_DEV_TO_MEM. + callback can be NULL - in this case it is not called. */ +static inline struct dma_async_tx_descriptor *smi_dma_submit_sgl( + struct bcm2835_smi_instance *inst, + struct scatterlist *sgl, + size_t sg_len, + enum dma_transfer_direction dir, + dma_async_tx_callback callback) +{ + struct dma_async_tx_descriptor *desc; + + desc = dmaengine_prep_slave_sg(inst->dma_chan, + sgl, + sg_len, + dir, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK | + DMA_PREP_FENCE); + if (!desc) { + dev_err(inst->dev, "read_sgl: dma slave preparation failed!"); + write_smi_reg(inst, read_smi_reg(inst, SMICS) & ~SMICS_ACTIVE, + SMICS); + while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE) + cpu_relax(); + write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_ACTIVE, + SMICS); + return NULL; + } + desc->callback = callback; + desc->callback_param = inst; + if (dmaengine_submit(desc) < 0) + return NULL; + return desc; +} + +/* NB this function blocks until the transfer is complete */ +static void +smi_dma_read_sgl(struct bcm2835_smi_instance *inst, + struct scatterlist *sgl, size_t sg_len, size_t n_bytes) +{ + struct dma_async_tx_descriptor *desc; + + /* Disable SMI and set to read before dispatching DMA - if SMI is in + * write mode and TX fifo is empty, it will generate a DREQ which may + * cause the read DMA to complete before the SMI read command is even + * dispatched! We want to dispatch DMA before SMI read so that reading + * is gapless, for logic analyser. + */ + + smi_disable(inst, DMA_DEV_TO_MEM); + + desc = smi_dma_submit_sgl(inst, sgl, sg_len, DMA_DEV_TO_MEM, NULL); + dma_async_issue_pending(inst->dma_chan); + + if (inst->settings.data_width == SMI_WIDTH_8BIT) + smi_init_programmed_read(inst, n_bytes); + else + smi_init_programmed_read(inst, n_bytes / 2); + + if (dma_wait_for_async_tx(desc) == DMA_ERROR) + smi_dump_context_labelled(inst, "DMA timeout!"); +} + +static void +smi_dma_write_sgl(struct bcm2835_smi_instance *inst, + struct scatterlist *sgl, size_t sg_len, size_t n_bytes) +{ + struct dma_async_tx_descriptor *desc; + + if (inst->settings.data_width == SMI_WIDTH_8BIT) + smi_init_programmed_write(inst, n_bytes); + else + smi_init_programmed_write(inst, n_bytes / 2); + + desc = smi_dma_submit_sgl(inst, sgl, sg_len, DMA_MEM_TO_DEV, NULL); + dma_async_issue_pending(inst->dma_chan); + + if (dma_wait_for_async_tx(desc) == DMA_ERROR) + smi_dump_context_labelled(inst, "DMA timeout!"); + else + /* Wait for SMI to finish our writes */ + while (!(read_smi_reg(inst, SMICS) & SMICS_DONE)) + cpu_relax(); +} + +ssize_t bcm2835_smi_user_dma( + struct bcm2835_smi_instance *inst, + enum dma_transfer_direction dma_dir, + char __user *user_ptr, size_t count, + struct bcm2835_smi_bounce_info **bounce) +{ + int chunk_no = 0, chunk_size, count_left = count; + struct scatterlist *sgl; + void (*init_trans_func)(struct bcm2835_smi_instance *, int); + + spin_lock(&inst->transaction_lock); + + if (dma_dir == DMA_DEV_TO_MEM) + init_trans_func = smi_init_programmed_read; + else + init_trans_func = smi_init_programmed_write; + + smi_disable(inst, dma_dir); + + sema_init(&inst->bounce.callback_sem, 0); + if (bounce) + *bounce = &inst->bounce; + while (count_left) { + chunk_size = count_left > DMA_BOUNCE_BUFFER_SIZE ? + DMA_BOUNCE_BUFFER_SIZE : count_left; + if (chunk_size == DMA_BOUNCE_BUFFER_SIZE) { + sgl = + &inst->bounce.sgl[chunk_no % DMA_BOUNCE_BUFFER_COUNT]; + } else { + sgl = smi_scatterlist_from_buffer( + inst, + inst->bounce.phys[ + chunk_no % DMA_BOUNCE_BUFFER_COUNT], + chunk_size, + &inst->buffer_sgl); + } + + if (!smi_dma_submit_sgl(inst, sgl, 1, dma_dir, + smi_dma_callback_user_copy + )) { + dev_err(inst->dev, "sgl submit failed"); + count = 0; + goto out; + } + count_left -= chunk_size; + chunk_no++; + } + dma_async_issue_pending(inst->dma_chan); + + if (inst->settings.data_width == SMI_WIDTH_8BIT) + init_trans_func(inst, count); + else if (inst->settings.data_width == SMI_WIDTH_16BIT) + init_trans_func(inst, count / 2); +out: + spin_unlock(&inst->transaction_lock); + return count; +} +EXPORT_SYMBOL(bcm2835_smi_user_dma); + + +/**************************************************************************** +* +* High level buffer transfer functions - for use by other drivers +* +***************************************************************************/ + +/* Buffer must be physically contiguous - i.e. kmalloc, not vmalloc! */ +void bcm2835_smi_write_buf( + struct bcm2835_smi_instance *inst, + const void *buf, size_t n_bytes) +{ + int odd_bytes = n_bytes & 0x3; + + n_bytes -= odd_bytes; + + spin_lock(&inst->transaction_lock); + + if (n_bytes > DMA_THRESHOLD_BYTES) { + dma_addr_t phy_addr = dma_map_single( + inst->dev, + (void *)buf, + n_bytes, + DMA_MEM_TO_DEV); + struct scatterlist *sgl = + smi_scatterlist_from_buffer(inst, phy_addr, n_bytes, + &inst->buffer_sgl); + + if (!sgl) { + smi_dump_context_labelled(inst, + "Error: could not create scatterlist for write!"); + goto out; + } + smi_dma_write_sgl(inst, sgl, 1, n_bytes); + + dma_unmap_single + (inst->dev, phy_addr, n_bytes, DMA_MEM_TO_DEV); + } else if (n_bytes) { + smi_write_fifo(inst, (uint32_t *) buf, n_bytes); + } + buf += n_bytes; + + if (inst->settings.data_width == SMI_WIDTH_8BIT) { + while (odd_bytes--) + smi_write_single_word(inst, *(uint8_t *) (buf++)); + } else { + while (odd_bytes >= 2) { + smi_write_single_word(inst, *(uint16_t *)buf); + buf += 2; + odd_bytes -= 2; + } + if (odd_bytes) { + /* Reading an odd number of bytes on a 16 bit bus is + a user bug. It's kinder to fail early and tell them + than to e.g. transparently give them the bottom byte + of a 16 bit transfer. */ + dev_err(inst->dev, + "WARNING: odd number of bytes specified for wide transfer."); + dev_err(inst->dev, + "At least one byte dropped as a result."); + dump_stack(); + } + } +out: + spin_unlock(&inst->transaction_lock); +} +EXPORT_SYMBOL(bcm2835_smi_write_buf); + +void bcm2835_smi_read_buf(struct bcm2835_smi_instance *inst, + void *buf, size_t n_bytes) +{ + + /* SMI is inherently 32-bit, which causes surprising amounts of mess + for bytes % 4 != 0. Easiest to avoid this mess altogether + by handling remainder separately. */ + int odd_bytes = n_bytes & 0x3; + + spin_lock(&inst->transaction_lock); + n_bytes -= odd_bytes; + if (n_bytes > DMA_THRESHOLD_BYTES) { + dma_addr_t phy_addr = dma_map_single(inst->dev, + buf, n_bytes, + DMA_DEV_TO_MEM); + struct scatterlist *sgl = smi_scatterlist_from_buffer( + inst, phy_addr, n_bytes, + &inst->buffer_sgl); + if (!sgl) { + smi_dump_context_labelled(inst, + "Error: could not create scatterlist for read!"); + goto out; + } + smi_dma_read_sgl(inst, sgl, 1, n_bytes); + dma_unmap_single(inst->dev, phy_addr, n_bytes, DMA_DEV_TO_MEM); + } else if (n_bytes) { + smi_read_fifo(inst, (uint32_t *)buf, n_bytes); + } + buf += n_bytes; + + if (inst->settings.data_width == SMI_WIDTH_8BIT) { + while (odd_bytes--) + *((uint8_t *) (buf++)) = smi_read_single_word(inst); + } else { + while (odd_bytes >= 2) { + *(uint16_t *) buf = smi_read_single_word(inst); + buf += 2; + odd_bytes -= 2; + } + if (odd_bytes) { + dev_err(inst->dev, + "WARNING: odd number of bytes specified for wide transfer."); + dev_err(inst->dev, + "At least one byte dropped as a result."); + dump_stack(); + } + } +out: + spin_unlock(&inst->transaction_lock); +} +EXPORT_SYMBOL(bcm2835_smi_read_buf); + +void bcm2835_smi_set_address(struct bcm2835_smi_instance *inst, + unsigned int address) +{ + spin_lock(&inst->transaction_lock); + smi_set_address(inst, address); + spin_unlock(&inst->transaction_lock); +} +EXPORT_SYMBOL(bcm2835_smi_set_address); + +struct bcm2835_smi_instance *bcm2835_smi_get(struct device_node *node) +{ + struct platform_device *pdev; + + if (!node) + return NULL; + + pdev = of_find_device_by_node(node); + if (!pdev) + return NULL; + + return platform_get_drvdata(pdev); +} +EXPORT_SYMBOL(bcm2835_smi_get); + +/**************************************************************************** +* +* bcm2835_smi_probe - called when the driver is loaded. +* +***************************************************************************/ + +static int bcm2835_smi_dma_setup(struct bcm2835_smi_instance *inst) +{ + int i, rv = 0; + + inst->dma_chan = dma_request_slave_channel(inst->dev, "rx-tx"); + + inst->dma_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + inst->dma_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + inst->dma_config.src_addr = inst->smi_regs_busaddr + SMID; + inst->dma_config.dst_addr = inst->dma_config.src_addr; + /* Direction unimportant - always overridden by prep_slave_sg */ + inst->dma_config.direction = DMA_DEV_TO_MEM; + dmaengine_slave_config(inst->dma_chan, &inst->dma_config); + /* Alloc and map bounce buffers */ + for (i = 0; i < DMA_BOUNCE_BUFFER_COUNT; ++i) { + inst->bounce.buffer[i] = + dmam_alloc_coherent(inst->dev, DMA_BOUNCE_BUFFER_SIZE, + &inst->bounce.phys[i], + GFP_KERNEL); + if (!inst->bounce.buffer[i]) { + dev_err(inst->dev, "Could not allocate buffer!"); + rv = -ENOMEM; + break; + } + smi_scatterlist_from_buffer( + inst, + inst->bounce.phys[i], + DMA_BOUNCE_BUFFER_SIZE, + &inst->bounce.sgl[i] + ); + } + + return rv; +} + +static int bcm2835_smi_probe(struct platform_device *pdev) +{ + int err; + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct resource *ioresource; + struct bcm2835_smi_instance *inst; + const __be32 *addr; + + /* We require device tree support */ + if (!node) + return -EINVAL; + /* Allocate buffers and instance data */ + inst = devm_kzalloc(dev, sizeof(struct bcm2835_smi_instance), + GFP_KERNEL); + if (!inst) + return -ENOMEM; + + inst->dev = dev; + spin_lock_init(&inst->transaction_lock); + + ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); + inst->smi_regs_ptr = devm_ioremap_resource(dev, ioresource); + if (IS_ERR(inst->smi_regs_ptr)) { + err = PTR_ERR(inst->smi_regs_ptr); + goto err; + } + addr = of_get_address(node, 0, NULL, NULL); + inst->smi_regs_busaddr = be32_to_cpu(addr); + + err = bcm2835_smi_dma_setup(inst); + if (err) + goto err; + + /* request clock */ + inst->clk = devm_clk_get(dev, NULL); + if (!inst->clk) + goto err; + clk_prepare_enable(inst->clk); + + /* Finally, do peripheral setup */ + smi_setup_regs(inst); + + platform_set_drvdata(pdev, inst); + + dev_info(inst->dev, "initialised"); + + return 0; +err: + kfree(inst); + return err; +} + +/**************************************************************************** +* +* bcm2835_smi_remove - called when the driver is unloaded. +* +***************************************************************************/ + +static int bcm2835_smi_remove(struct platform_device *pdev) +{ + struct bcm2835_smi_instance *inst = platform_get_drvdata(pdev); + struct device *dev = inst->dev; + + dmaengine_terminate_all(inst->dma_chan); + dma_release_channel(inst->dma_chan); + + clk_disable_unprepare(inst->clk); + + dev_info(dev, "SMI device removed - OK"); + return 0; +} + +/**************************************************************************** +* +* Register the driver with device tree +* +***************************************************************************/ + +static const struct of_device_id bcm2835_smi_of_match[] = { + {.compatible = "brcm,bcm2835-smi",}, + { /* sentinel */ }, +}; + +MODULE_DEVICE_TABLE(of, bcm2835_smi_of_match); + +static struct platform_driver bcm2835_smi_driver = { + .probe = bcm2835_smi_probe, + .remove = bcm2835_smi_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = bcm2835_smi_of_match, + }, +}; + +module_platform_driver(bcm2835_smi_driver); + +MODULE_ALIAS("platform:smi-bcm2835"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Device driver for BCM2835's secondary memory interface"); +MODULE_AUTHOR("Luke Wren "); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/misc/Kconfig linux-vendor/drivers/misc/Kconfig --- linux-4.18.16/drivers/misc/Kconfig 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/misc/Kconfig 2018-10-29 19:31:21.606729967 +0100 @@ -10,6 +10,14 @@ select INPUT_POLLDEV default n +config BCM2835_SMI + tristate "Broadcom 283x Secondary Memory Interface driver" + depends on ARCH_BCM2835 + default m + help + Driver for enabling and using Broadcom's Secondary/Slow Memory Interface. + Appears as /dev/bcm2835_smi. For ioctl interface see drivers/misc/bcm2835_smi.h + config AD525X_DPOT tristate "Analog Devices Digital Potentiometers" depends on (I2C || SPI) && SYSFS diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/misc/Makefile linux-vendor/drivers/misc/Makefile --- linux-4.18.16/drivers/misc/Makefile 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/misc/Makefile 2018-10-29 19:31:21.606729967 +0100 @@ -11,6 +11,7 @@ obj-$(CONFIG_INTEL_MID_PTI) += pti.o obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o +obj-$(CONFIG_BCM2835_SMI) += bcm2835_smi.o obj-$(CONFIG_DUMMY_IRQ) += dummy-irq.o obj-$(CONFIG_ICS932S401) += ics932s401.o obj-$(CONFIG_LKDTM) += lkdtm/ diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/mmc/core/block.c linux-vendor/drivers/mmc/core/block.c --- linux-4.18.16/drivers/mmc/core/block.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/mmc/core/block.c 2018-10-29 19:31:21.633728621 +0100 @@ -167,6 +167,13 @@ module_param(perdev_minors, int, 0444); MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device"); +/* + * Allow quirks to be overridden for the current card + */ +static char *card_quirks; +module_param(card_quirks, charp, 0644); +MODULE_PARM_DESC(card_quirks, "Force the use of the indicated quirks (a bitfield)"); + static inline int mmc_blk_part_switch(struct mmc_card *card, unsigned int part_type); @@ -2914,6 +2921,7 @@ { struct mmc_blk_data *md, *part_md; char cap_str[10]; + char quirk_str[24]; /* * Check that the card supports the command class(es) we need. @@ -2921,7 +2929,16 @@ if (!(card->csd.cmdclass & CCC_BLOCK_READ)) return -ENODEV; - mmc_fixup_device(card, mmc_blk_fixups); + if (card_quirks) { + unsigned long quirks; + if (kstrtoul(card_quirks, 0, &quirks) == 0) + card->quirks = (unsigned int)quirks; + else + pr_err("mmc_block: Invalid card_quirks parameter '%s'\n", + card_quirks); + } + else + mmc_fixup_device(card, mmc_blk_fixups); md = mmc_blk_alloc(card); if (IS_ERR(md)) @@ -2929,9 +2946,14 @@ string_get_size((u64)get_capacity(md->disk), 512, STRING_UNITS_2, cap_str, sizeof(cap_str)); - pr_info("%s: %s %s %s %s\n", + if (card->quirks) + snprintf(quirk_str, sizeof(quirk_str), + " (quirks 0x%08x)", card->quirks); + else + quirk_str[0] = '\0'; + pr_info("%s: %s %s %s%s%s\n", md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), - cap_str, md->read_only ? "(ro)" : ""); + cap_str, md->read_only ? " (ro)" : "", quirk_str); if (mmc_blk_alloc_parts(card, md)) goto out; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/mmc/core/core.c linux-vendor/drivers/mmc/core/core.c --- linux-4.18.16/drivers/mmc/core/core.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/mmc/core/core.c 2018-10-29 19:31:21.645728022 +0100 @@ -2229,7 +2229,8 @@ int mmc_can_erase(struct mmc_card *card) { if ((card->host->caps & MMC_CAP_ERASE) && - (card->csd.cmdclass & CCC_ERASE) && card->erase_size) + (card->csd.cmdclass & CCC_ERASE) && card->erase_size && + !(card->quirks & MMC_QUIRK_ERASE_BROKEN)) return 1; return 0; } diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/mmc/core/host.c linux-vendor/drivers/mmc/core/host.c --- linux-4.18.16/drivers/mmc/core/host.c 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/mmc/core/host.c 2018-10-29 19:31:21.646727973 +0100 @@ -359,15 +359,30 @@ { int err; struct mmc_host *host; + int id; host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); if (!host) return NULL; + /* If OF aliases exist, start dynamic assignment after highest */ + id = of_alias_get_highest_id("mmc"); + id = (id < 0) ? 0 : id + 1; + + /* If this devices has OF node, maybe it has an alias */ + if (dev->of_node) { + int of_id = of_alias_get_id(dev->of_node, "mmc"); + + if (of_id < 0) + dev_warn(dev, "/aliases ID not available\n"); + else + id = of_id; + } + /* scanning will be enabled when we're ready */ host->rescan_disable = 1; - err = ida_simple_get(&mmc_host_ida, 0, 0, GFP_KERNEL); + err = ida_simple_get(&mmc_host_ida, id, 0, GFP_KERNEL); if (err < 0) { kfree(host); return NULL; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/mmc/core/quirks.h linux-vendor/drivers/mmc/core/quirks.h --- linux-4.18.16/drivers/mmc/core/quirks.h 2018-10-20 09:47:10.000000000 +0200 +++ linux-vendor/drivers/mmc/core/quirks.h 2018-10-29 19:31:21.648727873 +0100 @@ -99,6 +99,14 @@ MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc, MMC_QUIRK_TRIM_BROKEN), + /* + * On some Kingston SD cards, multiple erases of less than 64 + * sectors can cause corruption. + */ + MMC_FIXUP("SD16G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN), + MMC_FIXUP("SD32G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN), + MMC_FIXUP("SD64G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN), + END_FIXUP }; diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/mmc/host/bcm2835-mmc.c linux-vendor/drivers/mmc/host/bcm2835-mmc.c --- linux-4.18.16/drivers/mmc/host/bcm2835-mmc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/mmc/host/bcm2835-mmc.c 2018-10-29 19:31:21.653727623 +0100 @@ -0,0 +1,1582 @@ +/* + * BCM2835 MMC host driver. + * + * Author: Gellert Weisz + * Copyright 2014 + * + * Based on + * sdhci-bcm2708.c by Broadcom + * sdhci-bcm2835.c by Stephen Warren and Oleksandr Tymoshenko + * sdhci.c and sdhci-pci.c by Pierre Ossman + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sdhci.h" + + +#define DRIVER_NAME "mmc-bcm2835" + +#define DBG(f, x...) \ +pr_debug(DRIVER_NAME " [%s()]: " f, __func__, ## x) + +#ifndef CONFIG_MMC_BCM2835_DMA + #define FORCE_PIO +#endif + + +/* the inclusive limit in bytes under which PIO will be used instead of DMA */ +#ifdef CONFIG_MMC_BCM2835_PIO_DMA_BARRIER +#define PIO_DMA_BARRIER CONFIG_MMC_BCM2835_PIO_DMA_BARRIER +#else +#define PIO_DMA_BARRIER 00 +#endif + +#define MIN_FREQ 400000 +#define TIMEOUT_VAL 0xE +#define BCM2835_SDHCI_WRITE_DELAY(f) (((2 * 1000000) / f) + 1) + + +unsigned mmc_debug; +unsigned mmc_debug2; + +struct bcm2835_host { + spinlock_t lock; + + void __iomem *ioaddr; + u32 bus_addr; + + struct mmc_host *mmc; + + u32 timeout; + + int clock; /* Current clock speed */ + u8 pwr; /* Current voltage */ + + unsigned int max_clk; /* Max possible freq */ + unsigned int timeout_clk; /* Timeout freq (KHz) */ + unsigned int clk_mul; /* Clock Muliplier value */ + + struct tasklet_struct finish_tasklet; /* Tasklet structures */ + + struct timer_list timer; /* Timer for timeouts */ + + struct sg_mapping_iter sg_miter; /* SG state for PIO */ + unsigned int blocks; /* remaining PIO blocks */ + + int irq; /* Device IRQ */ + + + u32 ier; /* cached registers */ + + struct mmc_request *mrq; /* Current request */ + struct mmc_command *cmd; /* Current command */ + struct mmc_data *data; /* Current data request */ + unsigned int data_early:1; /* Data finished before cmd */ + + wait_queue_head_t buf_ready_int; /* Waitqueue for Buffer Read Ready interrupt */ + + u32 thread_isr; + + u32 shadow; + + /*DMA part*/ + struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */ + struct dma_slave_config dma_cfg_rx; + struct dma_slave_config dma_cfg_tx; + struct dma_async_tx_descriptor *tx_desc; /* descriptor */ + + bool have_dma; + bool use_dma; + bool wait_for_dma; + /*end of DMA part*/ + + int max_delay; /* maximum length of time spent waiting */ + + int flags; /* Host attributes */ +#define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */ +#define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */ +#define SDHCI_AUTO_CMD12 (1<<6) /* Auto CMD12 support */ +#define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */ +#define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ + + u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ + u32 max_overclock; /* Highest reported */ +}; + + +static inline void bcm2835_mmc_writel(struct bcm2835_host *host, u32 val, int reg, int from) +{ + unsigned delay; + lockdep_assert_held_once(&host->lock); + writel(val, host->ioaddr + reg); + udelay(BCM2835_SDHCI_WRITE_DELAY(max(host->clock, MIN_FREQ))); + + delay = ((mmc_debug >> 16) & 0xf) << ((mmc_debug >> 20) & 0xf); + if (delay && !((1<lock); + writel(val, host->ioaddr + reg); + + delay = ((mmc_debug >> 24) & 0xf) << ((mmc_debug >> 28) & 0xf); + if (delay) + udelay(delay); +} + +static inline u32 bcm2835_mmc_readl(struct bcm2835_host *host, int reg) +{ + lockdep_assert_held_once(&host->lock); + return readl(host->ioaddr + reg); +} + +static inline void bcm2835_mmc_writew(struct bcm2835_host *host, u16 val, int reg) +{ + u32 oldval = (reg == SDHCI_COMMAND) ? host->shadow : + bcm2835_mmc_readl(host, reg & ~3); + u32 word_num = (reg >> 1) & 1; + u32 word_shift = word_num * 16; + u32 mask = 0xffff << word_shift; + u32 newval = (oldval & ~mask) | (val << word_shift); + + if (reg == SDHCI_TRANSFER_MODE) + host->shadow = newval; + else + bcm2835_mmc_writel(host, newval, reg & ~3, 0); + +} + +static inline void bcm2835_mmc_writeb(struct bcm2835_host *host, u8 val, int reg) +{ + u32 oldval = bcm2835_mmc_readl(host, reg & ~3); + u32 byte_num = reg & 3; + u32 byte_shift = byte_num * 8; + u32 mask = 0xff << byte_shift; + u32 newval = (oldval & ~mask) | (val << byte_shift); + + bcm2835_mmc_writel(host, newval, reg & ~3, 1); +} + + +static inline u16 bcm2835_mmc_readw(struct bcm2835_host *host, int reg) +{ + u32 val = bcm2835_mmc_readl(host, (reg & ~3)); + u32 word_num = (reg >> 1) & 1; + u32 word_shift = word_num * 16; + u32 word = (val >> word_shift) & 0xffff; + + return word; +} + +static inline u8 bcm2835_mmc_readb(struct bcm2835_host *host, int reg) +{ + u32 val = bcm2835_mmc_readl(host, (reg & ~3)); + u32 byte_num = reg & 3; + u32 byte_shift = byte_num * 8; + u32 byte = (val >> byte_shift) & 0xff; + + return byte; +} + +static void bcm2835_mmc_unsignal_irqs(struct bcm2835_host *host, u32 clear) +{ + u32 ier; + + ier = bcm2835_mmc_readl(host, SDHCI_SIGNAL_ENABLE); + ier &= ~clear; + /* change which requests generate IRQs - makes no difference to + the content of SDHCI_INT_STATUS, or the need to acknowledge IRQs */ + bcm2835_mmc_writel(host, ier, SDHCI_SIGNAL_ENABLE, 2); +} + + +static void bcm2835_mmc_dumpregs(struct bcm2835_host *host) +{ + pr_debug(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n", + mmc_hostname(host->mmc)); + + pr_debug(DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n", + bcm2835_mmc_readl(host, SDHCI_DMA_ADDRESS), + bcm2835_mmc_readw(host, SDHCI_HOST_VERSION)); + pr_debug(DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n", + bcm2835_mmc_readw(host, SDHCI_BLOCK_SIZE), + bcm2835_mmc_readw(host, SDHCI_BLOCK_COUNT)); + pr_debug(DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n", + bcm2835_mmc_readl(host, SDHCI_ARGUMENT), + bcm2835_mmc_readw(host, SDHCI_TRANSFER_MODE)); + pr_debug(DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n", + bcm2835_mmc_readl(host, SDHCI_PRESENT_STATE), + bcm2835_mmc_readb(host, SDHCI_HOST_CONTROL)); + pr_debug(DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n", + bcm2835_mmc_readb(host, SDHCI_POWER_CONTROL), + bcm2835_mmc_readb(host, SDHCI_BLOCK_GAP_CONTROL)); + pr_debug(DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n", + bcm2835_mmc_readb(host, SDHCI_WAKE_UP_CONTROL), + bcm2835_mmc_readw(host, SDHCI_CLOCK_CONTROL)); + pr_debug(DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n", + bcm2835_mmc_readb(host, SDHCI_TIMEOUT_CONTROL), + bcm2835_mmc_readl(host, SDHCI_INT_STATUS)); + pr_debug(DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n", + bcm2835_mmc_readl(host, SDHCI_INT_ENABLE), + bcm2835_mmc_readl(host, SDHCI_SIGNAL_ENABLE)); + pr_debug(DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n", + bcm2835_mmc_readw(host, SDHCI_ACMD12_ERR), + bcm2835_mmc_readw(host, SDHCI_SLOT_INT_STATUS)); + pr_debug(DRIVER_NAME ": Caps: 0x%08x | Caps_1: 0x%08x\n", + bcm2835_mmc_readl(host, SDHCI_CAPABILITIES), + bcm2835_mmc_readl(host, SDHCI_CAPABILITIES_1)); + pr_debug(DRIVER_NAME ": Cmd: 0x%08x | Max curr: 0x%08x\n", + bcm2835_mmc_readw(host, SDHCI_COMMAND), + bcm2835_mmc_readl(host, SDHCI_MAX_CURRENT)); + pr_debug(DRIVER_NAME ": Host ctl2: 0x%08x\n", + bcm2835_mmc_readw(host, SDHCI_HOST_CONTROL2)); + + pr_debug(DRIVER_NAME ": ===========================================\n"); +} + + +static void bcm2835_mmc_reset(struct bcm2835_host *host, u8 mask) +{ + unsigned long timeout; + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + bcm2835_mmc_writeb(host, mask, SDHCI_SOFTWARE_RESET); + + if (mask & SDHCI_RESET_ALL) + host->clock = 0; + + /* Wait max 100 ms */ + timeout = 100; + + /* hw clears the bit when it's done */ + while (bcm2835_mmc_readb(host, SDHCI_SOFTWARE_RESET) & mask) { + if (timeout == 0) { + pr_err("%s: Reset 0x%x never completed.\n", + mmc_hostname(host->mmc), (int)mask); + bcm2835_mmc_dumpregs(host); + return; + } + timeout--; + spin_unlock_irqrestore(&host->lock, flags); + mdelay(1); + spin_lock_irqsave(&host->lock, flags); + } + + if (100-timeout > 10 && 100-timeout > host->max_delay) { + host->max_delay = 100-timeout; + pr_warning("Warning: MMC controller hung for %d ms\n", host->max_delay); + } + spin_unlock_irqrestore(&host->lock, flags); +} + +static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); + +static void bcm2835_mmc_init(struct bcm2835_host *host, int soft) +{ + unsigned long flags; + if (soft) + bcm2835_mmc_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA); + else + bcm2835_mmc_reset(host, SDHCI_RESET_ALL); + + host->ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | + SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | + SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC | + SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END | + SDHCI_INT_RESPONSE; + + spin_lock_irqsave(&host->lock, flags); + bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 3); + bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 3); + spin_unlock_irqrestore(&host->lock, flags); + + if (soft) { + /* force clock reconfiguration */ + host->clock = 0; + bcm2835_mmc_set_ios(host->mmc, &host->mmc->ios); + } +} + + + +static void bcm2835_mmc_finish_data(struct bcm2835_host *host); + +static void bcm2835_mmc_dma_complete(void *param) +{ + struct bcm2835_host *host = param; + struct dma_chan *dma_chan; + unsigned long flags; + u32 dir_data; + + spin_lock_irqsave(&host->lock, flags); + + host->use_dma = false; + + if (host->data && !(host->data->flags & MMC_DATA_WRITE)) { + /* otherwise handled in SDHCI IRQ */ + dma_chan = host->dma_chan_rxtx; + dir_data = DMA_FROM_DEVICE; + + dma_unmap_sg(dma_chan->device->dev, + host->data->sg, host->data->sg_len, + dir_data); + + bcm2835_mmc_finish_data(host); + } else if (host->wait_for_dma) { + host->wait_for_dma = false; + tasklet_schedule(&host->finish_tasklet); + } + + spin_unlock_irqrestore(&host->lock, flags); +} + +static void bcm2835_bcm2835_mmc_read_block_pio(struct bcm2835_host *host) +{ + unsigned long flags; + size_t blksize, len, chunk; + + u32 uninitialized_var(scratch); + u8 *buf; + + blksize = host->data->blksz; + chunk = 0; + + local_irq_save(flags); + + while (blksize) { + if (!sg_miter_next(&host->sg_miter)) + BUG(); + + len = min(host->sg_miter.length, blksize); + + blksize -= len; + host->sg_miter.consumed = len; + + buf = host->sg_miter.addr; + + while (len) { + if (chunk == 0) { + scratch = bcm2835_mmc_readl(host, SDHCI_BUFFER); + chunk = 4; + } + + *buf = scratch & 0xFF; + + buf++; + scratch >>= 8; + chunk--; + len--; + } + } + + sg_miter_stop(&host->sg_miter); + + local_irq_restore(flags); +} + +static void bcm2835_bcm2835_mmc_write_block_pio(struct bcm2835_host *host) +{ + unsigned long flags; + size_t blksize, len, chunk; + u32 scratch; + u8 *buf; + + blksize = host->data->blksz; + chunk = 0; + chunk = 0; + scratch = 0; + + local_irq_save(flags); + + while (blksize) { + if (!sg_miter_next(&host->sg_miter)) + BUG(); + + len = min(host->sg_miter.length, blksize); + + blksize -= len; + host->sg_miter.consumed = len; + + buf = host->sg_miter.addr; + + while (len) { + scratch |= (u32)*buf << (chunk * 8); + + buf++; + chunk++; + len--; + + if ((chunk == 4) || ((len == 0) && (blksize == 0))) { + mmc_raw_writel(host, scratch, SDHCI_BUFFER); + chunk = 0; + scratch = 0; + } + } + } + + sg_miter_stop(&host->sg_miter); + + local_irq_restore(flags); +} + + +static void bcm2835_mmc_transfer_pio(struct bcm2835_host *host) +{ + u32 mask; + + BUG_ON(!host->data); + + if (host->blocks == 0) + return; + + if (host->data->flags & MMC_DATA_READ) + mask = SDHCI_DATA_AVAILABLE; + else + mask = SDHCI_SPACE_AVAILABLE; + + while (bcm2835_mmc_readl(host, SDHCI_PRESENT_STATE) & mask) { + + if (host->data->flags & MMC_DATA_READ) + bcm2835_bcm2835_mmc_read_block_pio(host); + else + bcm2835_bcm2835_mmc_write_block_pio(host); + + host->blocks--; + + /* QUIRK used in sdhci.c removes the 'if' */ + /* but it seems this is unnecessary */ + if (host->blocks == 0) + break; + + + } +} + + +static void bcm2835_mmc_transfer_dma(struct bcm2835_host *host) +{ + u32 len, dir_data, dir_slave; + struct dma_async_tx_descriptor *desc = NULL; + struct dma_chan *dma_chan; + + + WARN_ON(!host->data); + + if (!host->data) + return; + + if (host->blocks == 0) + return; + + dma_chan = host->dma_chan_rxtx; + if (host->data->flags & MMC_DATA_READ) { + dir_data = DMA_FROM_DEVICE; + dir_slave = DMA_DEV_TO_MEM; + } else { + dir_data = DMA_TO_DEVICE; + dir_slave = DMA_MEM_TO_DEV; + } + + /* The parameters have already been validated, so this will not fail */ + (void)dmaengine_slave_config(dma_chan, + (dir_data == DMA_FROM_DEVICE) ? + &host->dma_cfg_rx : + &host->dma_cfg_tx); + + BUG_ON(!dma_chan->device); + BUG_ON(!dma_chan->device->dev); + BUG_ON(!host->data->sg); + + len = dma_map_sg(dma_chan->device->dev, host->data->sg, + host->data->sg_len, dir_data); + if (len > 0) { + desc = dmaengine_prep_slave_sg(dma_chan, host->data->sg, + len, dir_slave, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + } else { + dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n"); + } + if (desc) { + unsigned long flags; + spin_lock_irqsave(&host->lock, flags); + bcm2835_mmc_unsignal_irqs(host, SDHCI_INT_DATA_AVAIL | + SDHCI_INT_SPACE_AVAIL); + host->tx_desc = desc; + desc->callback = bcm2835_mmc_dma_complete; + desc->callback_param = host; + spin_unlock_irqrestore(&host->lock, flags); + dmaengine_submit(desc); + dma_async_issue_pending(dma_chan); + } + +} + + + +static void bcm2835_mmc_set_transfer_irqs(struct bcm2835_host *host) +{ + u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL; + u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR; + + if (host->use_dma) + host->ier = (host->ier & ~pio_irqs) | dma_irqs; + else + host->ier = (host->ier & ~dma_irqs) | pio_irqs; + + bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 4); + bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 4); +} + + +static void bcm2835_mmc_prepare_data(struct bcm2835_host *host, struct mmc_command *cmd) +{ + u8 count; + struct mmc_data *data = cmd->data; + + WARN_ON(host->data); + + if (data || (cmd->flags & MMC_RSP_BUSY)) { + count = TIMEOUT_VAL; + bcm2835_mmc_writeb(host, count, SDHCI_TIMEOUT_CONTROL); + } + + if (!data) + return; + + /* Sanity checks */ + BUG_ON(data->blksz * data->blocks > 524288); + BUG_ON(data->blksz > host->mmc->max_blk_size); + BUG_ON(data->blocks > 65535); + + host->data = data; + host->data_early = 0; + host->data->bytes_xfered = 0; + + + if (!(host->flags & SDHCI_REQ_USE_DMA)) { + int flags; + + flags = SG_MITER_ATOMIC; + if (host->data->flags & MMC_DATA_READ) + flags |= SG_MITER_TO_SG; + else + flags |= SG_MITER_FROM_SG; + sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); + host->blocks = data->blocks; + } + + host->use_dma = host->have_dma && data->blocks > PIO_DMA_BARRIER; + + bcm2835_mmc_set_transfer_irqs(host); + + /* Set the DMA boundary value and block size */ + bcm2835_mmc_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, + data->blksz), SDHCI_BLOCK_SIZE); + bcm2835_mmc_writew(host, data->blocks, SDHCI_BLOCK_COUNT); + + BUG_ON(!host->data); +} + +static void bcm2835_mmc_set_transfer_mode(struct bcm2835_host *host, + struct mmc_command *cmd) +{ + u16 mode; + struct mmc_data *data = cmd->data; + + if (data == NULL) { + /* clear Auto CMD settings for no data CMDs */ + mode = bcm2835_mmc_readw(host, SDHCI_TRANSFER_MODE); + bcm2835_mmc_writew(host, mode & ~(SDHCI_TRNS_AUTO_CMD12 | + SDHCI_TRNS_AUTO_CMD23), SDHCI_TRANSFER_MODE); + return; + } + + WARN_ON(!host->data); + + mode = SDHCI_TRNS_BLK_CNT_EN; + + if ((mmc_op_multi(cmd->opcode) || data->blocks > 1)) { + mode |= SDHCI_TRNS_MULTI; + + /* + * If we are sending CMD23, CMD12 never gets sent + * on successful completion (so no Auto-CMD12). + */ + if (!host->mrq->sbc && (host->flags & SDHCI_AUTO_CMD12)) + mode |= SDHCI_TRNS_AUTO_CMD12; + else if (host->mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) { + mode |= SDHCI_TRNS_AUTO_CMD23; + bcm2835_mmc_writel(host, host->mrq->sbc->arg, SDHCI_ARGUMENT2, 5); + } + } + + if (data->flags & MMC_DATA_READ) + mode |= SDHCI_TRNS_READ; + if (host->flags & SDHCI_REQ_USE_DMA) + mode |= SDHCI_TRNS_DMA; + + bcm2835_mmc_writew(host, mode, SDHCI_TRANSFER_MODE); +} + +void bcm2835_mmc_send_command(struct bcm2835_host *host, struct mmc_command *cmd) +{ + int flags; + u32 mask; + unsigned long timeout; + + WARN_ON(host->cmd); + + /* Wait max 10 ms */ + timeout = 1000; + + mask = SDHCI_CMD_INHIBIT; + if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY)) + mask |= SDHCI_DATA_INHIBIT; + + /* We shouldn't wait for data inihibit for stop commands, even + though they might use busy signaling */ + if (host->mrq->data && (cmd == host->mrq->data->stop)) + mask &= ~SDHCI_DATA_INHIBIT; + + while (bcm2835_mmc_readl(host, SDHCI_PRESENT_STATE) & mask) { + if (timeout == 0) { + pr_err("%s: Controller never released inhibit bit(s).\n", + mmc_hostname(host->mmc)); + bcm2835_mmc_dumpregs(host); + cmd->error = -EIO; + tasklet_schedule(&host->finish_tasklet); + return; + } + timeout--; + udelay(10); + } + + if ((1000-timeout)/100 > 1 && (1000-timeout)/100 > host->max_delay) { + host->max_delay = (1000-timeout)/100; + pr_warning("Warning: MMC controller hung for %d ms\n", host->max_delay); + } + + timeout = jiffies; + if (!cmd->data && cmd->busy_timeout > 9000) + timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; + else + timeout += 10 * HZ; + mod_timer(&host->timer, timeout); + + host->cmd = cmd; + host->use_dma = false; + + bcm2835_mmc_prepare_data(host, cmd); + + bcm2835_mmc_writel(host, cmd->arg, SDHCI_ARGUMENT, 6); + + bcm2835_mmc_set_transfer_mode(host, cmd); + + if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { + pr_err("%s: Unsupported response type!\n", + mmc_hostname(host->mmc)); + cmd->error = -EINVAL; + tasklet_schedule(&host->finish_tasklet); + return; + } + + if (!(cmd->flags & MMC_RSP_PRESENT)) + flags = SDHCI_CMD_RESP_NONE; + else if (cmd->flags & MMC_RSP_136) + flags = SDHCI_CMD_RESP_LONG; + else if (cmd->flags & MMC_RSP_BUSY) + flags = SDHCI_CMD_RESP_SHORT_BUSY; + else + flags = SDHCI_CMD_RESP_SHORT; + + if (cmd->flags & MMC_RSP_CRC) + flags |= SDHCI_CMD_CRC; + if (cmd->flags & MMC_RSP_OPCODE) + flags |= SDHCI_CMD_INDEX; + + if (cmd->data) + flags |= SDHCI_CMD_DATA; + + bcm2835_mmc_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); +} + + +static void bcm2835_mmc_finish_data(struct bcm2835_host *host) +{ + struct mmc_data *data; + + BUG_ON(!host->data); + + data = host->data; + host->data = NULL; + + if (data->error) + data->bytes_xfered = 0; + else + data->bytes_xfered = data->blksz * data->blocks; + + /* + * Need to send CMD12 if - + * a) open-ended multiblock transfer (no CMD23) + * b) error in multiblock transfer + */ + if (data->stop && + (data->error || + !host->mrq->sbc)) { + + /* + * The controller needs a reset of internal state machines + * upon error conditions. + */ + if (data->error) { + bcm2835_mmc_reset(host, SDHCI_RESET_CMD); + bcm2835_mmc_reset(host, SDHCI_RESET_DATA); + } + + bcm2835_mmc_send_command(host, data->stop); + } else if (host->use_dma) { + host->wait_for_dma = true; + } else { + tasklet_schedule(&host->finish_tasklet); + } +} + +static void bcm2835_mmc_finish_command(struct bcm2835_host *host) +{ + int i; + + BUG_ON(host->cmd == NULL); + + if (host->cmd->flags & MMC_RSP_PRESENT) { + if (host->cmd->flags & MMC_RSP_136) { + /* CRC is stripped so we need to do some shifting. */ + for (i = 0; i < 4; i++) { + host->cmd->resp[i] = bcm2835_mmc_readl(host, + SDHCI_RESPONSE + (3-i)*4) << 8; + if (i != 3) + host->cmd->resp[i] |= + bcm2835_mmc_readb(host, + SDHCI_RESPONSE + (3-i)*4-1); + } + } else { + host->cmd->resp[0] = bcm2835_mmc_readl(host, SDHCI_RESPONSE); + } + } + + host->cmd->error = 0; + + /* Finished CMD23, now send actual command. */ + if (host->cmd == host->mrq->sbc) { + host->cmd = NULL; + bcm2835_mmc_send_command(host, host->mrq->cmd); + + if (host->mrq->cmd->data && host->use_dma) { + /* DMA transfer starts now, PIO starts after interrupt */ + bcm2835_mmc_transfer_dma(host); + } + } else { + + /* Processed actual command. */ + if (host->data && host->data_early) + bcm2835_mmc_finish_data(host); + + if (!host->cmd->data) + tasklet_schedule(&host->finish_tasklet); + + host->cmd = NULL; + } +} + + +static void bcm2835_mmc_timeout_timer(struct timer_list *t) +{ + struct bcm2835_host *host = from_timer(host, t, timer); + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + + if (host->mrq) { + pr_err("%s: Timeout waiting for hardware interrupt.\n", + mmc_hostname(host->mmc)); + bcm2835_mmc_dumpregs(host); + + if (host->data) { + host->data->error = -ETIMEDOUT; + bcm2835_mmc_finish_data(host); + } else { + if (host->cmd) + host->cmd->error = -ETIMEDOUT; + else + host->mrq->cmd->error = -ETIMEDOUT; + + tasklet_schedule(&host->finish_tasklet); + } + } + + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); +} + + +static void bcm2835_mmc_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) +{ + if (!(host->flags & SDHCI_DEVICE_DEAD)) { + if (enable) + host->ier |= SDHCI_INT_CARD_INT; + else + host->ier &= ~SDHCI_INT_CARD_INT; + + bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 7); + bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 7); + mmiowb(); + } +} + +static void bcm2835_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) +{ + struct bcm2835_host *host = mmc_priv(mmc); + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + if (enable) + host->flags |= SDHCI_SDIO_IRQ_ENABLED; + else + host->flags &= ~SDHCI_SDIO_IRQ_ENABLED; + + bcm2835_mmc_enable_sdio_irq_nolock(host, enable); + spin_unlock_irqrestore(&host->lock, flags); +} + +static void bcm2835_mmc_cmd_irq(struct bcm2835_host *host, u32 intmask) +{ + + BUG_ON(intmask == 0); + + if (!host->cmd) { + pr_err("%s: Got command interrupt 0x%08x even " + "though no command operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_mmc_dumpregs(host); + return; + } + + if (intmask & SDHCI_INT_TIMEOUT) + host->cmd->error = -ETIMEDOUT; + else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT | + SDHCI_INT_INDEX)) { + host->cmd->error = -EILSEQ; + } + + if (host->cmd->error) { + tasklet_schedule(&host->finish_tasklet); + return; + } + + if (intmask & SDHCI_INT_RESPONSE) + bcm2835_mmc_finish_command(host); + +} + +static void bcm2835_mmc_data_irq(struct bcm2835_host *host, u32 intmask) +{ + struct dma_chan *dma_chan; + u32 dir_data; + + BUG_ON(intmask == 0); + + if (!host->data) { + /* + * The "data complete" interrupt is also used to + * indicate that a busy state has ended. See comment + * above in sdhci_cmd_irq(). + */ + if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) { + if (intmask & SDHCI_INT_DATA_END) { + bcm2835_mmc_finish_command(host); + return; + } + } + + pr_debug("%s: Got data interrupt 0x%08x even " + "though no data operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_mmc_dumpregs(host); + + return; + } + + if (intmask & SDHCI_INT_DATA_TIMEOUT) + host->data->error = -ETIMEDOUT; + else if (intmask & SDHCI_INT_DATA_END_BIT) + host->data->error = -EILSEQ; + else if ((intmask & SDHCI_INT_DATA_CRC) && + SDHCI_GET_CMD(bcm2835_mmc_readw(host, SDHCI_COMMAND)) + != MMC_BUS_TEST_R) + host->data->error = -EILSEQ; + + if (host->use_dma) { + if (host->data->flags & MMC_DATA_WRITE) { + /* IRQ handled here */ + + dma_chan = host->dma_chan_rxtx; + dir_data = DMA_TO_DEVICE; + dma_unmap_sg(dma_chan->device->dev, + host->data->sg, host->data->sg_len, + dir_data); + + bcm2835_mmc_finish_data(host); + } + + } else { + if (host->data->error) + bcm2835_mmc_finish_data(host); + else { + if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) + bcm2835_mmc_transfer_pio(host); + + if (intmask & SDHCI_INT_DATA_END) { + if (host->cmd) { + /* + * Data managed to finish before the + * command completed. Make sure we do + * things in the proper order. + */ + host->data_early = 1; + } else { + bcm2835_mmc_finish_data(host); + } + } + } + } +} + + +static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) +{ + irqreturn_t result = IRQ_NONE; + struct bcm2835_host *host = dev_id; + u32 intmask, mask, unexpected = 0; + int max_loops = 16; + + spin_lock(&host->lock); + + intmask = bcm2835_mmc_readl(host, SDHCI_INT_STATUS); + + if (!intmask || intmask == 0xffffffff) { + result = IRQ_NONE; + goto out; + } + + do { + /* Clear selected interrupts. */ + mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK | + SDHCI_INT_BUS_POWER); + bcm2835_mmc_writel(host, mask, SDHCI_INT_STATUS, 8); + + + if (intmask & SDHCI_INT_CMD_MASK) + bcm2835_mmc_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK); + + if (intmask & SDHCI_INT_DATA_MASK) + bcm2835_mmc_data_irq(host, intmask & SDHCI_INT_DATA_MASK); + + if (intmask & SDHCI_INT_BUS_POWER) + pr_err("%s: Card is consuming too much power!\n", + mmc_hostname(host->mmc)); + + if (intmask & SDHCI_INT_CARD_INT) { + bcm2835_mmc_enable_sdio_irq_nolock(host, false); + host->thread_isr |= SDHCI_INT_CARD_INT; + result = IRQ_WAKE_THREAD; + } + + intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE | + SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK | + SDHCI_INT_ERROR | SDHCI_INT_BUS_POWER | + SDHCI_INT_CARD_INT); + + if (intmask) { + unexpected |= intmask; + bcm2835_mmc_writel(host, intmask, SDHCI_INT_STATUS, 9); + } + + if (result == IRQ_NONE) + result = IRQ_HANDLED; + + intmask = bcm2835_mmc_readl(host, SDHCI_INT_STATUS); + } while (intmask && --max_loops); +out: + spin_unlock(&host->lock); + + if (unexpected) { + pr_err("%s: Unexpected interrupt 0x%08x.\n", + mmc_hostname(host->mmc), unexpected); + bcm2835_mmc_dumpregs(host); + } + + return result; +} + +static irqreturn_t bcm2835_mmc_thread_irq(int irq, void *dev_id) +{ + struct bcm2835_host *host = dev_id; + unsigned long flags; + u32 isr; + + spin_lock_irqsave(&host->lock, flags); + isr = host->thread_isr; + host->thread_isr = 0; + spin_unlock_irqrestore(&host->lock, flags); + + if (isr & SDHCI_INT_CARD_INT) { + sdio_run_irqs(host->mmc); + + spin_lock_irqsave(&host->lock, flags); + if (host->flags & SDHCI_SDIO_IRQ_ENABLED) + bcm2835_mmc_enable_sdio_irq_nolock(host, true); + spin_unlock_irqrestore(&host->lock, flags); + } + + return isr ? IRQ_HANDLED : IRQ_NONE; +} + + + +void bcm2835_mmc_set_clock(struct bcm2835_host *host, unsigned int clock) +{ + int div = 0; /* Initialized for compiler warning */ + int real_div = div, clk_mul = 1; + u16 clk = 0; + unsigned long timeout; + unsigned int input_clock = clock; + + if (host->overclock_50 && (clock == 50000000)) + clock = host->overclock_50 * 1000000 + 999999; + + host->mmc->actual_clock = 0; + + bcm2835_mmc_writew(host, 0, SDHCI_CLOCK_CONTROL); + + if (clock == 0) + return; + + /* Version 3.00 divisors must be a multiple of 2. */ + if (host->max_clk <= clock) + div = 1; + else { + for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; + div += 2) { + if ((host->max_clk / div) <= clock) + break; + } + } + + real_div = div; + div >>= 1; + + if (real_div) + clock = (host->max_clk * clk_mul) / real_div; + host->mmc->actual_clock = clock; + + if ((clock > input_clock) && (clock > host->max_overclock)) { + pr_warn("%s: Overclocking to %dHz\n", + mmc_hostname(host->mmc), clock); + host->max_overclock = clock; + } + + clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; + clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) + << SDHCI_DIVIDER_HI_SHIFT; + clk |= SDHCI_CLOCK_INT_EN; + bcm2835_mmc_writew(host, clk, SDHCI_CLOCK_CONTROL); + + /* Wait max 20 ms */ + timeout = 20; + while (!((clk = bcm2835_mmc_readw(host, SDHCI_CLOCK_CONTROL)) + & SDHCI_CLOCK_INT_STABLE)) { + if (timeout == 0) { + pr_err("%s: Internal clock never " + "stabilised.\n", mmc_hostname(host->mmc)); + bcm2835_mmc_dumpregs(host); + return; + } + timeout--; + mdelay(1); + } + + if (20-timeout > 10 && 20-timeout > host->max_delay) { + host->max_delay = 20-timeout; + pr_warning("Warning: MMC controller hung for %d ms\n", host->max_delay); + } + + clk |= SDHCI_CLOCK_CARD_EN; + bcm2835_mmc_writew(host, clk, SDHCI_CLOCK_CONTROL); +} + +static void bcm2835_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct bcm2835_host *host; + unsigned long flags; + + host = mmc_priv(mmc); + + spin_lock_irqsave(&host->lock, flags); + + WARN_ON(host->mrq != NULL); + + host->mrq = mrq; + + if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) + bcm2835_mmc_send_command(host, mrq->sbc); + else + bcm2835_mmc_send_command(host, mrq->cmd); + + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); + + if (!(mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) && mrq->cmd->data && host->use_dma) { + /* DMA transfer starts now, PIO starts after interrupt */ + bcm2835_mmc_transfer_dma(host); + } +} + + +static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + + struct bcm2835_host *host = mmc_priv(mmc); + unsigned long flags; + u8 ctrl; + u16 clk, ctrl_2; + + pr_debug("bcm2835_mmc_set_ios: clock %d, pwr %d, bus_width %d, timing %d, vdd %d, drv_type %d\n", + ios->clock, ios->power_mode, ios->bus_width, + ios->timing, ios->signal_voltage, ios->drv_type); + + spin_lock_irqsave(&host->lock, flags); + + if (!ios->clock || ios->clock != host->clock) { + bcm2835_mmc_set_clock(host, ios->clock); + host->clock = ios->clock; + } + + if (host->pwr != SDHCI_POWER_330) { + host->pwr = SDHCI_POWER_330; + bcm2835_mmc_writeb(host, SDHCI_POWER_330 | SDHCI_POWER_ON, SDHCI_POWER_CONTROL); + } + + ctrl = bcm2835_mmc_readb(host, SDHCI_HOST_CONTROL); + + /* set bus width */ + ctrl &= ~SDHCI_CTRL_8BITBUS; + if (ios->bus_width == MMC_BUS_WIDTH_4) + ctrl |= SDHCI_CTRL_4BITBUS; + else + ctrl &= ~SDHCI_CTRL_4BITBUS; + + ctrl &= ~SDHCI_CTRL_HISPD; /* NO_HISPD_BIT */ + + + bcm2835_mmc_writeb(host, ctrl, SDHCI_HOST_CONTROL); + /* + * We only need to set Driver Strength if the + * preset value enable is not set. + */ + ctrl_2 = bcm2835_mmc_readw(host, SDHCI_HOST_CONTROL2); + ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK; + if (ios->drv_type == MMC_SET_DRIVER_TYPE_A) + ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A; + else if (ios->drv_type == MMC_SET_DRIVER_TYPE_C) + ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C; + + bcm2835_mmc_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); + + /* Reset SD Clock Enable */ + clk = bcm2835_mmc_readw(host, SDHCI_CLOCK_CONTROL); + clk &= ~SDHCI_CLOCK_CARD_EN; + bcm2835_mmc_writew(host, clk, SDHCI_CLOCK_CONTROL); + + /* Re-enable SD Clock */ + bcm2835_mmc_set_clock(host, host->clock); + bcm2835_mmc_writeb(host, ctrl, SDHCI_HOST_CONTROL); + + mmiowb(); + + spin_unlock_irqrestore(&host->lock, flags); +} + + +static struct mmc_host_ops bcm2835_ops = { + .request = bcm2835_mmc_request, + .set_ios = bcm2835_mmc_set_ios, + .enable_sdio_irq = bcm2835_mmc_enable_sdio_irq, +}; + + +static void bcm2835_mmc_tasklet_finish(unsigned long param) +{ + struct bcm2835_host *host; + unsigned long flags; + struct mmc_request *mrq; + + host = (struct bcm2835_host *)param; + + spin_lock_irqsave(&host->lock, flags); + + /* + * If this tasklet gets rescheduled while running, it will + * be run again afterwards but without any active request. + */ + if (!host->mrq) { + spin_unlock_irqrestore(&host->lock, flags); + return; + } + + del_timer(&host->timer); + + mrq = host->mrq; + + /* + * The controller needs a reset of internal state machines + * upon error conditions. + */ + if (!(host->flags & SDHCI_DEVICE_DEAD) && + ((mrq->cmd && mrq->cmd->error) || + (mrq->data && (mrq->data->error || + (mrq->data->stop && mrq->data->stop->error))))) { + + spin_unlock_irqrestore(&host->lock, flags); + bcm2835_mmc_reset(host, SDHCI_RESET_CMD); + bcm2835_mmc_reset(host, SDHCI_RESET_DATA); + spin_lock_irqsave(&host->lock, flags); + } + + host->mrq = NULL; + host->cmd = NULL; + host->data = NULL; + + mmiowb(); + + spin_unlock_irqrestore(&host->lock, flags); + mmc_request_done(host->mmc, mrq); +} + + + +static int bcm2835_mmc_add_host(struct bcm2835_host *host) +{ + struct mmc_host *mmc = host->mmc; + struct device *dev = mmc->parent; +#ifndef FORCE_PIO + struct dma_slave_config cfg; +#endif + int ret; + + bcm2835_mmc_reset(host, SDHCI_RESET_ALL); + + host->clk_mul = 0; + + if (!mmc->f_max || mmc->f_max > host->max_clk) + mmc->f_max = host->max_clk; + mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300; + + /* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */ + host->timeout_clk = mmc->f_max / 1000; + mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; + + /* host controller capabilities */ + mmc->caps |= MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | + MMC_CAP_SDIO_IRQ | MMC_CAP_SD_HIGHSPEED | + MMC_CAP_MMC_HIGHSPEED; + + mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; + + host->flags = SDHCI_AUTO_CMD23; + + dev_info(dev, "mmc_debug:%x mmc_debug2:%x\n", mmc_debug, mmc_debug2); +#ifdef FORCE_PIO + dev_info(dev, "Forcing PIO mode\n"); + host->have_dma = false; +#else + if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) { + dev_err(dev, "%s: Unable to initialise DMA channel. Falling back to PIO\n", + DRIVER_NAME); + host->have_dma = false; + } else { + dev_info(dev, "DMA channel allocated"); + + cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + cfg.slave_id = 11; /* DREQ channel */ + + /* Validate the slave configurations */ + + cfg.direction = DMA_MEM_TO_DEV; + cfg.src_addr = 0; + cfg.dst_addr = host->bus_addr + SDHCI_BUFFER; + + ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); + + if (ret == 0) { + host->dma_cfg_tx = cfg; + + cfg.direction = DMA_DEV_TO_MEM; + cfg.src_addr = host->bus_addr + SDHCI_BUFFER; + cfg.dst_addr = 0; + + ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); + } + + if (ret == 0) { + host->dma_cfg_rx = cfg; + + host->have_dma = true; + } else { + pr_err("%s: unable to configure DMA channel. " + "Falling back to PIO\n", + mmc_hostname(mmc)); + dma_release_channel(host->dma_chan_rxtx); + host->dma_chan_rxtx = NULL; + host->have_dma = false; + } + } +#endif + mmc->max_segs = 128; + mmc->max_req_size = 524288; + mmc->max_seg_size = mmc->max_req_size; + mmc->max_blk_size = 512; + mmc->max_blk_count = 65535; + + /* report supported voltage ranges */ + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + + tasklet_init(&host->finish_tasklet, + bcm2835_mmc_tasklet_finish, (unsigned long)host); + + timer_setup(&host->timer, bcm2835_mmc_timeout_timer, 0); + init_waitqueue_head(&host->buf_ready_int); + + bcm2835_mmc_init(host, 0); + ret = devm_request_threaded_irq(dev, host->irq, bcm2835_mmc_irq, + bcm2835_mmc_thread_irq, IRQF_SHARED, + mmc_hostname(mmc), host); + if (ret) { + dev_err(dev, "Failed to request IRQ %d: %d\n", host->irq, ret); + goto untasklet; + } + + mmiowb(); + mmc_add_host(mmc); + + return 0; + +untasklet: + tasklet_kill(&host->finish_tasklet); + + return ret; +} + +static int bcm2835_mmc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct clk *clk; + struct resource *iomem; + struct bcm2835_host *host; + struct mmc_host *mmc; + const __be32 *addr; + int ret; + + mmc = mmc_alloc_host(sizeof(*host), dev); + if (!mmc) + return -ENOMEM; + + mmc->ops = &bcm2835_ops; + host = mmc_priv(mmc); + host->mmc = mmc; + host->timeout = msecs_to_jiffies(1000); + spin_lock_init(&host->lock); + + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + host->ioaddr = devm_ioremap_resource(dev, iomem); + if (IS_ERR(host->ioaddr)) { + ret = PTR_ERR(host->ioaddr); + goto err; + } + + addr = of_get_address(node, 0, NULL, NULL); + if (!addr) { + dev_err(dev, "could not get DMA-register address\n"); + return -ENODEV; + } + host->bus_addr = be32_to_cpup(addr); + pr_debug(" - ioaddr %lx, iomem->start %lx, bus_addr %lx\n", + (unsigned long)host->ioaddr, + (unsigned long)iomem->start, + (unsigned long)host->bus_addr); + +#ifndef FORCE_PIO + if (node) { + host->dma_chan_rxtx = dma_request_slave_channel(dev, "rx-tx"); + if (!host->dma_chan_rxtx) + host->dma_chan_rxtx = + dma_request_slave_channel(dev, "tx"); + if (!host->dma_chan_rxtx) + host->dma_chan_rxtx = + dma_request_slave_channel(dev, "rx"); + } else { + dma_cap_mask_t mask; + + dma_cap_zero(mask); + /* we don't care about the channel, any would work */ + dma_cap_set(DMA_SLAVE, mask); + host->dma_chan_rxtx = dma_request_channel(mask, NULL, NULL); + } +#endif + clk = devm_clk_get(dev, NULL); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + if (ret == -EPROBE_DEFER) + dev_info(dev, "could not get clk, deferring probe\n"); + else + dev_err(dev, "could not get clk\n"); + goto err; + } + + host->max_clk = clk_get_rate(clk); + + host->irq = platform_get_irq(pdev, 0); + if (host->irq <= 0) { + dev_err(dev, "get IRQ failed\n"); + ret = -EINVAL; + goto err; + } + + if (node) { + mmc_of_parse(mmc); + + /* Read any custom properties */ + of_property_read_u32(node, + "brcm,overclock-50", + &host->overclock_50); + } else { + mmc->caps |= MMC_CAP_4_BIT_DATA; + } + + ret = bcm2835_mmc_add_host(host); + if (ret) + goto err; + + platform_set_drvdata(pdev, host); + + return 0; +err: + mmc_free_host(mmc); + + return ret; +} + +static int bcm2835_mmc_remove(struct platform_device *pdev) +{ + struct bcm2835_host *host = platform_get_drvdata(pdev); + unsigned long flags; + int dead; + u32 scratch; + + dead = 0; + scratch = bcm2835_mmc_readl(host, SDHCI_INT_STATUS); + if (scratch == (u32)-1) + dead = 1; + + + if (dead) { + spin_lock_irqsave(&host->lock, flags); + + host->flags |= SDHCI_DEVICE_DEAD; + + if (host->mrq) { + pr_err("%s: Controller removed during " + " transfer!\n", mmc_hostname(host->mmc)); + + host->mrq->cmd->error = -ENOMEDIUM; + tasklet_schedule(&host->finish_tasklet); + } + + spin_unlock_irqrestore(&host->lock, flags); + } + + mmc_remove_host(host->mmc); + + if (!dead) + bcm2835_mmc_reset(host, SDHCI_RESET_ALL); + + free_irq(host->irq, host); + + del_timer_sync(&host->timer); + + tasklet_kill(&host->finish_tasklet); + + mmc_free_host(host->mmc); + platform_set_drvdata(pdev, NULL); + + return 0; +} + + +static const struct of_device_id bcm2835_mmc_match[] = { + { .compatible = "brcm,bcm2835-mmc" }, + { } +}; +MODULE_DEVICE_TABLE(of, bcm2835_mmc_match); + + + +static struct platform_driver bcm2835_mmc_driver = { + .probe = bcm2835_mmc_probe, + .remove = bcm2835_mmc_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = bcm2835_mmc_match, + }, +}; +module_platform_driver(bcm2835_mmc_driver); + +module_param(mmc_debug, uint, 0644); +module_param(mmc_debug2, uint, 0644); +MODULE_ALIAS("platform:mmc-bcm2835"); +MODULE_DESCRIPTION("BCM2835 SDHCI driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gellert Weisz"); diff -Nur --no-dereference '--exclude=.git' linux-4.18.16/drivers/mmc/host/bcm2835-sdhost.c linux-vendor/drivers/mmc/host/bcm2835-sdhost.c --- linux-4.18.16/drivers/mmc/host/bcm2835-sdhost.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-vendor/drivers/mmc/host/bcm2835-sdhost.c 2018-10-29 19:31:21.654727573 +0100 @@ -0,0 +1,2191 @@ +/* + * BCM2835 SD host driver. + * + * Author: Phil Elwell + * Copyright (C) 2015-2016 Raspberry Pi (Trading) Ltd. + * + * Based on + * mmc-bcm2835.c by Gellert Weisz + * which is, in turn, based on + * sdhci-bcm2708.c by Broadcom + * sdhci-bcm2835.c by Stephen Warren and Oleksandr Tymoshenko + * sdhci.c and sdhci-pci.c by Pierre Ossman + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define FIFO_READ_THRESHOLD 4 +#define FIFO_WRITE_THRESHOLD 4 +#define ALLOW_CMD23_READ 1 +#define ALLOW_CMD23_WRITE 0 +#define ENABLE_LOG 1 +#define SDDATA_FIFO_PIO_BURST 8 +#define CMD_DALLY_US 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* For mmc_card_blockaddr */ +#include "../core/card.h" + +#define DRIVER_NAME "sdhost-bcm2835" + +#define SDCMD 0x00 /* Command to SD card - 16 R/W */ +#define SDARG 0x04 /* Argument to SD card - 32 R/W */ +#define SDTOUT 0x08 /* Start value for timeout counter - 32 R/W */ +#define SDCDIV 0x0c /* Start value for clock divider - 11 R/W */ +#define SDRSP0 0x10 /* SD card response (31:0) - 32 R */ +#define SDRSP1 0x14 /* SD card response (63:32) - 32 R */ +#define SDRSP2 0x18 /* SD card response (95:64) - 32 R */ +#define SDRSP3 0x1c /* SD card response (127:96) - 32 R */ +#define SDHSTS 0x20 /* SD host status - 11 R */ +#define SDVDD 0x30 /* SD card power control - 1 R/W */ +#define SDEDM 0x34 /* Emergency Debug Mode - 13 R/W */ +#define SDHCFG 0x38 /* Host configuration - 2 R/W */ +#define SDHBCT 0x3c /* Host byte count (debug) - 32 R/W */ +#define SDDATA 0x40 /* Data to/from SD card - 32 R/W */ +#define SDHBLC 0x50 /* Host block count (SDIO/SDHC) - 9 R/W */ + +#define SDCMD_NEW_FLAG 0x8000 +#define SDCMD_FAIL_FLAG 0x4000 +#define SDCMD_BUSYWAIT 0x800 +#define SDCMD_NO_RESPONSE 0x400 +#define SDCMD_LONG_RESPONSE 0x200 +#define SDCMD_WRITE_CMD 0x80 +#define SDCMD_READ_CMD 0x40 +#define SDCMD_CMD_MASK 0x3f + +#define SDCDIV_MAX_CDIV 0x7ff + +#define SDHSTS_BUSY_IRPT 0x400 +#define SDHSTS_BLOCK_IRPT 0x200 +#define SDHSTS_SDIO_IRPT 0x100 +#define SDHSTS_REW_TIME_OUT 0x80 +#define SDHSTS_CMD_TIME_OUT 0x40 +#define SDHSTS_CRC16_ERROR 0x20 +#define SDHSTS_CRC7_ERROR 0x10 +#define SDHSTS_FIFO_ERROR 0x08 +/* Reserved */ +/* Reserved */ +#define SDHSTS_DATA_FLAG 0x01 + +#define SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC7_ERROR|SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR) +#define SDHSTS_ERROR_MASK (SDHSTS_CMD_TIME_OUT|SDHSTS_TRANSFER_ERROR_MASK) + +#define SDHCFG_BUSY_IRPT_EN (1<<10) +#define SDHCFG_BLOCK_IRPT_EN (1<<8) +#define SDHCFG_SDIO_IRPT_EN (1<<5) +#define SDHCFG_DATA_IRPT_EN (1<<4) +#define SDHCFG_SLOW_CARD (1<<3) +#define SDHCFG_WIDE_EXT_BUS (1<<2) +#define SDHCFG_WIDE_INT_BUS (1<<1) +#define SDHCFG_REL_CMD_LINE (1<<0) + +#define SDEDM_FORCE_DATA_MODE (1<<19) +#define SDEDM_CLOCK_PULSE (1<<20) +#define SDEDM_BYPASS (1<<21) + +#define SDEDM_WRITE_THRESHOLD_SHIFT 9 +#define SDEDM_READ_THRESHOLD_SHIFT 14 +#define SDEDM_THRESHOLD_MASK 0x1f + +#define SDEDM_FSM_MASK 0xf +#define SDEDM_FSM_IDENTMODE 0x0 +#define SDEDM_FSM_DATAMODE 0x1 +#define SDEDM_FSM_READDATA 0x2 +#define SDEDM_FSM_WRITEDATA 0x3 +#define SDEDM_FSM_READWAIT 0x4 +#define SDEDM_FSM_READCRC 0x5 +#define SDEDM_FSM_WRITECRC 0x6 +#define SDEDM_FSM_WRITEWAIT1 0x7 +#define SDEDM_FSM_POWERDOWN 0x8 +#define SDEDM_FSM_POWERUP 0x9 +#define SDEDM_FSM_WRITESTART1 0xa +#define SDEDM_FSM_WRITESTART2 0xb +#define SDEDM_FSM_GENPULSES 0xc +#define SDEDM_FSM_WRITEWAIT2 0xd +#define SDEDM_FSM_STARTPOWDOWN 0xf + +#define SDDATA_FIFO_WORDS 16 + +#define USE_CMD23_FLAGS ((ALLOW_CMD23_READ * MMC_DATA_READ) | \ + (ALLOW_CMD23_WRITE * MMC_DATA_WRITE)) + +#define MHZ 1000000 + + +struct bcm2835_host { + spinlock_t lock; + + void __iomem *ioaddr; + u32 bus_addr; + + struct mmc_host *mmc; + + u32 pio_timeout; /* In jiffies */ + + int clock; /* Current clock speed */ + + bool slow_card; /* Force 11-bit divisor */ + + unsigned int max_clk; /* Max possible freq */ + + struct tasklet_struct finish_tasklet; /* Tasklet structures */ + + struct work_struct cmd_wait_wq; /* Workqueue function */ + + struct timer_list timer; /* Timer for timeouts */ + + struct sg_mapping_iter sg_miter; /* SG state for PIO */ + unsigned int blocks; /* remaining PIO blocks */ + + int irq; /* Device IRQ */ + + u32 cmd_quick_poll_retries; + u32 ns_per_fifo_word; + + /* cached registers */ + u32 hcfg; + u32 cdiv; + + struct mmc_request *mrq; /* Current request */ + struct mmc_command *cmd; /* Current command */ + struct mmc_data *data; /* Current data request */ + unsigned int data_complete:1; /* Data finished before cmd */ + + unsigned int flush_fifo:1; /* Drain the fifo when finishing */ + + unsigned int use_busy:1; /* Wait for busy interrupt */ + + unsigned int use_sbc:1; /* Send CMD23 */ + + unsigned int debug:1; /* Enable debug output */ + unsigned int firmware_sets_cdiv:1; /* Let the firmware manage the clock */ + unsigned int reset_clock:1; /* Reset the clock fore the next request */ + + /*DMA part*/ + struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */ + struct dma_chan *dma_chan; /* Channel in use */ + struct dma_slave_config dma_cfg_rx; + struct dma_slave_config dma_cfg_tx; + struct dma_async_tx_descriptor *dma_desc; + u32 dma_dir; + u32 drain_words; + struct page *drain_page; + u32 drain_offset; + + bool allow_dma; + bool use_dma; + /*end of DMA part*/ + + int max_delay; /* maximum length of time spent waiting */ + struct timeval stop_time; /* when the last stop was issued */ + u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ + u32 delay_after_this_stop; /* minimum time between this stop and subsequent data transfer */ + u32 user_overclock_50; /* User's preferred frequency to use when 50MHz is requested (in MHz) */ + u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ + u32 overclock; /* Current frequency if overclocked, else zero */ + u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ + + u32 sectors; /* Cached card size in sectors */ +}; + +#if ENABLE_LOG + +struct log_entry_struct { + char event[4]; + u32 timestamp; + u32 param1; + u32 param2; +}; + +typedef struct log_entry_struct LOG_ENTRY_T; + +LOG_ENTRY_T *sdhost_log_buf; +dma_addr_t sdhost_log_addr; +static u32 sdhost_log_idx; +static spinlock_t log_lock; +static void __iomem *timer_base; + +#define LOG_ENTRIES (256*1) +#define LOG_SIZE (sizeof(LOG_ENTRY_T)*LOG_ENTRIES) + +static void log_init(struct device *dev, u32 bus_to_phys) +{ + spin_lock_init(&log_lock); + sdhost_log_buf = dma_zalloc_coherent(dev, LOG_SIZE, &sdhost_log_addr, + GFP_KERNEL); + if (sdhost_log_buf) { + pr_info("sdhost: log_buf @ %p (%x)\n", + sdhost_log_buf, sdhost_log_addr); + timer_base = ioremap_nocache(bus_to_phys + 0x7e003000, SZ_4K); + if (!timer_base) + pr_err("sdhost: failed to remap timer\n"); + } + else + pr_err("sdhost: failed to allocate log buf\n"); +} + +static void log_event_impl(const char *event, u32 param1, u32 param2) +{ + if (sdhost_log_buf) { + LOG_ENTRY_T *entry; + unsigned long flags; + + spin_lock_irqsave(&log_lock, flags); + + entry = sdhost_log_buf + sdhost_log_idx; + memcpy(entry->event, event, 4); + entry->timestamp = (readl(timer_base + 4) & 0x3fffffff) + + (smp_processor_id()<<30); + entry->param1 = param1; + entry->param2 = param2; + sdhost_log_idx = (sdhost_log_idx + 1) % LOG_ENTRIES; + + spin_unlock_irqrestore(&log_lock, flags); + } +} + +static void log_dump(void) +{ + if (sdhost_log_buf) { + LOG_ENTRY_T *entry; + unsigned long flags; + int idx; + + spin_lock_irqsave(&log_lock, flags); + + idx = sdhost_log_idx; + do { + entry = sdhost_log_buf + idx; + if (entry->event[0] != '\0') + pr_info("[%08x] %.4s %x %x\n", + entry->timestamp, + entry->event, + entry->param1, + entry->param2); + idx = (idx + 1) % LOG_ENTRIES; + } while (idx != sdhost_log_idx); + + spin_unlock_irqrestore(&log_lock, flags); + } +} + +#define log_event(event, param1, param2) log_event_impl(event, param1, param2) + +#else + +#define log_init(x) (void)0 +#define log_event(event, param1, param2) (void)0 +#define log_dump() (void)0 + +#endif + +static inline void bcm2835_sdhost_write(struct bcm2835_host *host, u32 val, int reg) +{ + writel(val, host->ioaddr + reg); +} + +static inline u32 bcm2835_sdhost_read(struct bcm2835_host *host, int reg) +{ + return readl(host->ioaddr + reg); +} + +static inline u32 bcm2835_sdhost_read_relaxed(struct bcm2835_host *host, int reg) +{ + return readl_relaxed(host->ioaddr + reg); +} + +static void bcm2835_sdhost_dumpcmd(struct bcm2835_host *host, + struct mmc_command *cmd, + const char *label) +{ + if (cmd) + pr_info("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", + mmc_hostname(host->mmc), + (cmd == host->cmd) ? '>' : ' ', + label, cmd->opcode, cmd->arg, cmd->flags, + cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3], + cmd->error); +} + +static void bcm2835_sdhost_dumpregs(struct bcm2835_host *host) +{ + if (host->mrq) + { + bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc"); + bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd"); + if (host->mrq->data) + pr_info("%s: data blocks %x blksz %x - err %d\n", + mmc_hostname(host->mmc), + host->mrq->data->blocks, + host->mrq->data->blksz, + host->mrq->data->error); + bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop"); + } + + pr_info("%s: =========== REGISTER DUMP ===========\n", + mmc_hostname(host->mmc)); + + pr_info("%s: SDCMD 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDCMD)); + pr_info("%s: SDARG 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDARG)); + pr_info("%s: SDTOUT 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDTOUT)); + pr_info("%s: SDCDIV 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDCDIV)); + pr_info("%s: SDRSP0 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP0)); + pr_info("%s: SDRSP1 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP1)); + pr_info("%s: SDRSP2 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP2)); + pr_info("%s: SDRSP3 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP3)); + pr_info("%s: SDHSTS 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHSTS)); + pr_info("%s: SDVDD 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDVDD)); + pr_info("%s: SDEDM 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDEDM)); + pr_info("%s: SDHCFG 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHCFG)); + pr_info("%s: SDHBCT 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHBCT)); + pr_info("%s: SDHBLC 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHBLC)); + + pr_info("%s: ===========================================\n", + mmc_hostname(host->mmc)); +} + +static void bcm2835_sdhost_set_power(struct bcm2835_host *host, bool on) +{ + bcm2835_sdhost_write(host, on ? 1 : 0, SDVDD); +} + +static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) +{ + u32 temp; + + if (host->debug) + pr_info("%s: reset\n", mmc_hostname(host->mmc)); + + bcm2835_sdhost_set_power(host, false); + + bcm2835_sdhost_write(host, 0, SDCMD); + bcm2835_sdhost_write(host, 0, SDARG); + bcm2835_sdhost_write(host, 0xf00000, SDTOUT); + bcm2835_sdhost_write(host, 0, SDCDIV); + bcm2835_sdhost_write(host, 0x7f8, SDHSTS); /* Write 1s to clear */ + bcm2835_sdhost_write(host, 0, SDHCFG); + bcm2835_sdhost_write(host, 0, SDHBCT); + bcm2835_sdhost_write(host, 0, SDHBLC); + + /* Limit fifo usage due to silicon bug */ + temp = bcm2835_sdhost_read(host, SDEDM); + temp &= ~((SDEDM_THRESHOLD_MASK<clock = 0; + host->sectors = 0; + bcm2835_sdhost_write(host, host->hcfg, SDHCFG); + bcm2835_sdhost_write(host, SDCDIV_MAX_CDIV, SDCDIV); + mmiowb(); +} + +static void bcm2835_sdhost_reset(struct mmc_host *mmc) +{ + struct bcm2835_host *host = mmc_priv(mmc); + unsigned long flags; + spin_lock_irqsave(&host->lock, flags); + log_event("RST<", 0, 0); + + bcm2835_sdhost_reset_internal(host); + + spin_unlock_irqrestore(&host->lock, flags); +} + +static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); + +static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) +{ + pr_debug("bcm2835_sdhost_init(%d)\n", soft); + + /* Set interrupt enables */ + host->hcfg = SDHCFG_BUSY_IRPT_EN; + + bcm2835_sdhost_reset_internal(host); + + if (soft) { + /* force clock reconfiguration */ + host->clock = 0; + bcm2835_sdhost_set_ios(host->mmc, &host->mmc->ios); + } +} + +static void bcm2835_sdhost_wait_transfer_complete(struct bcm2835_host *host) +{ + int timediff; + u32 alternate_idle; + u32 edm; + + alternate_idle = (host->mrq->data->flags & MMC_DATA_READ) ? + SDEDM_FSM_READWAIT : SDEDM_FSM_WRITESTART1; + + edm = bcm2835_sdhost_read(host, SDEDM); + + log_event("WTC<", edm, 0); + + timediff = 0; + + while (1) { + u32 fsm = edm & SDEDM_FSM_MASK; + if ((fsm == SDEDM_FSM_IDENTMODE) || + (fsm == SDEDM_FSM_DATAMODE)) + break; + if (fsm == alternate_idle) { + bcm2835_sdhost_write(host, + edm | SDEDM_FORCE_DATA_MODE, + SDEDM); + break; + } + + timediff++; + if (timediff == 100000) { + pr_err("%s: wait_transfer_complete - still waiting after %d retries\n", + mmc_hostname(host->mmc), + timediff); + log_dump(); + bcm2835_sdhost_dumpregs(host); + host->mrq->data->error = -ETIMEDOUT; + log_event("WTC!", edm, 0); + return; + } + cpu_relax(); + edm = bcm2835_sdhost_read(host, SDEDM); + } + log_event("WTC>", edm, 0); +} + +static void bcm2835_sdhost_finish_data(struct bcm2835_host *host); + +static void bcm2835_sdhost_dma_complete(void *param) +{ + struct bcm2835_host *host = param; + struct mmc_data *data = host->data; + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + log_event("DMA<", (u32)host->data, bcm2835_sdhost_read(host, SDHSTS)); + log_event("DMA ", bcm2835_sdhost_read(host, SDCMD), + bcm2835_sdhost_read(host, SDEDM)); + + if (host->dma_chan) { + dma_unmap_sg(host->dma_chan->device->dev, + data->sg, data->sg_len, + host->dma_dir); + + host->dma_chan = NULL; + } + + if (host->drain_words) { + void *page; + u32 *buf; + + page = kmap_atomic(host->drain_page); + buf = page + host->drain_offset; + + while (host->drain_words) { + u32 edm = bcm2835_sdhost_read(host, SDEDM); + if ((edm >> 4) & 0x1f) + *(buf++) = bcm2835_sdhost_read(host, + SDDATA); + host->drain_words--; + } + + kunmap_atomic(page); + } + + bcm2835_sdhost_finish_data(host); + + log_event("DMA>", (u32)host->data, 0); + spin_unlock_irqrestore(&host->lock, flags); +} + +static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) +{ + unsigned long flags; + size_t blksize, len; + u32 *buf; + unsigned long wait_max; + + blksize = host->data->blksz; + + wait_max = jiffies + msecs_to_jiffies(host->pio_timeout); + + local_irq_save(flags); + + while (blksize) { + int copy_words; + u32 hsts = 0; + + if (!sg_miter_next(&host->sg_miter)) { + host->data->error = -EINVAL; + break; + } + + len = min(host->sg_miter.length, blksize); + if (len % 4) { + host->data->error = -EINVAL; + break; + } + + blksize -= len; + host->sg_miter.consumed = len; + + buf = (u32 *)host->sg_miter.addr; + + copy_words = len/4; + + while (copy_words) { + int burst_words, words; + u32 edm; + + burst_words = SDDATA_FIFO_PIO_BURST; + if (burst_words > copy_words) + burst_words = copy_words; + edm = bcm2835_sdhost_read(host, SDEDM); + words = ((edm >> 4) & 0x1f); + + if (words < burst_words) { + int fsm_state = (edm & SDEDM_FSM_MASK); + if ((fsm_state != SDEDM_FSM_READDATA) && + (fsm_state != SDEDM_FSM_READWAIT) && + (fsm_state != SDEDM_FSM_READCRC)) { + hsts = bcm2835_sdhost_read(host, + SDHSTS); + pr_info("%s: fsm %x, hsts %x\n", + mmc_hostname(host->mmc), + fsm_state, hsts); + if (hsts & SDHSTS_ERROR_MASK) + break; + } + + if (time_after(jiffies, wait_max)) { + pr_err("%s: PIO read timeout - EDM %x\n", + mmc_hostname(host->mmc), + edm); + hsts = SDHSTS_REW_TIME_OUT; + break; + } + ndelay((burst_words - words) * + host->ns_per_fifo_word); + continue; + } else if (words > copy_words) { + words = copy_words; + } + + copy_words -= words; + + while (words) { + *(buf++) = bcm2835_sdhost_read(host, SDDATA); + words--; + } + } + + if (hsts & SDHSTS_ERROR_MASK) + break; + } + + sg_miter_stop(&host->sg_miter); + + local_irq_restore(flags); +} + +static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) +{ + unsigned long flags; + size_t blksize, len; + u32 *buf; + unsigned long wait_max; + + blksize = host->data->blksz; + + wait_max = jiffies + msecs_to_jiffies(host->pio_timeout); + + local_irq_save(flags); + + while (blksize) { + int copy_words; + u32 hsts = 0; + + if (!sg_miter_next(&host->sg_miter)) { + host->data->error = -EINVAL; + break; + } + + len = min(host->sg_miter.length, blksize); + if (len % 4) { + host->data->error = -EINVAL; + break; + } + + blksize -= len; + host->sg_miter.consumed = len; + + buf = (u32 *)host->sg_miter.addr; + + copy_words = len/4; + + while (copy_words) { + int burst_words, words; + u32 edm; + + burst_words = SDDATA_FIFO_PIO_BURST; + if (burst_words > copy_words) + burst_words = copy_words; + edm = bcm2835_sdhost_read(host, SDEDM); + words = SDDATA_FIFO_WORDS - ((edm >> 4) & 0x1f); + + if (words < burst_words) { + int fsm_state = (edm & SDEDM_FSM_MASK); + if ((fsm_state != SDEDM_FSM_WRITEDATA) && + (fsm_state != SDEDM_FSM_WRITESTART1) && + (fsm_state != SDEDM_FSM_WRITESTART2)) { + hsts = bcm2835_sdhost_read(host, + SDHSTS); + pr_info("%s: fsm %x, hsts %x\n", + mmc_hostname(host->mmc), + fsm_state, hsts); + if (hsts & SDHSTS_ERROR_MASK) + break; + } + + if (time_after(jiffies, wait_max)) { + pr_err("%s: PIO write timeout - EDM %x\n", + mmc_hostname(host->mmc), + edm); + hsts = SDHSTS_REW_TIME_OUT; + break; + } + ndelay((burst_words - words) * + host->ns_per_fifo_word); + continue; + } else if (words > copy_words) { + words = copy_words; + } + + copy_words -= words; + + while (words) { + bcm2835_sdhost_write(host, *(buf++), SDDATA); + words--; + } + } + + if (hsts & SDHSTS_ERROR_MASK) + break; + } + + sg_miter_stop(&host->sg_miter); + + local_irq_restore(flags); +} + +static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) +{ + u32 sdhsts; + bool is_read; + BUG_ON(!host->data); + log_event("XFP<", (u32)host->data, host->blocks); + + is_read = (host->data->flags & MMC_DATA_READ) != 0; + if (is_read) + bcm2835_sdhost_read_block_pio(host); + else + bcm2835_sdhost_write_block_pio(host); + + sdhsts = bcm2835_sdhost_read(host, SDHSTS); + if (sdhsts & (SDHSTS_CRC16_ERROR | + SDHSTS_CRC7_ERROR | + SDHSTS_FIFO_ERROR)) { + pr_err("%s: %s transfer error - HSTS %x\n", + mmc_hostname(host->mmc), + is_read ? "read" : "write", + sdhsts); + host->data->error = -EILSEQ; + } else if ((sdhsts & (SDHSTS_CMD_TIME_OUT | + SDHSTS_REW_TIME_OUT))) { + pr_err("%s: %s timeout error - HSTS %x\n", + mmc_hostname(host->mmc), + is_read ? "read" : "write", + sdhsts); + host->data->error = -ETIMEDOUT; + } + log_event("XFP>", (u32)host->data, host->blocks); +} + +static void bcm2835_sdhost_prepare_dma(struct bcm2835_host *host, + struct mmc_data *data) +{ + int len, dir_data, dir_slave; + struct dma_async_tx_descriptor *desc = NULL; + struct dma_chan *dma_chan; + + log_event("PRD<", (u32)data, 0); + pr_debug("bcm2835_sdhost_prepare_dma()\n"); + + dma_chan = host->dma_chan_rxtx; + if (data->flags & MMC_DATA_READ) { + dir_data = DMA_FROM_DEVICE; + dir_slave = DMA_DEV_TO_MEM; + } else { + dir_data = DMA_TO_DEVICE; + dir_slave = DMA_MEM_TO_DEV; + } + log_event("PRD1", (u32)dma_chan, 0); + + BUG_ON(!dma_chan->device); + BUG_ON(!dma_chan->device->dev); + BUG_ON(!data->sg); + + /* The block doesn't manage the FIFO DREQs properly for multi-block + transfers, so don't attempt to DMA the final few words. + Unfortunately this requires the final sg entry to be trimmed. + N.B. This code demands that the overspill is contained in + a single sg entry. + */ + + host->drain_words = 0; + if ((data->blocks > 1) && (dir_data == DMA_FROM_DEVICE)) { + struct scatterlist *sg; + u32 len; + int i; + + len = min((u32)(FIFO_READ_THRESHOLD - 1) * 4, + (u32)data->blocks * data->blksz); + + for_each_sg(data->sg, sg, data->sg_len, i) { + if (sg_is_last(sg)) { + BUG_ON(sg->length < len); + sg->length -= len; + host->drain_page = sg_page(sg); + host->drain_offset = sg->offset + sg->length; + } + } + host->drain_words = len/4; + } + + /* The parameters have already been validated, so this will not fail */ + (void)dmaengine_slave_config(dma_chan, + (dir_data == DMA_FROM_DEVICE) ? + &host->dma_cfg_rx : + &host->dma_cfg_tx); + + len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len, + dir_data); + + log_event("PRD2", len, 0); + if (len > 0) + desc = dmaengine_prep_slave_sg(dma_chan, data->sg, + len, dir_slave, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + log_event("PRD3", (u32)desc, 0); + + if (desc) { + desc->callback = bcm2835_sdhost_dma_complete; + desc->callback_param = host; + host->dma_desc = desc; + host->dma_chan = dma_chan; + host->dma_dir = dir_data; + } + log_event("PDM>", (u32)data, 0); +} + +static void bcm2835_sdhost_start_dma(struct bcm2835_host *host) +{ + log_event("SDMA", (u32)host->data, (u32)host->dma_chan); + dmaengine_submit(host->dma_desc); + dma_async_issue_pending(host->dma_chan); +} + +static void bcm2835_sdhost_set_transfer_irqs(struct bcm2835_host *host) +{ + u32 all_irqs = SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN | + SDHCFG_BUSY_IRPT_EN; + if (host->dma_desc) + host->hcfg = (host->hcfg & ~all_irqs) | + SDHCFG_BUSY_IRPT_EN; + else + host->hcfg = (host->hcfg & ~all_irqs) | + SDHCFG_DATA_IRPT_EN | + SDHCFG_BUSY_IRPT_EN; + + bcm2835_sdhost_write(host, host->hcfg, SDHCFG); +} + +static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_command *cmd) +{ + struct mmc_data *data = cmd->data; + + WARN_ON(host->data); + + host->data = data; + if (!data) + return; + + /* Sanity checks */ + BUG_ON(data->blksz * data->blocks > 524288); + BUG_ON(data->blksz > host->mmc->max_blk_size); + BUG_ON(data->blocks > 65535); + + host->data_complete = 0; + host->flush_fifo = 0; + host->data->bytes_xfered = 0; + + if (!host->sectors && host->mmc->card) { + struct mmc_card *card = host->mmc->card; + if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { + /* + * The EXT_CSD sector count is in number of 512 byte + * sectors. + */ + host->sectors = card->ext_csd.sectors; + } else { + /* + * The CSD capacity field is in units of read_blkbits. + * set_capacity takes units of 512 bytes. + */ + host->sectors = card->csd.capacity << + (card->csd.read_blkbits - 9); + } + } + + if (!host->dma_desc) { + /* Use PIO */ + int flags = SG_MITER_ATOMIC; + + if (data->flags & MMC_DATA_READ) + flags |= SG_MITER_TO_SG; + else + flags |= SG_MITER_FROM_SG; + sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); + host->blocks = data->blocks; + } + + bcm2835_sdhost_set_transfer_irqs(host); + + bcm2835_sdhost_write(host, data->blksz, SDHBCT); + bcm2835_sdhost_write(host, data->blocks, SDHBLC); + + BUG_ON(!host->data); +} + +bool bcm2835_sdhost_send_command(struct bcm2835_host *host, + struct mmc_command *cmd) +{ + u32 sdcmd, sdhsts; + unsigned long timeout; + int delay; + + WARN_ON(host->cmd); + log_event("CMD<", cmd->opcode, cmd->arg); + + if (cmd->data) + pr_debug("%s: send_command %d 0x%x " + "(flags 0x%x) - %s %d*%d\n", + mmc_hostname(host->mmc), + cmd->opcode, cmd->arg, cmd->flags, + (cmd->data->flags & MMC_DATA_READ) ? + "read" : "write", cmd->data->blocks, + cmd->data->blksz); + else + pr_debug("%s: send_command %d 0x%x (flags 0x%x)\n", + mmc_hostname(host->mmc), + cmd->opcode, cmd->arg, cmd->flags); + + /* Wait max 100 ms */ + timeout = 10000; + + while (bcm2835_sdhost_read(host, SDCMD) & SDCMD_NEW_FLAG) { + if (timeout == 0) { + pr_warn("%s: previous command never completed.\n", + mmc_hostname(host->mmc)); + if (host->debug) + bcm2835_sdhost_dumpregs(host); + cmd->error = -EILSEQ; + tasklet_schedule(&host->finish_tasklet); + return false; + } + timeout--; + udelay(10); + } + + delay = (10000 - timeout)/100; + if (delay > host->max_delay) { + host->max_delay = delay; + pr_warning("%s: controller hung for %d ms\n", + mmc_hostname(host->mmc), + host->max_delay); + } + + timeout = jiffies; + if (!cmd->data && cmd->busy_timeout > 9000) + timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; + else + timeout += 10 * HZ; + mod_timer(&host->timer, timeout); + + host->cmd = cmd; + + /* Clear any error flags */ + sdhsts = bcm2835_sdhost_read(host, SDHSTS); + if (sdhsts & SDHSTS_ERROR_MASK) + bcm2835_sdhost_write(host, sdhsts, SDHSTS); + + if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { + pr_err("%s: unsupported response type!\n", + mmc_hostname(host->mmc)); + cmd->error = -EINVAL; + tasklet_schedule(&host->finish_tasklet); + return false; + } + + bcm2835_sdhost_prepare_data(host, cmd); + + bcm2835_sdhost_write(host, cmd->arg, SDARG); + + sdcmd = cmd->opcode & SDCMD_CMD_MASK; + + host->use_busy = 0; + if (!(cmd->flags & MMC_RSP_PRESENT)) { + sdcmd |= SDCMD_NO_RESPONSE; + } else { + if (cmd->flags & MMC_RSP_136) + sdcmd |= SDCMD_LONG_RESPONSE; + if (cmd->flags & MMC_RSP_BUSY) { + sdcmd |= SDCMD_BUSYWAIT; + host->use_busy = 1; + } + } + + if (cmd->data) { + log_event("CMDD", cmd->data->blocks, cmd->data->blksz); + if (host->delay_after_this_stop) { + struct timeval now; + int time_since_stop; + do_gettimeofday(&now); + time_since_stop = (now.tv_sec - host->stop_time.tv_sec); + if (time_since_stop < 2) { + /* Possibly less than one second */ + time_since_stop = time_since_stop * 1000000 + + (now.tv_usec - host->stop_time.tv_usec); + if (time_since_stop < + host->delay_after_this_stop) + udelay(host->delay_after_this_stop - + time_since_stop); + } + } + + host->delay_after_this_stop = host->delay_after_stop; + if ((cmd->data->flags & MMC_DATA_READ) && !host->use_sbc) { + /* See if read crosses one of the hazardous sectors */ + u32 first_blk, last_blk; + + /* Intentionally include the following sector because + without CMD23/SBC the read may run on. */ + first_blk = host->mrq->cmd->arg; + last_blk = first_blk + cmd->data->blocks; + + if (((last_blk >= (host->sectors - 64)) && + (first_blk <= (host->sectors - 64))) || + ((last_blk >= (host->sectors - 32)) && + (first_blk <= (host->sectors - 32)))) { + host->delay_after_this_stop = + max(250u, host->delay_after_stop); + } + } + + if (cmd->data->flags & MMC_DATA_WRITE) + sdcmd |= SDCMD_WRITE_CMD; + if (cmd->data->flags & MMC_DATA_READ) + sdcmd |= SDCMD_READ_CMD; + } + + bcm2835_sdhost_write(host, sdcmd | SDCMD_NEW_FLAG, SDCMD); + + return true; +} + +static void bcm2835_sdhost_finish_command(struct bcm2835_host *host, + unsigned long *irq_flags); +static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host); + +static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) +{ + struct mmc_data *data; + + data = host->data; + BUG_ON(!data); + + log_event("FDA<", (u32)host->mrq, (u32)host->cmd); + pr_debug("finish_data(error %d, stop %d, sbc %d)\n", + data->error, data->stop ? 1 : 0, + host->mrq->sbc ? 1 : 0); + + host->hcfg &= ~(SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN); + bcm2835_sdhost_write(host, host->hcfg, SDHCFG); + + data->bytes_xfered = data->error ? 0 : (data->blksz * data->blocks); + + host->data_complete = 1; + + if (host->cmd) { + /* + * Data managed to finish before the + * command completed. Make sure we do + * things in the proper order. + */ + pr_debug("Finished early - HSTS %x\n", + bcm2835_sdhost_read(host, SDHSTS)); + } + else + bcm2835_sdhost_transfer_complete(host); + log_event("FDA>", (u32)host->mrq, (u32)host->cmd); +} + +static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) +{ + struct mmc_data *data; + + BUG_ON(host->cmd); + BUG_ON(!host->data); + BUG_ON(!host->data_complete); + + data = host->data; + host->data = NULL; + + log_event("TCM<", (u32)data, data->error); + pr_debug("transfer_complete(error %d, stop %d)\n", + data->error, data->stop ? 1 : 0); + + /* + * Need to send CMD12 if - + * a) open-ended multiblock transfer (no CMD23) + * b) error in multiblock transfer + */ + if (host->mrq->stop && (data->error || !host->use_sbc)) { + if (bcm2835_sdhost_send_command(host, host->mrq->stop)) { + /* No busy, so poll for completion */ + if (!host->use_busy) + bcm2835_sdhost_finish_command(host, NULL); + + if (host->delay_after_this_stop) + do_gettimeofday(&host->stop_time); + } + } else { + bcm2835_sdhost_wait_transfer_complete(host); + tasklet_schedule(&host->finish_tasklet); + } + log_event("TCM>", (u32)data, 0); +} + +/* If irq_flags is valid, the caller is in a thread context and is allowed + to sleep */ +static void bcm2835_sdhost_finish_command(struct bcm2835_host *host, + unsigned long *irq_flags) +{ + u32 sdcmd; + u32 retries; +#ifdef DEBUG + struct timeval before, after; + int timediff = 0; +#endif + + log_event("FCM<", (u32)host->mrq, (u32)host->cmd); + pr_debug("finish_command(%x)\n", bcm2835_sdhost_read(host, SDCMD)); + + BUG_ON(!host->cmd || !host->mrq); + + /* Poll quickly at first */ + + retries = host->cmd_quick_poll_retries; + if (!retries) { + /* Work out how many polls take 1us by timing 10us */ + struct timeval start, now; + int us_diff; + + retries = 1; + do { + int i; + + retries *= 2; + + do_gettimeofday(&start); + + for (i = 0; i < retries; i++) { + cpu_relax(); + sdcmd = bcm2835_sdhost_read(host, SDCMD); + } + + do_gettimeofday(&now); + us_diff = (now.tv_sec - start.tv_sec) * 1000000 + + (now.tv_usec - start.tv_usec); + } while (us_diff < 10); + + host->cmd_quick_poll_retries = ((retries * us_diff + 9)*CMD_DALLY_US)/10 + 1; + retries = 1; // We've already waited long enough this time + } + + for (sdcmd = bcm2835_sdhost_read(host, SDCMD); + (sdcmd & SDCMD_NEW_FLAG) && retries; + retries--) { + cpu_relax(); + sdcmd = bcm2835_sdhost_read(host, SDCMD); + } + + if (!retries) { + unsigned long wait_max; + + if (!irq_flags) { + /* Schedule the work */ + log_event("CWWQ", 0, 0); + schedule_work(&host->cmd_wait_wq); + return; + } + + /* Wait max 100 ms */ + wait_max = jiffies + msecs_to_jiffies(100); + while (time_before(jiffies, wait_max)) { + spin_unlock_irqrestore(&host->lock, *irq_flags); + usleep_range(1, 10); + spin_lock_irqsave(&host->lock, *irq_flags); + sdcmd = bcm2835_sdhost_read(host, SDCMD); + if (!(sdcmd & SDCMD_NEW_FLAG)) + break; + } + } + + /* Check for errors */ + if (sdcmd & SDCMD_NEW_FLAG) { + if (host->debug) { + pr_err("%s: command %d never completed.\n", + mmc_hostname(host->mmc), host->cmd->opcode); + bcm2835_sdhost_dumpregs(host); + } + host->cmd->error = -EILSEQ; + tasklet_schedule(&host->finish_tasklet); + return; + } else if (sdcmd & SDCMD_FAIL_FLAG) { + u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); + + /* Clear the errors */ + bcm2835_sdhost_write(host, SDHSTS_ERROR_MASK, SDHSTS); + + if (host->debug) + pr_info("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", + mmc_hostname(host->mmc), sdcmd, sdhsts, + bcm2835_sdhost_read(host, SDEDM)); + + if ((sdhsts & SDHSTS_CRC7_ERROR) && + (host->cmd->opcode == 1)) { + if (host->debug) + pr_info("%s: ignoring CRC7 error for CMD1\n", + mmc_hostname(host->mmc)); + } else { + if (sdhsts & SDHSTS_CMD_TIME_OUT) { + if (host->debug) + pr_warn("%s: command %d timeout\n", + mmc_hostname(host->mmc), + host->cmd->opcode); + host->cmd->error = -ETIMEDOUT; + } else { + pr_warn("%s: unexpected command %d error\n", + mmc_hostname(host->mmc), + host->cmd->opcode); + host->cmd->error = -EILSEQ; + } + tasklet_schedule(&host->finish_tasklet); + return; + } + } + + if (host->cmd->flags & MMC_RSP_PRESENT) { + if (host->cmd->flags & MMC_RSP_136) { + int i; + for (i = 0; i < 4; i++) + host->cmd->resp[3 - i] = bcm2835_sdhost_read(host, SDRSP0 + i*4); + pr_debug("%s: finish_command %08x %08x %08x %08x\n", + mmc_hostname(host->mmc), + host->cmd->resp[0], host->cmd->resp[1], host->cmd->resp[2], host->cmd->resp[3]); + log_event("RSP ", host->cmd->resp[0], host->cmd->resp[1]); + } else { + host->cmd->resp[0] = bcm2835_sdhost_read(host, SDRSP0); + pr_debug("%s: finish_command %08x\n", + mmc_hostname(host->mmc), + host->cmd->resp[0]); + log_event("RSP ", host->cmd->resp[0], 0); + } + } + + if (host->cmd == host->mrq->sbc) { + /* Finished CMD23, now send actual command. */ + host->cmd = NULL; + if (bcm2835_sdhost_send_command(host, host->mrq->cmd)) { + if (host->data && host->dma_desc) + /* DMA transfer starts now, PIO starts after irq */ + bcm2835_sdhost_start_dma(host); + + if (!host->use_busy) + bcm2835_sdhost_finish_command(host, NULL); + } + } else if (host->cmd == host->mrq->stop) { + /* Finished CMD12 */ + tasklet_schedule(&host->finish_tasklet); + } else { + /* Processed actual command. */ + host->cmd = NULL; + if (!host->data) + tasklet_schedule(&host->finish_tasklet); + else if (host->data_complete) + bcm2835_sdhost_transfer_complete(host); + } + log_event("FCM>", (u32)host->mrq, (u32)host->cmd); +} + +static void bcm2835_sdhost_timeout(struct timer_list *t) +{ + struct bcm2835_host *host = from_timer(host, t, timer); + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + log_event("TIM<", 0, 0); + + if (host->mrq) { + pr_err("%s: timeout waiting for hardware interrupt.\n", + mmc_hostname(host->mmc)); + log_dump(); + bcm2835_sdhost_dumpregs(host); + + if (host->data) { + host->data->error = -ETIMEDOUT; + bcm2835_sdhost_finish_data(host); + } else { + if (host->cmd) + host->cmd->error = -ETIMEDOUT; + else + host->mrq->cmd->error = -ETIMEDOUT; + + pr_debug("timeout_timer tasklet_schedule\n"); + tasklet_schedule(&host->finish_tasklet); + } + } + + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); +} + +static void bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) +{ + log_event("IRQB", (u32)host->cmd, intmask); + if (!host->cmd) { + pr_err("%s: got command busy interrupt 0x%08x even " + "though no command operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); + return; + } + + if (!host->use_busy) { + pr_err("%s: got command busy interrupt 0x%08x even " + "though not expecting one.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); + return; + } + host->use_busy = 0; + + if (intmask & SDHSTS_ERROR_MASK) + { + pr_err("sdhost_busy_irq: intmask %x, data %p\n", intmask, host->mrq->data); + if (intmask & SDHSTS_CRC7_ERROR) + host->cmd->error = -EILSEQ; + else if (intmask & (SDHSTS_CRC16_ERROR | + SDHSTS_FIFO_ERROR)) { + if (host->mrq->data) + host->mrq->data->error = -EILSEQ; + else + host->cmd->error = -EILSEQ; + } else if (intmask & SDHSTS_REW_TIME_OUT) { + if (host->mrq->data) + host->mrq->data->error = -ETIMEDOUT; + else + host->cmd->error = -ETIMEDOUT; + } else if (intmask & SDHSTS_CMD_TIME_OUT) + host->cmd->error = -ETIMEDOUT; + + if (host->debug) { + log_dump(); + bcm2835_sdhost_dumpregs(host); + } + } + else + bcm2835_sdhost_finish_command(host, NULL); +} + +static void bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) +{ + /* There are no dedicated data/space available interrupt + status bits, so it is necessary to use the single shared + data/space available FIFO status bits. It is therefore not + an error to get here when there is no data transfer in + progress. */ + log_event("IRQD", (u32)host->data, intmask); + if (!host->data) + return; + + if (intmask & (SDHSTS_CRC16_ERROR | + SDHSTS_FIFO_ERROR | + SDHSTS_REW_TIME_OUT)) { + if (intmask & (SDHSTS_CRC16_ERROR | + SDHSTS_FIFO_ERROR)) + host->data->error = -EILSEQ; + else + host->data->error = -ETIMEDOUT; + + if (host->debug) { + log_dump(); + bcm2835_sdhost_dumpregs(host); + } + } + + if (host->data->error) { + bcm2835_sdhost_finish_data(host); + } else if (host->data->flags & MMC_DATA_WRITE) { + /* Use the block interrupt for writes after the first block */ + host->hcfg &= ~(SDHCFG_DATA_IRPT_EN); + host->hcfg |= SDHCFG_BLOCK_IRPT_EN; + bcm2835_sdhost_write(host, host->hcfg, SDHCFG); + bcm2835_sdhost_transfer_pio(host); + } else { + bcm2835_sdhost_transfer_pio(host); + host->blocks--; + if ((host->blocks == 0) || host->data->error) + bcm2835_sdhost_finish_data(host); + } +} + +static void bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) +{ + log_event("IRQK", (u32)host->data, intmask); + if (!host->data) { + pr_err("%s: got block interrupt 0x%08x even " + "though no data operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); + return; + } + + if (intmask & (SDHSTS_CRC16_ERROR | + SDHSTS_FIFO_ERROR | + SDHSTS_REW_TIME_OUT)) { + if (intmask & (SDHSTS_CRC16_ERROR | + SDHSTS_FIFO_ERROR)) + host->data->error = -EILSEQ; + else + host->data->error = -ETIMEDOUT; + + if (host->debug) { + log_dump(); + bcm2835_sdhost_dumpregs(host); + } + } + + if (!host->dma_desc) { + BUG_ON(!host->blocks); + if (host->data->error || (--host->blocks == 0)) { + bcm2835_sdhost_finish_data(host); + } else { + bcm2835_sdhost_transfer_pio(host); + } + } else if (host->data->flags & MMC_DATA_WRITE) { + bcm2835_sdhost_finish_data(host); + } +} + +static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) +{ + irqreturn_t result = IRQ_NONE; + struct bcm2835_host *host = dev_id; + u32 intmask; + + spin_lock(&host->lock); + + intmask = bcm2835_sdhost_read(host, SDHSTS); + log_event("IRQ<", intmask, 0); + + bcm2835_sdhost_write(host, + SDHSTS_BUSY_IRPT | + SDHSTS_BLOCK_IRPT | + SDHSTS_SDIO_IRPT | + SDHSTS_DATA_FLAG, + SDHSTS); + + if (intmask & SDHSTS_BLOCK_IRPT) { + bcm2835_sdhost_block_irq(host, intmask); + result = IRQ_HANDLED; + } + + if (intmask & SDHSTS_BUSY_IRPT) { + bcm2835_sdhost_busy_irq(host, intmask); + result = IRQ_HANDLED; + } + + /* There is no true data interrupt status bit, so it is + necessary to qualify the data flag with the interrupt + enable bit */ + if ((intmask & SDHSTS_DATA_FLAG) && + (host->hcfg & SDHCFG_DATA_IRPT_EN)) { + bcm2835_sdhost_data_irq(host, intmask); + result = IRQ_HANDLED; + } + + mmiowb(); + + log_event("IRQ>", bcm2835_sdhost_read(host, SDHSTS), 0); + spin_unlock(&host->lock); + + return result; +} + +void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) +{ + int div = 0; /* Initialized for compiler warning */ + unsigned int input_clock = clock; + unsigned long flags; + + if (host->debug) + pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); + + if (host->overclock_50 && (clock == 50*MHZ)) + clock = host->overclock_50 * MHZ + (MHZ - 1); + + /* The SDCDIV register has 11 bits, and holds (div - 2). + But in data mode the max is 50MHz wihout a minimum, and only the + bottom 3 bits are used. Since the switch over is automatic (unless + we have marked the card as slow...), chosen values have to make + sense in both modes. + Ident mode must be 100-400KHz, so can range check the requested + clock. CMD15 must be used to return to data mode, so this can be + monitored. + + clock 250MHz -> 0->125MHz, 1->83.3MHz, 2->62.5MHz, 3->50.0MHz + 4->41.7MHz, 5->35.7MHz, 6->31.3MHz, 7->27.8MHz + + 623->400KHz/27.8MHz + reset value (507)->491159/50MHz + + BUT, the 3-bit clock divisor in data mode is too small if the + core clock is higher than 250MHz, so instead use the SLOW_CARD + configuration bit to force the use of the ident clock divisor + at all times. + */ + + host->mmc->actual_clock = 0; + + if (host->firmware_sets_cdiv) { + u32 msg[3] = { clock, 0, 0 }; + + rpi_firmware_property(rpi_firmware_get(NULL), + RPI_FIRMWARE_SET_SDHOST_CLOCK, + &msg, sizeof(msg)); + + clock = max(msg[1], msg[2]); + spin_lock_irqsave(&host->lock, flags); + } else { + spin_lock_irqsave(&host->lock, flags); + if (clock < 100000) { + /* Can't stop the clock, but make it as slow as + * possible to show willing + */ + host->cdiv = SDCDIV_MAX_CDIV; + bcm2835_sdhost_write(host, host->cdiv, SDCDIV); + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); + return; + } + + div = host->max_clk / clock; + if (div < 2) + div = 2; + if ((host->max_clk / div) > clock) + div++; + div -= 2; + + if (div > SDCDIV_MAX_CDIV) + div = SDCDIV_MAX_CDIV; + + clock = host->max_clk / (div + 2); + + host->cdiv = div; + bcm2835_sdhost_write(host, host->cdiv, SDCDIV); + + if (host->debug) + pr_info("%s: clock=%d -> max_clk=%d, cdiv=%x " + "(actual clock %d)\n", + mmc_hostname(host->mmc), input_clock, + host->max_clk, host->cdiv, + clock); + } + + /* Calibrate some delays */ + + host->ns_per_fifo_word = (1000000000/clock) * + ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); + + if (input_clock == 50 * MHZ) { + if (clock > input_clock) { + /* Save the closest value, to make it easier + to reduce in the event of error */ + host->overclock_50 = (clock/MHZ); + + if (clock != host->overclock) { + pr_info("%s: overclocking to %dHz\n", + mmc_hostname(host->mmc), clock); + host->overclock = clock; + } + } else if (host->overclock) { + host->overclock = 0; + if (clock == 50 * MHZ) + pr_warn("%s: cancelling overclock\n", + mmc_hostname(host->mmc)); + } + } else if (input_clock == 0) { + /* Reset the preferred ove