aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4')
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Disable-forced-software-CS.patch47
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Re-enable-HW-CS.patch80
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0135-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0136-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0135-spi-spi-bcm2835-Disable-forced-software-CS.patch47
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0136-configs-Enable-the-AD193x-codecs.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0137-configs-Enable-the-AD193x-codecs.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0137-lan78xx-EEE-support-is-now-a-PHY-property.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0138-lan78xx-EEE-support-is-now-a-PHY-property.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0138-Revert-staging-vchiq-delete-vchiq_killable.h.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0139-Revert-staging-vchiq-delete-vchiq_killable.h.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0139-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0140-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0140-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0141-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0141-bcm2835-dma-Add-support-for-per-channel-flags.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0142-bcm2835-dma-Add-support-for-per-channel-flags.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0142-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0143-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0143-rtc-rv3028-Add-backup-switchover-mode-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0144-rtc-rv3028-Add-backup-switchover-mode-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0144-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0145-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0145-lan78xx-use-default-alignment-for-rx-buffers.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0146-lan78xx-use-default-alignment-for-rx-buffers.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0146-Added-IQaudIO-Pi-Codec-board-support-2969.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0147-Added-IQaudIO-Pi-Codec-board-support-2969.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0147-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0148-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0148-media-ov5647-Add-set_fmt-and-get_fmt-calls.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0149-media-ov5647-Add-set_fmt-and-get_fmt-calls.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0149-media-Documentation-DT-add-device-tree-for-PWDN-cont.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0150-media-Documentation-DT-add-device-tree-for-PWDN-cont.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0150-media-ov5647-Add-support-for-PWDN-GPIO.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0151-media-ov5647-Add-support-for-PWDN-GPIO.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0151-media-ov5647-Add-support-for-non-continuous-clock-mo.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0152-media-ov5647-Add-support-for-non-continuous-clock-mo.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0152-media-tc358743-Increase-FIFO-level-to-374.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0153-media-tc358743-Increase-FIFO-level-to-374.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0153-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0154-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0154-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0155-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0155-media-tc358743-Check-I2C-succeeded-during-probe.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0156-media-tc358743-Check-I2C-succeeded-during-probe.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0156-media-adv7180-Default-to-the-first-valid-input.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0157-media-adv7180-Default-to-the-first-valid-input.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0157-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0158-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0158-media-videodev2-Add-helper-defines-for-printing-FOUR.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0159-media-videodev2-Add-helper-defines-for-printing-FOUR.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0159-dt-bindings-Document-BCM283x-CSI2-CCP2-receiver.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0160-dt-bindings-Document-BCM283x-CSI2-CCP2-receiver.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0160-MAINTAINERS-Add-entry-for-BCM2835-Unicam-driver.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0161-MAINTAINERS-Add-entry-for-BCM2835-Unicam-driver.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0161-media-tc358743-Return-an-appropriate-colorspace-from.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0162-media-tc358743-Return-an-appropriate-colorspace-from.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0162-staging-bcm2835-camera-Fix-logical-continuation-spli.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0164-staging-bcm2835-camera-Fix-logical-continuation-spli.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0163-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0165-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0164-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0166-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0165-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0167-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0166-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0168-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0167-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0169-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0168-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0170-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0169-staging-mmal-vchiq-Add-support-for-event-callbacks.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0171-staging-mmal-vchiq-Add-support-for-event-callbacks.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0170-staging-vc04_services-Support-sending-data-to-MMAL-p.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0172-staging-vc04_services-Support-sending-data-to-MMAL-p.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0171-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0173-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0172-staging-vc04_services-Add-new-vc-sm-cma-driver.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0174-staging-vc04_services-Add-new-vc-sm-cma-driver.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0173-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0175-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0174-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0176-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0175-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0177-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0176-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0178-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0177-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0179-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0178-media-ov5647-Use-gpiod_set_value_cansleep.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0180-media-ov5647-Use-gpiod_set_value_cansleep.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0179-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0181-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0180-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0182-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0181-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0183-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0182-staging-mmal-vchiq-Always-return-the-param-size-from.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0184-staging-mmal-vchiq-Always-return-the-param-size-from.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0183-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0185-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0184-staging-bcm2835_codec-Query-supported-formats-from-t.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0186-staging-bcm2835_codec-Query-supported-formats-from-t.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0185-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0187-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0186-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0188-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0187-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0189-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0188-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0190-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0189-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0191-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0190-staging-bcm2835-codec-NULL-component-handle-on-queue.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0192-staging-bcm2835-codec-NULL-component-handle-on-queue.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0191-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0193-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0192-staging-bcm2835-codec-Refactor-default-resolution-co.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0194-staging-bcm2835-codec-Refactor-default-resolution-co.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0193-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0195-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0194-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0196-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0195-staging-mmal-vchiq-Free-the-event-context-for-contro.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0197-staging-mmal-vchiq-Free-the-event-context-for-contro.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0196-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0198-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0197-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0200-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0198-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0201-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0199-Bluetooth-Check-key-sizes-only-when-Secure-Simple-Pa.patch39
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0199-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0202-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0200-arm-bcm2835-Fix-FIQ-early-ioremap.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0203-arm-bcm2835-Fix-FIQ-early-ioremap.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0201-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0204-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0202-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0205-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0203-arm-bcm2835-DMA-can-only-address-1GB.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0206-arm-bcm2835-DMA-can-only-address-1GB.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0204-hwrng-iproc-rng200-Add-BCM2838-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0207-hwrng-iproc-rng200-Add-BCM2838-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0205-vchiq-Add-36-bit-address-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0208-vchiq-Add-36-bit-address-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0206-bcm2835-pcm.c-Support-multichannel-audio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0209-bcm2835-pcm.c-Support-multichannel-audio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0207-bcmgenet-constrain-max-DMA-burst-length.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0210-bcmgenet-constrain-max-DMA-burst-length.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0208-bcmgenet-Better-coalescing-parameter-defaults.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0211-bcmgenet-Better-coalescing-parameter-defaults.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0209-net-genet-enable-link-energy-detect-powerdown-for-ex.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0212-net-genet-enable-link-energy-detect-powerdown-for-ex.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0210-usb-xhci-Disable-the-XHCI-5-second-timeout.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0213-usb-xhci-Disable-the-XHCI-5-second-timeout.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0211-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0214-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0212-spi-bcm2835-enable-shared-interrupt-support.patch35
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0213-clk-bcm2835-Don-t-wait-for-pllh-lock.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0216-clk-bcm2835-Don-t-wait-for-pllh-lock.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0214-soc-bcm-bcm2835-pm-Add-support-for-2711.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0217-soc-bcm-bcm2835-pm-Add-support-for-2711.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0215-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0218-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0215-spi-bcm2835-enable-shared-interrupt-support.patch35
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0216-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0219-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0217-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0220-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0218-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0221-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0219-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0222-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0220-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0223-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0221-arm-bcm2835-Add-bcm2838-compatible-string.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0224-arm-bcm2835-Add-bcm2838-compatible-string.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0222-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0225-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0223-drm-v3d-Add-support-for-2711.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0226-drm-v3d-Add-support-for-2711.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0224-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0227-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0225-drm-v3d-Hook-up-the-runtime-PM-ops.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0228-drm-v3d-Hook-up-the-runtime-PM-ops.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0226-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0229-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0227-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0228-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0231-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0229-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0232-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0233-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0231-drm-vc4-Increase-max-screen-size-to-4096x4096.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Increase-max-screen-size-to-4096x4096.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0232-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0233-drm-vc4-Fix-build-warning.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Fix-build-warning.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Select-display-to-blank-during-initialisatio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0237-drm-vc4-Select-display-to-blank-during-initialisatio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Remove-now-unused-structure.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Remove-now-unused-structure.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0237-drm-vc4-Set-the-display-number-when-querying-the-dis.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Set-the-display-number-when-querying-the-dis.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Increase-max_width-height-to-7680.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Increase-max_width-height-to-7680.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Log-flags-in-fkms-mode-set.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-Log-flags-in-fkms-mode-set.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-firmware-kms-Fix-DSI-display-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-firmware-kms-Fix-DSI-display-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-handle-the-case-where-there-are-no-available.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-handle-the-case-where-there-are-no-available.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-Support-the-VEC-in-FKMS.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-Support-the-VEC-in-FKMS.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-Correct-SAND-support-for-FKMS.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-Correct-SAND-support-for-FKMS.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-Add-status-of-which-display-is-updated-throu.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Add-status-of-which-display-is-updated-throu.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Limit-fkms-to-modes-85Hz.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-Limit-fkms-to-modes-85Hz.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Ignore-HVS-unless-initialised.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0263-drm-vc4-Ignore-HVS-unless-initialised.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0264-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0265-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0263-tty-amba-pl011-Make-TX-optimisation-conditional.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0266-tty-amba-pl011-Make-TX-optimisation-conditional.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0264-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0267-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0265-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0268-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0266-staging-vc04_services-fix-compiling-in-separate-dire.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0269-staging-vc04_services-fix-compiling-in-separate-dire.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0267-clk-bcm2835-Avoid-null-pointer-exception.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0270-clk-bcm2835-Avoid-null-pointer-exception.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0268-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0271-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0269-drm-v3d-HACK-gut-runtime-pm-for-now.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0272-drm-v3d-HACK-gut-runtime-pm-for-now.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0270-drm-v3d-Clock-V3D-down-when-not-in-use.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0273-drm-v3d-Clock-V3D-down-when-not-in-use.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0271-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0274-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0272-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0275-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0273-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0276-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0274-drm-vc4-Add-support-for-margins-to-fkms.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0277-drm-vc4-Add-support-for-margins-to-fkms.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0275-drm-vc4-Ensure-zpos-is-always-initialised.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0278-drm-vc4-Ensure-zpos-is-always-initialised.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0276-adds-the-Hifiberry-DAC-ADC-PRO-version.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0279-adds-the-Hifiberry-DAC-ADC-PRO-version.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0277-drm-vc4-A-present-but-empty-dmas-disables-audio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0280-drm-vc4-A-present-but-empty-dmas-disables-audio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0278-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0281-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0279-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0282-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0280-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0283-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0281-drm-vc4-Add-Broadcast-RGB-connector-property.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0284-drm-vc4-Add-Broadcast-RGB-connector-property.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0282-drm-vc4-fkms-Set-default-state-margin-at-reset.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0285-drm-vc4-fkms-Set-default-state-margin-at-reset.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0283-staging-bcm2835-codec-switch-to-multi-planar-API.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0286-staging-bcm2835-codec-switch-to-multi-planar-API.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0284-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0287-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0285-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0288-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0286-Add-HDMI1-facility-to-the-driver.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0289-Add-HDMI1-facility-to-the-driver.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0287-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0290-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0288-drm-vc4-Remove-unused-mode-variable.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0291-drm-vc4-Remove-unused-mode-variable.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0289-staging-bcm2835-codec-Expand-logging-on-format-setti.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0292-staging-bcm2835-codec-Expand-logging-on-format-setti.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0290-staging-bcm2835-codec-Correct-bytesperline-on-format.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0293-staging-bcm2835-codec-Correct-bytesperline-on-format.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0291-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0294-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0292-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0295-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0293-xhci-Use-more-event-ring-segment-table-entries.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0296-xhci-Use-more-event-ring-segment-table-entries.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0294-configs-arm64-bcm2711-Enable-V3D.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0297-configs-arm64-bcm2711-Enable-V3D.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0295-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0298-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0296-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0299-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0297-arch-arm-Add-model-string-to-cpuinfo.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0300-arch-arm-Add-model-string-to-cpuinfo.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0298-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0301-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0299-staging-bcm2835-codec-Fix-non-documentation-comment-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0302-staging-bcm2835-codec-Fix-non-documentation-comment-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0300-staging-bcm2835-codec-Fix-declaration-of-roles.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0303-staging-bcm2835-codec-Fix-declaration-of-roles.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0301-staging-bcm2835-codec-Add-role-to-device-name.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0304-staging-bcm2835-codec-Add-role-to-device-name.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0302-staging-bcm2835-codec-Pass-driver-context-to-create-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0305-staging-bcm2835-codec-Pass-driver-context-to-create-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0303-staging-bcm2835-codec-add-media-controller-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0306-staging-bcm2835-codec-add-media-controller-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0304-v4l2-Add-a-Greyworld-AWB-mode.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0307-v4l2-Add-a-Greyworld-AWB-mode.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0305-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0308-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0306-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0309-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0307-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0310-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0308-staging-bcm2835-codec-Allow-height-of-1920.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0311-staging-bcm2835-codec-Allow-height-of-1920.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0309-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0312-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0310-drm-v3d-Delete-pm_runtime-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0313-drm-v3d-Delete-pm_runtime-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0311-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0314-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0312-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0315-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0313-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0316-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0314-dma-direct-Temporary-DMA-fix-on-arm64.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0317-dma-direct-Temporary-DMA-fix-on-arm64.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0315-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0318-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0316-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0319-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0317-vchiq_2835_arm-suppress-warning.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0320-vchiq_2835_arm-suppress-warning.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0318-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0321-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0319-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0322-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0320-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0323-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0321-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0324-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0322-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0325-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0323-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0326-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0324-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0327-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0325-staging-bcm2835-codec-Set-default-and-error-check-ti.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0328-staging-bcm2835-codec-Set-default-and-error-check-ti.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0326-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0329-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0327-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0330-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0328-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0331-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0329-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0332-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0330-drm-v3d-Suppress-all-but-the-first-MMU-error.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0333-drm-v3d-Suppress-all-but-the-first-MMU-error.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0331-drm-v3d-Plug-dma_fence-leak.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0334-drm-v3d-Plug-dma_fence-leak.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0332-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0335-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0333-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0336-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0334-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0337-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0335-net-bcmgenet-The-second-IRQ-is-optional.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0339-net-bcmgenet-The-second-IRQ-is-optional.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0336-drm-v3d-The-third-IRQ-is-optional.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0340-drm-v3d-The-third-IRQ-is-optional.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0337-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0341-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0338-rpi-poe-fan-fix-def_pwm1-writes.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0342-rpi-poe-fan-fix-def_pwm1-writes.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0339-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0343-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0340-overlays-smi-fix-typo-in-comment-3320.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0344-overlays-smi-fix-typo-in-comment-3320.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0341-net-phy-2711-Change-the-default-ethernet-LED-actions.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0345-net-phy-2711-Change-the-default-ethernet-LED-actions.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0342-overlays-Add-apds9960-overlay.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0346-overlays-Add-apds9960-overlay.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0343-overlays-Remove-hack-from-uart0-overlay.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0347-overlays-Remove-hack-from-uart0-overlay.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0344-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0348-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0345-v3d_drv-Handle-missing-clock-more-gracefully.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0349-v3d_drv-Handle-missing-clock-more-gracefully.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0346-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0350-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0347-clk-bcm2835-Disable-v3d-clock.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0351-clk-bcm2835-Disable-v3d-clock.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0348-arm-dts-Correct-Pi-4B-LED-values.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0353-arm-dts-Correct-Pi-4B-LED-values.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0349-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0354-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0350-arm-dts-2711-Add-pcie0-alias.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0355-arm-dts-2711-Add-pcie0-alias.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0351-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0356-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0352-raspberrypi-cpufreq-Only-report-integer-pll-divisor-.patch40
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0352-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0357-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0353-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0358-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0354-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0359-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0355-overlays-Make-mcp342x-run-time-compatible.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0360-overlays-Make-mcp342x-run-time-compatible.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0356-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0361-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0357-sound-soc-only-first-codec-is-master-in-multicodec-s.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0362-sound-soc-only-first-codec-is-master-in-multicodec-s.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0358-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0363-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0359-overlays-dht11-Allow-multiple-instantiation.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0364-overlays-dht11-Allow-multiple-instantiation.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0360-overlays-i2c-rtc-Add-pcf85363-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0365-overlays-i2c-rtc-Add-pcf85363-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0361-pinctrl-bcm2835-Remove-gpiochip-on-error.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0366-pinctrl-bcm2835-Remove-gpiochip-on-error.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0362-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0367-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0363-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0368-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0364-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0369-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0365-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0370-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0366-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0371-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0367-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0372-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0368-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0373-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0369-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0374-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0370-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0375-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0371-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0376-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0372-net-bcmgenet-Add-RGMII_RXID-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0377-net-bcmgenet-Add-RGMII_RXID-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0373-ARM-dts-bcm2838-Backport-genet-from-upstream.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0378-ARM-dts-bcm2838-Backport-genet-from-upstream.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0374-ARM-bcm-Backport-BCM2711-support-from-upstream.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0379-ARM-bcm-Backport-BCM2711-support-from-upstream.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0375-hwrng-iproc-rng200-Add-support-for-BCM2711.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0380-hwrng-iproc-rng200-Add-support-for-BCM2711.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0376-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0381-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0377-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0382-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0378-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0383-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0379-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0384-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0380-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0385-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0381-driver-char-rpimem-Add-SPDX-licence-header.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0386-driver-char-rpimem-Add-SPDX-licence-header.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0382-driver-char-rpivid-Fix-access-to-freed-memory.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0387-driver-char-rpivid-Fix-access-to-freed-memory.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0383-add-BME680-to-i2c-sensor-overlay.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0388-add-BME680-to-i2c-sensor-overlay.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0384-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0389-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0385-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0390-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0386-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0391-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0387-Add-universal-device-tree-overlay-for-SPI-devices.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0392-Add-universal-device-tree-overlay-for-SPI-devices.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0388-sound-Add-the-HiFiBerry-DAC-HD-version.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0393-sound-Add-the-HiFiBerry-DAC-HD-version.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0389-Initialise-rpi-firmware-before-clk-bcm2835.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0394-Initialise-rpi-firmware-before-clk-bcm2835.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0390-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0395-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0391-overlays-Use-preferred-compatible-strings.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0396-overlays-Use-preferred-compatible-strings.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0392-tty-amba-pl011-Add-un-throttle-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0397-tty-amba-pl011-Add-un-throttle-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0393-Fix-i2c-pwm-pca9685a-overlay.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0398-Fix-i2c-pwm-pca9685a-overlay.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0394-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0399-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0395-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0400-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0396-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0401-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0397-pisound-Added-reading-Pisound-board-hardware-revisio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0402-pisound-Added-reading-Pisound-board-hardware-revisio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0398-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0403-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0399-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0404-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0400-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0405-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0401-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0406-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0402-tty-amba-pl011-Avoid-rare-write-when-full-error.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0407-tty-amba-pl011-Avoid-rare-write-when-full-error.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0403-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0408-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0404-overlays-Correct-the-eth_led-colour-assignments.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0409-overlays-Correct-the-eth_led-colour-assignments.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0405-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0410-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0406-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0411-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0407-overlays-dwc2-Increase-RX-FIFO-size.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0412-overlays-dwc2-Increase-RX-FIFO-size.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0408-overlays-Fix-mcp23017-s-addr-parameter.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0413-overlays-Fix-mcp23017-s-addr-parameter.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0409-SQUASH-Fix-spi-driver-compiler-warnings.patch22
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0410-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0415-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0411-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0416-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0412-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0417-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0413-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0418-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0414-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0419-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0414-SQUASH-Fix-spi-driver-compiler-warnings.patch22
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0415-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0416-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0421-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0417-ARM-dts-Rebuild-downstream-DTS-files.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0422-ARM-dts-Rebuild-downstream-DTS-files.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0418-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0423-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0419-hwrng-iproc-rng200-Correct-SoC-name.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0424-hwrng-iproc-rng200-Correct-SoC-name.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-Correct-SoC-name.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0425-ARM-dts-Correct-SoC-name.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0421-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0426-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0422-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0427-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0423-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0429-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0424-ARM-dts-overlays-Create-custom-clocks-in.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0430-ARM-dts-overlays-Create-custom-clocks-in.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0425-staging-vc04_services-Fix-vcsm-overflow-bug-when-cou.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0431-staging-vc04_services-Fix-vcsm-overflow-bug-when-cou.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0426-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0432-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0427-of-overlay-Correct-symbol-path-fixups.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0433-of-overlay-Correct-symbol-path-fixups.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0428-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0434-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0429-of-address-Introduce-of_get_next_dma_parent-helper.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0435-of-address-Introduce-of_get_next_dma_parent-helper.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0430-of-address-Follow-DMA-parent-for-dma-coherent.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0436-of-address-Follow-DMA-parent-for-dma-coherent.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0431-of-Factor-out-addr-size-cells-parsing.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0437-of-Factor-out-addr-size-cells-parsing.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0432-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0438-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0433-of-Make-of_dma_get_range-work-on-bus-nodes.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0439-of-Make-of_dma_get_range-work-on-bus-nodes.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0434-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0440-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0435-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0441-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0436-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0442-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0437-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0443-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0438-resource-Add-a-resource_list_first_type-helper.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0444-resource-Add-a-resource_list_first_type-helper.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0439-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0445-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0440-x86-PCI-sta2x11-use-default-DMA-address-translation.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0446-x86-PCI-sta2x11-use-default-DMA-address-translation.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0441-PCI-of-Add-inbound-resource-parsing-to-helpers.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0447-PCI-of-Add-inbound-resource-parsing-to-helpers.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0442-dma-direct-unify-the-dma_capable-definitions.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0448-dma-direct-unify-the-dma_capable-definitions.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0443-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0449-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0444-dma-direct-exclude-dma_direct_map_resource-from-the-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0450-dma-direct-exclude-dma_direct_map_resource-from-the-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0445-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0451-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0446-ARM-dts-bcm2711-Enable-PCIe-controller.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0452-ARM-dts-bcm2711-Enable-PCIe-controller.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0447-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0453-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0448-PCI-brcmstb-Add-MSI-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0454-PCI-brcmstb-Add-MSI-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0449-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0455-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0450-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0456-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0451-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0457-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0452-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0458-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0453-overlays-imx219-Correct-link-frequency-to-match-the-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0459-overlays-imx219-Correct-link-frequency-to-match-the-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0454-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0460-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0455-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0461-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0456-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0462-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0457-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0463-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0458-media-ov5647-Add-extra-10-bit-sensor-modes.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0464-media-ov5647-Add-extra-10-bit-sensor-modes.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0459-media-ov5647-change-defaults-to-better-match-raw-cam.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0465-media-ov5647-change-defaults-to-better-match-raw-cam.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0460-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0466-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0461-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0467-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0462-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0468-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0463-gpio-ir-overlay-add-parameter-to-configure-signal-po.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0469-gpio-ir-overlay-add-parameter-to-configure-signal-po.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0464-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0470-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0465-ARM-dts-bcm2711-Add-32-bit-PMU-compatibility.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0471-ARM-dts-bcm2711-Add-32-bit-PMU-compatibility.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0466-ARM-dts-bcm271x-Use-a53-pmu-drop-RPI364.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0472-ARM-dts-bcm271x-Use-a53-pmu-drop-RPI364.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0467-net-bcmgenet-Clear-ID_MODE_DIS-in-EXT_RGMII_OOB_CTRL.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0473-net-bcmgenet-Clear-ID_MODE_DIS-in-EXT_RGMII_OOB_CTRL.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0468-drm-modes-parse_cmdline-Fix-possible-reference-past-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0474-drm-modes-parse_cmdline-Fix-possible-reference-past-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0469-drm-modes-parse_cmdline-Make-various-char-pointers-c.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0475-drm-modes-parse_cmdline-Make-various-char-pointers-c.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0470-drm-modes-parse_cmdline-Stop-parsing-extras-after-bp.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0476-drm-modes-parse_cmdline-Stop-parsing-extras-after-bp.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0471-drm-modes-parse_cmdline-Accept-extras-directly-after.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0477-drm-modes-parse_cmdline-Accept-extras-directly-after.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0472-drm-modes-parse_cmdline-Rework-drm_mode_parse_cmdlin.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0478-drm-modes-parse_cmdline-Rework-drm_mode_parse_cmdlin.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0473-drm-modes-parse_cmdline-Add-freestanding-argument-to.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0479-drm-modes-parse_cmdline-Add-freestanding-argument-to.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0474-drm-modes-parse_cmdline-Set-bpp-refresh_specified-af.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0480-drm-modes-parse_cmdline-Set-bpp-refresh_specified-af.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0475-drm-modes-parse_cmdline-Allow-specifying-stand-alone.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0481-drm-modes-parse_cmdline-Allow-specifying-stand-alone.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0476-drm-modes-parse_cmdline-Add-support-for-specifying-p.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0482-drm-modes-parse_cmdline-Add-support-for-specifying-p.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0477-drm-modes-parse_cmdline-Remove-some-unnecessary-code.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0483-drm-modes-parse_cmdline-Remove-some-unnecessary-code.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0478-drm-modes-parse_cmdline-Explicitly-memset-the-passed.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0484-drm-modes-parse_cmdline-Explicitly-memset-the-passed.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0479-drm-v3d-Replace-wait_for-macros-to-remove-use-of-msl.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0485-drm-v3d-Replace-wait_for-macros-to-remove-use-of-msl.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0480-Reduce-noise-from-rpi-poe-hat-fan.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0486-Reduce-noise-from-rpi-poe-hat-fan.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0481-add-Sensirion-SPS30-to-i2c-sensor-overlay.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0487-add-Sensirion-SPS30-to-i2c-sensor-overlay.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0482-media-add-V4L2_CTRL_TYPE_AREA-control-type.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0488-media-add-V4L2_CTRL_TYPE_AREA-control-type.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0483-media-add-V4L2_CID_UNIT_CELL_SIZE-control.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0489-media-add-V4L2_CID_UNIT_CELL_SIZE-control.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0484-media-v4l2-common-add-pixel-encoding-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0490-media-v4l2-common-add-pixel-encoding-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0485-media-v4l2-common-add-RGB565-and-RGB55-to-v4l2_forma.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0491-media-v4l2-common-add-RGB565-and-RGB55-to-v4l2_forma.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0486-media-vb2-add-V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0492-media-vb2-add-V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0487-media-v4l2-mem2mem-support-held-capture-buffers.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0493-media-v4l2-mem2mem-support-held-capture-buffers.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0488-media-videodev2.h-add-V4L2_DEC_CMD_FLUSH.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0494-media-videodev2.h-add-V4L2_DEC_CMD_FLUSH.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0489-media-v4l2-mem2mem-add-stateless_-try_-decoder_cmd-i.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0495-media-v4l2-mem2mem-add-stateless_-try_-decoder_cmd-i.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0490-media-v4l2-mem2mem-add-new_frame-detection.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0496-media-v4l2-mem2mem-add-new_frame-detection.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0491-media-Documentation-media-Document-V4L2_CTRL_TYPE_AR.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0497-media-Documentation-media-Document-V4L2_CTRL_TYPE_AR.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0492-media-v4l-Add-definitions-for-HEVC-stateless-decodin.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0498-media-v4l-Add-definitions-for-HEVC-stateless-decodin.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0493-media-v4l2-mem2mem-Fix-hold-buf-flag-checks.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0499-media-v4l2-mem2mem-Fix-hold-buf-flag-checks.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0494-media-pixfmt-Document-the-HEVC-slice-pixel-format.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0500-media-pixfmt-Document-the-HEVC-slice-pixel-format.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0495-media-uapi-hevc-Add-scaling-matrix-control.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0501-media-uapi-hevc-Add-scaling-matrix-control.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0496-media-uapi-hevc-Add-segment-address-field.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0502-media-uapi-hevc-Add-segment-address-field.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0497-media-hevc_ctrls-Add-slice-param-dependent-slice-seg.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0503-media-hevc_ctrls-Add-slice-param-dependent-slice-seg.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0498-media-uapi-Add-hevc-ctrls-for-WPP-decoding.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0504-media-uapi-Add-hevc-ctrls-for-WPP-decoding.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0499-media-videodev2.h-Add-a-format-for-column-YUV4-2-0-m.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0505-media-videodev2.h-Add-a-format-for-column-YUV4-2-0-m.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0500-media-v4l2-mem2mem-allow-request-job-buffer-processi.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0506-media-v4l2-mem2mem-allow-request-job-buffer-processi.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0501-media-dt-bindings-media-Add-binding-for-the-Raspberr.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0507-media-dt-bindings-media-Add-binding-for-the-Raspberr.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0502-staging-media-Add-Raspberry-Pi-V4L2-H265-decoder.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0508-staging-media-Add-Raspberry-Pi-V4L2-H265-decoder.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0503-dtoverlays-Add-overlay-to-enable-the-HEVC-V4L2-drive.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0509-dtoverlays-Add-overlay-to-enable-the-HEVC-V4L2-drive.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0504-mmc-sdhci-Silence-MMC-warnings.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0510-mmc-sdhci-Silence-MMC-warnings.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0505-dt-bindings-i2c-brcmstb-Convert-the-BRCMSTB-binding-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0511-dt-bindings-i2c-brcmstb-Convert-the-BRCMSTB-binding-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0506-dt-bindings-i2c-brcmstb-Add-BCM2711-BSC-AUTO-I2C-bin.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0512-dt-bindings-i2c-brcmstb-Add-BCM2711-BSC-AUTO-I2C-bin.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0507-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0513-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0508-i2c-brcmstb-Allow-to-compile-it-on-BCM2835.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0514-i2c-brcmstb-Allow-to-compile-it-on-BCM2835.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0509-dt-bindings-clock-Add-a-binding-for-the-RPi-Firmware.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0515-dt-bindings-clock-Add-a-binding-for-the-RPi-Firmware.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0510-clk-bcm-rpi-Allow-the-driver-to-be-probed-by-DT.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0516-clk-bcm-rpi-Allow-the-driver-to-be-probed-by-DT.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0511-clk-bcm-rpi-Statically-init-clk_init_data.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0517-clk-bcm-rpi-Statically-init-clk_init_data.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0512-clk-bcm-rpi-Use-clk_hw_register-for-pllb_arm.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0518-clk-bcm-rpi-Use-clk_hw_register-for-pllb_arm.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0513-clk-bcm-rpi-Remove-global-pllb_arm-clock-pointer.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0519-clk-bcm-rpi-Remove-global-pllb_arm-clock-pointer.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0514-clk-bcm-rpi-Make-sure-pllb_arm-is-removed.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0520-clk-bcm-rpi-Make-sure-pllb_arm-is-removed.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0515-clk-bcm-rpi-Remove-pllb_arm_lookup-global-pointer.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0521-clk-bcm-rpi-Remove-pllb_arm_lookup-global-pointer.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0516-clk-bcm-rpi-Switch-to-clk_hw_register_clkdev.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0522-clk-bcm-rpi-Switch-to-clk_hw_register_clkdev.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0517-clk-bcm-rpi-Make-sure-the-clkdev-lookup-is-removed.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0523-clk-bcm-rpi-Make-sure-the-clkdev-lookup-is-removed.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0518-clk-bcm-rpi-Create-a-data-structure-for-the-clocks.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0524-clk-bcm-rpi-Create-a-data-structure-for-the-clocks.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0519-clk-bcm-rpi-Add-clock-id-to-data.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0525-clk-bcm-rpi-Add-clock-id-to-data.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0520-clk-bcm-rpi-Pass-the-clocks-data-to-the-firmware-fun.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0526-clk-bcm-rpi-Pass-the-clocks-data-to-the-firmware-fun.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0521-clk-bcm-rpi-Rename-is_prepared-function.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0527-clk-bcm-rpi-Rename-is_prepared-function.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0522-clk-bcm-rpi-Split-pllb-clock-hooks.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0528-clk-bcm-rpi-Split-pllb-clock-hooks.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0523-clk-bcm-rpi-Make-the-PLLB-registration-function-retu.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0529-clk-bcm-rpi-Make-the-PLLB-registration-function-retu.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0524-clk-bcm-rpi-Add-DT-provider-for-the-clocks.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0530-clk-bcm-rpi-Add-DT-provider-for-the-clocks.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0525-clk-bcm-rpi-Discover-the-firmware-clocks.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0531-clk-bcm-rpi-Discover-the-firmware-clocks.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0526-ARM-dts-bcm2711-Add-firmware-clocks-node.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0532-ARM-dts-bcm2711-Add-firmware-clocks-node.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0527-reset-Move-reset-simple-header-out-of-drivers-reset.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0533-reset-Move-reset-simple-header-out-of-drivers-reset.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0528-reset-simple-Add-reset-callback.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0534-reset-simple-Add-reset-callback.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0529-dt-bindings-clock-Add-BCM2711-DVP-binding.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0535-dt-bindings-clock-Add-BCM2711-DVP-binding.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0530-clk-bcm-Add-BCM2711-DVP-driver.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0536-clk-bcm-Add-BCM2711-DVP-driver.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0531-ARM-dts-bcm2711-Add-HDMI-DVP.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0537-ARM-dts-bcm2711-Add-HDMI-DVP.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0532-dt-bindings-display-Convert-VC4-bindings-to-schemas.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0538-dt-bindings-display-Convert-VC4-bindings-to-schemas.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0533-dt-bindings-display-vc4-dpi-Add-missing-clock-names-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0539-dt-bindings-display-vc4-dpi-Add-missing-clock-names-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0534-dt-bindings-display-vc4-dsi-Add-missing-clock-proper.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0540-dt-bindings-display-vc4-dsi-Add-missing-clock-proper.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0535-dt-bindings-display-vc4-hdmi-Add-missing-clock-names.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0541-dt-bindings-display-vc4-hdmi-Add-missing-clock-names.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0536-dt-bindings-display-vc4-Document-BCM2711-VC5.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0542-dt-bindings-display-vc4-Document-BCM2711-VC5.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0537-drm-vc4-drv-Add-include-guards.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0543-drm-vc4-drv-Add-include-guards.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0538-drm-vc4-drv-Support-BCM2711.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0544-drm-vc4-drv-Support-BCM2711.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0539-drm-vc4-drv-Add-support-for-the-BCM2711-HVS5.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0545-drm-vc4-drv-Add-support-for-the-BCM2711-HVS5.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0540-drm-vc4-plane-Improve-LBM-usage.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0546-drm-vc4-plane-Improve-LBM-usage.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0541-drm-vc4-plane-Move-planes-creation-to-its-own-functi.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0547-drm-vc4-plane-Move-planes-creation-to-its-own-functi.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0542-drm-vc4-plane-Move-additional-planes-creation-to-dri.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0548-drm-vc4-plane-Move-additional-planes-creation-to-dri.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0543-drm-vc4-plane-Register-all-the-planes-at-once.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0549-drm-vc4-plane-Register-all-the-planes-at-once.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0544-drm-vc4-plane-Create-overlays-for-any-CRTC.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0550-drm-vc4-plane-Create-overlays-for-any-CRTC.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0545-drm-vc4-plane-Create-more-planes.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0551-drm-vc4-plane-Create-more-planes.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0546-drm-vc4-crtc-Rename-SoC-data-structures.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0552-drm-vc4-crtc-Rename-SoC-data-structures.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0547-drm-vc4-crtc-Move-crtc-state-to-common-header.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0553-drm-vc4-crtc-Move-crtc-state-to-common-header.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0548-drm-vc4-crtc-Deal-with-different-number-of-pixel-per.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0554-drm-vc4-crtc-Deal-with-different-number-of-pixel-per.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0549-drm-vc4-crtc-Use-a-shared-interrupt.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0555-drm-vc4-crtc-Use-a-shared-interrupt.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0550-drm-vc4-crtc-Turn-static-const-variable-into-a-defin.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0556-drm-vc4-crtc-Turn-static-const-variable-into-a-defin.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0551-drm-vc4-crtc-Move-the-cob-allocation-outside-of-bind.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0557-drm-vc4-crtc-Move-the-cob-allocation-outside-of-bind.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0552-drm-vc4-crtc-Rename-HVS-channel-to-output.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0558-drm-vc4-crtc-Rename-HVS-channel-to-output.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0553-drm-vc4-crtc-Use-local-chan-variable.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0559-drm-vc4-crtc-Use-local-chan-variable.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0554-drm-vc4-crtc-Enable-and-disable-the-PV-in-atomic_ena.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0560-drm-vc4-crtc-Enable-and-disable-the-PV-in-atomic_ena.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0555-drm-vc4-crtc-Assign-output-to-channel-automatically.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0561-drm-vc4-crtc-Assign-output-to-channel-automatically.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0556-drm-vc4-crtc-Add-FIFO-depth-to-vc4_crtc_data.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0562-drm-vc4-crtc-Add-FIFO-depth-to-vc4_crtc_data.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0557-drm-vc4-crtc-Add-function-to-compute-FIFO-level-bits.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0563-drm-vc4-crtc-Add-function-to-compute-FIFO-level-bits.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0558-drm-vc4-crtc-Rename-HDMI-encoder-type-to-HDMI0.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0564-drm-vc4-crtc-Rename-HDMI-encoder-type-to-HDMI0.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0559-drm-vc4-crtc-Add-HDMI1-encoder-type.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0565-drm-vc4-crtc-Add-HDMI1-encoder-type.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0560-drm-vc4-crtc-Remove-redundant-call-to-drm_crtc_enabl.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-crtc-Remove-redundant-call-to-drm_crtc_enabl.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0561-drm-vc4-crtc-Disable-color-management-for-HVS5.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0567-drm-vc4-crtc-Disable-color-management-for-HVS5.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0562-dt-bindings-display-vc4-pv-Add-BCM2711-pixel-valves.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0568-dt-bindings-display-vc4-pv-Add-BCM2711-pixel-valves.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0563-drm-vc4-crtc-Add-BCM2711-pixelvalves.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0569-drm-vc4-crtc-Add-BCM2711-pixelvalves.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0564-drm-vc4-hdmi-Use-debugfs-private-field.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0570-drm-vc4-hdmi-Use-debugfs-private-field.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0565-drm-vc4-hdmi-Move-structure-to-header.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0571-drm-vc4-hdmi-Move-structure-to-header.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-hdmi-rework-connectors-and-encoders.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0572-drm-vc4-hdmi-rework-connectors-and-encoders.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0567-drm-vc4-hdmi-Rename-hdmi-to-vc4_hdmi.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0573-drm-vc4-hdmi-Rename-hdmi-to-vc4_hdmi.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0568-drm-vc4-hdmi-Move-accessors-to-vc4_hdmi.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0574-drm-vc4-hdmi-Move-accessors-to-vc4_hdmi.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0569-drm-vc4-hdmi-Use-local-vc4_hdmi-directly.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0575-drm-vc4-hdmi-Use-local-vc4_hdmi-directly.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0570-drm-vc4-hdmi-Add-container_of-macros-for-encoders-an.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0576-drm-vc4-hdmi-Add-container_of-macros-for-encoders-an.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0571-drm-vc4-hdmi-Pass-vc4_hdmi-to-CEC-code.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0577-drm-vc4-hdmi-Pass-vc4_hdmi-to-CEC-code.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0572-drm-vc4-hdmi-Remove-vc4_dev-hdmi-pointer.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0578-drm-vc4-hdmi-Remove-vc4_dev-hdmi-pointer.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0573-drm-vc4-hdmi-Remove-vc4_hdmi_connector.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Remove-vc4_hdmi_connector.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0574-drm-vc4-hdmi-Introduce-resource-init-and-variant.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0580-drm-vc4-hdmi-Introduce-resource-init-and-variant.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0575-drm-vc4-hdmi-Implement-a-register-layout-abstraction.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0581-drm-vc4-hdmi-Implement-a-register-layout-abstraction.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0576-drm-vc4-hdmi-Add-reset-callback.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0582-drm-vc4-hdmi-Add-reset-callback.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0577-drm-vc4-hdmi-Add-PHY-init-and-disable-function.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0583-drm-vc4-hdmi-Add-PHY-init-and-disable-function.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0578-drm-vc4-hdmi-Add-PHY-RNG-enable-disable-function.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0584-drm-vc4-hdmi-Add-PHY-RNG-enable-disable-function.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0585-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0580-drm-vc4-hdmi-Add-a-set_timings-callback.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0586-drm-vc4-hdmi-Add-a-set_timings-callback.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0581-drm-vc4-hdmi-Add-HDMI-ID.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0587-drm-vc4-hdmi-Add-HDMI-ID.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0582-drm-vc4-hdmi-Deal-with-multiple-debugfs-files.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0588-drm-vc4-hdmi-Deal-with-multiple-debugfs-files.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0583-drm-vc4-hdmi-Add-an-audio-support-flag.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0589-drm-vc4-hdmi-Add-an-audio-support-flag.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0584-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0590-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0585-drm-vc4-hdmi-Add-CEC-support-flag.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0591-drm-vc4-hdmi-Add-CEC-support-flag.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0586-drm-vc4-hdmi-Remove-unused-CEC_CLOCK_DIV-define.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0592-drm-vc4-hdmi-Remove-unused-CEC_CLOCK_DIV-define.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0587-drm-vc4-hdmi-Rename-drm_encoder-pointer-in-mode_vali.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0593-drm-vc4-hdmi-Rename-drm_encoder-pointer-in-mode_vali.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0588-drm-vc4-hdmi-Adjust-HSM-clock-rate-depending-on-pixe.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0594-drm-vc4-hdmi-Adjust-HSM-clock-rate-depending-on-pixe.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0589-drm-vc4-hdmi-Support-the-BCM2711-HDMI-controllers.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-hdmi-Support-the-BCM2711-HDMI-controllers.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0590-dt-bindings-display-vc4-hdmi-Add-BCM2711-HDMI-contro.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0596-dt-bindings-display-vc4-hdmi-Add-BCM2711-HDMI-contro.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0591-ARM-dts-bcm2711-Enable-the-display-pipeline.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0597-ARM-dts-bcm2711-Enable-the-display-pipeline.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0592-DOWNSTREAM-ARM-dts-rpi4-Disable-KMS-driver-by-defaul.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0598-DOWNSTREAM-ARM-dts-rpi4-Disable-KMS-driver-by-defaul.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0593-dtoverlays-Add-Pi4-version-of-vc4-kms-v3d.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0599-dtoverlays-Add-Pi4-version-of-vc4-kms-v3d.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0594-drm-Checking-of-the-pitch-is-only-valid-for-linear-f.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0600-drm-Checking-of-the-pitch-is-only-valid-for-linear-f.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0601-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0596-Fixup-P030-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0602-Fixup-P030-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0597-drm-vc4-The-check-for-assigned-HVS-channels-is-not-a.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-The-check-for-assigned-HVS-channels-is-not-a.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0598-dt-Update-v3d-to-use-firmware_clocks.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0604-dt-Update-v3d-to-use-firmware_clocks.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0599-drm-vc4-Reset-audio-infoframe-on-encoder_enable-if-p.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0605-drm-vc4-Reset-audio-infoframe-on-encoder_enable-if-p.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0600-drm-vc4-Set-the-b-frame-marker-to-the-match-ALSA-s-d.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0606-drm-vc4-Set-the-b-frame-marker-to-the-match-ALSA-s-d.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0601-dts-Add-reg-names-for-the-HDMI-registers-on-bcm2835.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0607-dts-Add-reg-names-for-the-HDMI-registers-on-bcm2835.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0602-dt-Add-HDMI-audio-dma-values-to-bcm2711.dtsi.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0608-dt-Add-HDMI-audio-dma-values-to-bcm2711.dtsi.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-Use-reg-names-to-configure-HDMI-audio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0609-drm-vc4-Use-reg-names-to-configure-HDMI-audio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0604-drm-vc4-Add-audio-initialisation-for-Pi4.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0610-drm-vc4-Add-audio-initialisation-for-Pi4.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0605-drm-vc4-Enable-audio-on-Pi4.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0611-drm-vc4-Enable-audio-on-Pi4.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0606-drm-vc4-Alter-the-HDMI-state-machine-clock-calc-to-a.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0612-drm-vc4-Alter-the-HDMI-state-machine-clock-calc-to-a.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0607-dtoverlays-Remove-comment-about-vc4-kms-v3d-locking-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0613-dtoverlays-Remove-comment-about-vc4-kms-v3d-locking-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0608-drm-vc4-Kick-the-core-clock-up-during-a-mode-change.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0614-drm-vc4-Kick-the-core-clock-up-during-a-mode-change.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0609-drm-vc4-Fixup-for-firmware-KMS.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0615-drm-vc4-Fixup-for-firmware-KMS.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0610-drm-vc4-Fixup-plane-init-within-firmware-kms.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0616-drm-vc4-Fixup-plane-init-within-firmware-kms.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0611-drm-vc4-hdmi-Give-the-HDMI-audio-instances-different.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0617-drm-vc4-hdmi-Give-the-HDMI-audio-instances-different.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0612-i2c-brcmstb-The-interrupt-line-is-optional-so-use-pl.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0618-i2c-brcmstb-The-interrupt-line-is-optional-so-use-pl.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0613-dt-Drop-I2C-for-Pi4-HDMI-interfaces-to-97.5kHz.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0619-dt-Drop-I2C-for-Pi4-HDMI-interfaces-to-97.5kHz.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0614-overlays-Add-missing-rpi-poe-parameters.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0620-overlays-Add-missing-rpi-poe-parameters.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0615-vc4_hdmi_phy-Fix-offset-calculation.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0621-vc4_hdmi_phy-Fix-offset-calculation.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0616-overlays-Add-overlay_map.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0622-overlays-Add-overlay_map.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0617-overlays-Formally-rename-deprecate-old-overlays.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0623-overlays-Formally-rename-deprecate-old-overlays.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0618-overlays-Add-vc4-kms-v3d-pi4-to-overlay_map.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0624-overlays-Add-vc4-kms-v3d-pi4-to-overlay_map.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0619-Add-upstream-and-upstream-pi4-to-overlay_map.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0625-Add-upstream-and-upstream-pi4-to-overlay_map.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0620-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0626-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0621-Add-support-for-the-AudioInjector.net-Isolated-sound.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0627-Add-support-for-the-AudioInjector.net-Isolated-sound.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0622-overlays-Fix-dtc-warnings-in-i2c-gpio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0628-overlays-Fix-dtc-warnings-in-i2c-gpio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0623-kbuild-Disable-gcc-plugins.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0629-kbuild-Disable-gcc-plugins.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0624-ASoC-ma120x0p-Add-96KHz-rate-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0630-ASoC-ma120x0p-Add-96KHz-rate-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0625-arm64-mm-reserve-CMA-and-crashkernel-in-ZONE_DMA32.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0631-arm64-mm-reserve-CMA-and-crashkernel-in-ZONE_DMA32.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0626-arm64-mm-Fix-initialisation-of-DMA-zones-on-non-NUMA.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0632-arm64-mm-Fix-initialisation-of-DMA-zones-on-non-NUMA.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0627-ARM-dts-bcm283x-Unify-CMA-configuration.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0633-ARM-dts-bcm283x-Unify-CMA-configuration.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0628-dma-contiguous-CMA-give-precedence-to-cmdline.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0634-dma-contiguous-CMA-give-precedence-to-cmdline.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0629-ARM-dts-Use-upstream-CMA-configuration.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0635-ARM-dts-Use-upstream-CMA-configuration.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0630-ARM-dts-overlays-Unify-overlay-CMA-handling.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0636-ARM-dts-overlays-Unify-overlay-CMA-handling.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0631-ARM-dts-bcm283x-Fix-vc4-s-firmware-bus-DMA-limitatio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0637-ARM-dts-bcm283x-Fix-vc4-s-firmware-bus-DMA-limitatio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0632-ARM-dts-bcm2711-Restrict-CMA-to-first-768MB.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0638-ARM-dts-bcm2711-Restrict-CMA-to-first-768MB.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0633-ARM-dts-Extend-SCB-bus-address-range.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0639-ARM-dts-Extend-SCB-bus-address-range.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0634-dts-bcm2711-Move-emmc2-to-its-own-bus.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0640-dts-bcm2711-Move-emmc2-to-its-own-bus.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0635-drm-vc4-hdmi-Silence-pixel-clock-error-on-EPROBE_DEF.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0641-drm-vc4-hdmi-Silence-pixel-clock-error-on-EPROBE_DEF.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0636-Fixes-a-problem-with-clock-settings-of-HiFiBerry-DAC.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0643-Fixes-a-problem-with-clock-settings-of-HiFiBerry-DAC.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0637-Documentation-media-Update-sub-device-API-intro.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0644-Documentation-media-Update-sub-device-API-intro.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0638-Documentation-media-Document-read-only-subdevice.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0645-Documentation-media-Document-read-only-subdevice.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0639-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0646-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0640-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0647-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0641-media-uapi-v4l2-core-Add-sensor-ancillary-data-V4L2-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0648-media-uapi-v4l2-core-Add-sensor-ancillary-data-V4L2-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0642-media-uapi-Add-MEDIA_BUS_FMT_SENSOR_DATA-media-bus-f.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0649-media-uapi-Add-MEDIA_BUS_FMT_SENSOR_DATA-media-bus-f.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0643-media-bcm2835-unicam-Add-support-for-mulitple-device.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0650-media-bcm2835-unicam-Add-support-for-mulitple-device.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0644-media-bcm2835-unicam-Add-embedded-data-node.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0651-media-bcm2835-unicam-Add-embedded-data-node.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0645-media-bcm2835-unicam-Use-dummy-buffer-if-none-have-b.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0652-media-bcm2835-unicam-Use-dummy-buffer-if-none-have-b.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0646-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0653-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0647-media-i2c-imx219-Fix-power-sequence.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0654-media-i2c-imx219-Fix-power-sequence.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0648-media-i2c-imx219-Add-support-for-RAW8-bit-bayer-form.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0655-media-i2c-imx219-Add-support-for-RAW8-bit-bayer-form.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0649-media-i2c-imx219-Add-support-for-cropped-640x480-res.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0656-media-i2c-imx219-Add-support-for-cropped-640x480-res.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0650-media-i2c-imx219-Fix-a-bug-in-imx219_enum_frame_size.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0657-media-i2c-imx219-Fix-a-bug-in-imx219_enum_frame_size.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0651-media-bcm2835-unicam-Disable-event-related-ioctls-on.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0658-media-bcm2835-unicam-Disable-event-related-ioctls-on.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0652-media-bcm2835-unicam-Add-support-for-the-FRAME_SYNC-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0659-media-bcm2835-unicam-Add-support-for-the-FRAME_SYNC-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0653-Revert-firmware-raspberrypi-register-clk-device.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0660-Revert-firmware-raspberrypi-register-clk-device.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0654-media-imx219-Advertise-embedded-data-node-on-media-p.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0661-media-imx219-Advertise-embedded-data-node-on-media-p.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0655-dts-bcm2711-EMMC2-can-address-the-whole-first-GB.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0662-dts-bcm2711-EMMC2-can-address-the-whole-first-GB.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0656-driver-char-rpivid-Remove-legacy-name-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0663-driver-char-rpivid-Remove-legacy-name-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0657-driver-char-rpivid-Don-t-map-more-than-wanted.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0664-driver-char-rpivid-Don-t-map-more-than-wanted.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0658-dt-Implement-an-I2C-pinctrl-mux-for-BSC0.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0665-dt-Implement-an-I2C-pinctrl-mux-for-BSC0.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0659-dtoverlays-Update-CSI-overlays-to-use-i2c_csi_dsi.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0666-dtoverlays-Update-CSI-overlays-to-use-i2c_csi_dsi.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0660-dt-Update-all-mainline-bcm283x-dt-files-for-i2c0-pin.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0667-dt-Update-all-mainline-bcm283x-dt-files-for-i2c0-pin.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0661-ARM-dts-Create-bcm2708-rpi-b-rev1.dts.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0668-ARM-dts-Create-bcm2708-rpi-b-rev1.dts.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0662-dts-bcm2711-set-size-cells-2.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0669-dts-bcm2711-set-size-cells-2.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0663-dts-bcm2711-add-High-Peripheral-mode-overlay.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0670-dts-bcm2711-add-High-Peripheral-mode-overlay.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0664-Revert-spi-spidev-Fix-CS-polarity-if-GPIO-descriptor.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0671-Revert-spi-spidev-Fix-CS-polarity-if-GPIO-descriptor.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0665-spi-use_gpio_descriptor-fixup-moved-to-spi_setup.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0672-spi-use_gpio_descriptor-fixup-moved-to-spi_setup.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0666-overlays-rpivid-v4l2-also-needs-size-cells-2.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0673-overlays-rpivid-v4l2-also-needs-size-cells-2.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0667-media-bcm2835-unicam-Re-fetch-mbus-code-from-subdev-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0674-media-bcm2835-unicam-Re-fetch-mbus-code-from-subdev-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0668-uapi-bcm2835-isp-Add-bcm2835-isp-uapi-header-file.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0675-uapi-bcm2835-isp-Add-bcm2835-isp-uapi-header-file.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0669-media-uapi-v4l2-core-Add-ISP-statistics-output-V4L2-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0676-media-uapi-v4l2-core-Add-ISP-statistics-output-V4L2-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0670-media-uapi-v4l-ctrls-Add-CID-base-for-the-bcm2835-is.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0677-media-uapi-v4l-ctrls-Add-CID-base-for-the-bcm2835-is.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0671-staging-mmal-vchiq-Fix-formatting-errors-in-mmal_par.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0678-staging-mmal-vchiq-Fix-formatting-errors-in-mmal_par.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0672-staging-vc04_services-ISP-Add-a-more-complex-ISP-pro.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0679-staging-vc04_services-ISP-Add-a-more-complex-ISP-pro.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0673-staging-vchiq-Load-bcm2835_isp-driver-from-vchiq.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0680-staging-vchiq-Load-bcm2835_isp-driver-from-vchiq.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0674-vc4_hvs-Mark-core-clock-as-optional.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0681-vc4_hvs-Mark-core-clock-as-optional.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0675-vc4_hdmi-BCM2835-requires-a-fixed-hsm-clock-for-CEC-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0682-vc4_hdmi-BCM2835-requires-a-fixed-hsm-clock-for-CEC-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0676-media-i2c-imx219-Implement-get_selection.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0683-media-i2c-imx219-Implement-get_selection.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0677-media-i2c-ov5647-Add-support-for-g_selection-to-refl.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0684-media-i2c-ov5647-Add-support-for-g_selection-to-refl.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0678-media-i2c-ov5467-Fixup-error-path-to-release-mutex.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0685-media-i2c-ov5467-Fixup-error-path-to-release-mutex.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0679-media-i2c-ov5647-Support-V4L2_CID_PIXEL_RATE.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0686-media-i2c-ov5647-Support-V4L2_CID_PIXEL_RATE.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0680-media-i2c-ov5647-Set-V4L2_SUBDEV_FL_HAS_EVENTS-flag.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0687-media-i2c-ov5647-Set-V4L2_SUBDEV_FL_HAS_EVENTS-flag.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0681-media-i2c-ov5647-Add-support-for-V4L2_CID_VBLANK.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0688-media-i2c-ov5647-Add-support-for-V4L2_CID_VBLANK.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0682-media-i2c-ov5647-Neither-analogue-gain-nor-exposure-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0689-media-i2c-ov5647-Neither-analogue-gain-nor-exposure-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0683-media-i2c-ov5647-Use-member-names-in-mode-tables.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0690-media-i2c-ov5647-Use-member-names-in-mode-tables.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0684-media-i2c-ov5647-Advertise-the-correct-exposure-rang.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0691-media-i2c-ov5647-Advertise-the-correct-exposure-rang.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0685-media-i2c-imx219-Declare-that-the-driver-can-create-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0692-media-i2c-imx219-Declare-that-the-driver-can-create-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0686-media-bcm2835-unicam-Add-support-for-VIDIOC_-S-G-_SE.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0693-media-bcm2835-unicam-Add-support-for-VIDIOC_-S-G-_SE.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0687-media-bcm2835-unicam-Do-not-stop-streaming-in-unicam.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0694-media-bcm2835-unicam-Do-not-stop-streaming-in-unicam.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0688-media-bcm2835-unicam-Fix-reference-counting-in-unica.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0695-media-bcm2835-unicam-Fix-reference-counting-in-unica.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0689-staging-vc04_services-ISP-Add-enum_framesizes-ioctl.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0696-staging-vc04_services-ISP-Add-enum_framesizes-ioctl.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0690-SQUASH-spi-Demote-SPI_CS_HIGH-warning-to-KERN_DEBUG.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0697-SQUASH-spi-Demote-SPI_CS_HIGH-warning-to-KERN_DEBUG.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0691-bcm2835-dma-Add-proper-40-bit-DMA-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0698-bcm2835-dma-Add-proper-40-bit-DMA-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0692-ARM-dts-bcm2711-Allow-40-bit-DMA-for-SPI.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0699-ARM-dts-bcm2711-Allow-40-bit-DMA-for-SPI.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0693-overlays-Make-the-i2c-gpio-overlay-safe-again.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0700-overlays-Make-the-i2c-gpio-overlay-safe-again.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0694-staging-vc04_services-isp-Remove-duplicated-initiali.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0701-staging-vc04_services-isp-Remove-duplicated-initiali.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0695-staging-vc04_services-isp-Make-all-references-to-bcm.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0702-staging-vc04_services-isp-Make-all-references-to-bcm.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0696-vc4_hdmi_phy-Fix-typo-in-phy_get_cp_current.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0704-vc4_hdmi_phy-Fix-typo-in-phy_get_cp_current.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0697-overlays-Make-use-of-intra-overlay-fragments.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0705-overlays-Make-use-of-intra-overlay-fragments.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0698-media-i2c-tc358743-Fix-fallthrough-warning.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0706-media-i2c-tc358743-Fix-fallthrough-warning.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0699-media-bcm2835-unicam-Fix-uninitialized-warning.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0707-media-bcm2835-unicam-Fix-uninitialized-warning.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0700-video-bcm2708_fb-Disable-FB-if-no-displays-found.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0708-video-bcm2708_fb-Disable-FB-if-no-displays-found.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0701-overlays-sc16is752-spi1-Add-xtal-parameter.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0709-overlays-sc16is752-spi1-Add-xtal-parameter.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0702-vc4_hdmi-Fix-register-offset-when-sending-longer-CEC.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0710-vc4_hdmi-Fix-register-offset-when-sending-longer-CEC.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0703-overlays-gpio-keys-Avoid-open-drain-warnings.patch29
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0703-vc4_hdmi-Fix-up-CEC-registers.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0711-vc4_hdmi-Fix-up-CEC-registers.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0704-vc4_hdmi_regs-Add-Intr2-register-block.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0712-vc4_hdmi_regs-Add-Intr2-register-block.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0705-vc4_hdmi_regs-Make-interrupt-mask-variant-specific.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0713-vc4_hdmi_regs-Make-interrupt-mask-variant-specific.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0706-vc4_hdmi-Make-irq-shared.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0714-vc4_hdmi-Make-irq-shared.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0707-vc4_hdmi-Adjust-CEC-ref-clock-based-on-its-input-clo.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0715-vc4_hdmi-Adjust-CEC-ref-clock-based-on-its-input-clo.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0708-vc4_hdmi-Remove-cec_available-flag-as-always-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0716-vc4_hdmi-Remove-cec_available-flag-as-always-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0709-overlays-tc358743-Use-intra-overlay-fragments.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0717-overlays-tc358743-Use-intra-overlay-fragments.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0710-overlays-Move-fixed-clock-nodes-to-the-root.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0718-overlays-Move-fixed-clock-nodes-to-the-root.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0711-raspberrypi-dts-Switch-to-discrete-ALSA-devices.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0719-raspberrypi-dts-Switch-to-discrete-ALSA-devices.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0712-dt-bindings-media-i2c-Add-IMX477-CMOS-sensor-binding.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0720-dt-bindings-media-i2c-Add-IMX477-CMOS-sensor-binding.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0713-dtoverlays-Add-IMX477-sensor-overlay.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0721-dtoverlays-Add-IMX477-sensor-overlay.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0714-media-i2c-Add-driver-for-Sony-IMX477-sensor.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0722-media-i2c-Add-driver-for-Sony-IMX477-sensor.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0715-media-i2c-imx477-Add-support-for-adaptive-frame-cont.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0723-media-i2c-imx477-Add-support-for-adaptive-frame-cont.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0716-udmabuf-Remove-deleted-map-unmap-handlers.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0724-udmabuf-Remove-deleted-map-unmap-handlers.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0717-udmabuf-use-cache_sgt_mapping-option.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0725-udmabuf-use-cache_sgt_mapping-option.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0718-udmabuf-add-a-pointer-to-the-miscdevice-in-dma-buf-p.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0726-udmabuf-add-a-pointer-to-the-miscdevice-in-dma-buf-p.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0719-udmabuf-separate-out-creating-destroying-scatter-tab.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0727-udmabuf-separate-out-creating-destroying-scatter-tab.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0720-udmabuf-implement-begin_cpu_access-end_cpu_access-ho.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0728-udmabuf-implement-begin_cpu_access-end_cpu_access-ho.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0721-udmabuf-fix-dma-buf-cpu-access.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0729-udmabuf-fix-dma-buf-cpu-access.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0722-dma-buf-Add-dma-buf-heaps-framework.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0730-dma-buf-Add-dma-buf-heaps-framework.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0723-dma-buf-heaps-Add-heap-helpers.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0731-dma-buf-heaps-Add-heap-helpers.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0724-dma-buf-heaps-Add-system-heap-to-dmabuf-heaps.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0732-dma-buf-heaps-Add-system-heap-to-dmabuf-heaps.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0725-dma-buf-heaps-Add-CMA-heap-to-dmabuf-heaps.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0733-dma-buf-heaps-Add-CMA-heap-to-dmabuf-heaps.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0726-kselftests-Add-dma-heap-test.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0734-kselftests-Add-dma-heap-test.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0727-dma-buf-heaps-Use-_IOCTL_-for-userspace-IOCTL-identi.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0735-dma-buf-heaps-Use-_IOCTL_-for-userspace-IOCTL-identi.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0728-dma-buf-heaps-Remove-redundant-heap-identifier-from-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0736-dma-buf-heaps-Remove-redundant-heap-identifier-from-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0729-dma-buf-fix-resource-leak-on-ENOTTY-error-return-pat.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0737-dma-buf-fix-resource-leak-on-ENOTTY-error-return-pat.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0730-dma-heap-Make-the-symbol-dma_heap_ioctl_cmds-static.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0738-dma-heap-Make-the-symbol-dma_heap_ioctl_cmds-static.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0731-ARM-dts-Enable-firmware-clocks-on-all-Pis.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0739-ARM-dts-Enable-firmware-clocks-on-all-Pis.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0732-media-bcm2835-unicam-Always-service-interrupts.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0740-media-bcm2835-unicam-Always-service-interrupts.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0733-sc16is7xx-Fix-for-hardware-flow-control.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0741-sc16is7xx-Fix-for-hardware-flow-control.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0734-drm-vc4-Fix-VIC-usage-with-Broadcast-RGB.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0742-drm-vc4-Fix-VIC-usage-with-Broadcast-RGB.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0735-staging-vc04_services-mmal-vchiq-Update-parameters-l.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0743-staging-vc04_services-mmal-vchiq-Update-parameters-l.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0736-staging-vc04_services-bcm2835-codec-Request-headers-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0744-staging-vc04_services-bcm2835-codec-Request-headers-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0737-staging-vc04_services-bcm2835-codec-Avoid-fragmentin.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0745-staging-vc04_services-bcm2835-codec-Avoid-fragmentin.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0738-staging-vc04_services-bcm2835-camera-Request-headers.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0746-staging-vc04_services-bcm2835-camera-Request-headers.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0739-overlays-Fix-audio-parameter-of-vc4-kms-v3d.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0747-overlays-Fix-audio-parameter-of-vc4-kms-v3d.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0740-Switch-to-snd_soc_dai_set_bclk_ratio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0748-Switch-to-snd_soc_dai_set_bclk_ratio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0741-media-bcm2835-unicam-Retain-packing-information-on-G.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0749-media-bcm2835-unicam-Retain-packing-information-on-G.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0742-zswap-Defer-zswap-initialisation.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0750-zswap-Defer-zswap-initialisation.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0743-drm-vc4-Adopt-the-dma-configuration-from-the-HVS-or-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0751-drm-vc4-Adopt-the-dma-configuration-from-the-HVS-or-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0744-drm-vc4-Add-FKMS-as-an-acceptable-node-for-dma-range.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0752-drm-vc4-Add-FKMS-as-an-acceptable-node-for-dma-range.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0745-media-i2c-imx477-Return-correct-result-on-sensor-id-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0753-media-i2c-imx477-Return-correct-result-on-sensor-id-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0746-staging-vchiq_arm-Clean-up-40-bit-DMA-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0754-staging-vchiq_arm-Clean-up-40-bit-DMA-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0747-ARM-dts-Update-for-new-VCHIQ-BCM2711-DMA-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0755-ARM-dts-Update-for-new-VCHIQ-BCM2711-DMA-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0748-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0756-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0749-dt-bindings-Add-Broadcom-AVS-RO-thermal.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0757-dt-bindings-Add-Broadcom-AVS-RO-thermal.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0750-thermal-Add-BCM2711-thermal-driver.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0758-thermal-Add-BCM2711-thermal-driver.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0751-ARM-dts-bcm2711-Enable-thermal.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0759-ARM-dts-bcm2711-Enable-thermal.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0752-ARM-dts-bcm2711-rpi-Remove-downstream-thermal-sensor.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0760-ARM-dts-bcm2711-rpi-Remove-downstream-thermal-sensor.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0753-overlays-i2c-rtc-Fix-trickle-resistor-ohms-param.patch26
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0754-overlays-gpio-shutdown-Add-information-for-SysV-init.patch51
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0755-overlays-gpio-shutdown-Add-information-for-Raspberry.patch62
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0756-overlays-Add-spi0-overlay-to-support-sc16is752.patch87
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0757-overlays-i2c-rtc-gpio-Fix-trickle-resistor-ohms-para.patch27
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0758-media-bcm2835-isp-fix-bytes-per-line-calculations-fo.patch80
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0759-Add-Micro-Crystal-RV-1805-to-i2c-rtc-overlays.patch167
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0760-vc4-Set-driver_name-for-card.patch22
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0761-staging-vchiq_arm-Use-g_dma_dev-for-dma_unmap_sg.patch27
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0762-vc4-cec-Restore-cec-physical-address-on-reconnect.patch56
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0763-snd_bcm2835-disable-HDMI-audio-when-vc4-is-used-3640.patch92
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0764-overlays-i2c-gpio-Avoid-open-drain-warnings.patch93
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0765-overlays-Update-upstream-overlays-after-vc4-kms-v3d-.patch42
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0766-w1_therm-adding-code-comments-and-code-reordering.patch580
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0767-w1_therm-fix-reset_select_slave-during-discovery.patch149
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0768-w1_therm-adding-ext_power-sysfs-entry.patch293
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0769-w1_therm-adding-resolution-sysfs-entry.patch713
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0770-w1_therm-adding-eeprom-sysfs-entry.patch372
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0771-w1_therm-optimizing-temperature-read-timings.patch528
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0772-w1_therm-adding-alarm-sysfs-entry.patch319
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0773-w1_therm-adding-bulk-read-support-to-trigger-multipl.patch587
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0774-w1_therm-Free-the-correct-variable.patch41
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0775-w1_therm-remove-redundant-assignments-to-variable-re.patch58
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0776-PCI-brcmstb-Assert-fundamental-reset-on-initializati.patch33
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0777-clk-rpi-Adjust-DT-binding-to-match-upstream.patch189
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0778-clk-bcm-rpi-Add-an-enum-for-the-firmware-clocks.patch80
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0779-clk-bcm-rpi-Use-CCF-boundaries-instead-of-rolling-ou.patch134
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0780-clk-bcm-rpi-Give-firmware-clocks-a-name.patch52
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0781-clk-bcm-rpi-Remove-the-quirks-for-the-CPU-clock.patch207
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0782-clk-rpi-Only-register-a-few-firmware-clocks.patch43
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0783-clk-rpi-Fix-compatible-indentation.patch23
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0784-SQUASH-dts-Fix-firmware-clocks-support.patch176
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0785-ARM-dts-Add-bcm2711-rpi-cm4.dts.patch631
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0786-PCI-brcmstb-Add-DT-property-to-control-L1SS.patch79
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0787-ARM-dts-Set-brcm-enable-l1ss-for-CM4.patch27
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0788-Revert-SQUASH-Fix-spi-driver-compiler-warnings.patch23
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0789-Revert-spi-spi-bcm2835-Disable-forced-software-CS.patch59
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0790-media-irs1125-Using-i2c_transfer-for-ic2-reads.patch65
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0791-media-irs1125-Refactoring-and-debug-messages.patch123
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0792-media-irs1125-Atomic-access-to-imager-reconfiguratio.patch381
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0793-media-irs1125-Keep-HW-in-sync-after-imager-reset.patch181
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0794-staging-bcm2835-audio-Add-missing-MODULE_ALIAS.patch30
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0795-media-v4l2-subdev-Introduce-get-set-_mbus_config-pad.patch63
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0796-media-i2c-Use-the-new-get_mbus_config-pad-op.patch235
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0797-media-i2c-ov6650-Use-new-get-set-_mbus_config-ops.patch134
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch285
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0799-media-v4l2-subdev-Remove-s-g-_mbus_config-video-ops.patch43
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0800-staging-media-imx-Update-TODO-entry.patch28
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0801-media-i2c-adv748x-Adjust-TXA-data-lanes-number.patch123
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0802-media-i2c-adv748x-Implement-get_mbus_config.patch63
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0803-media-rcar-csi2-Negotiate-data-lanes-number.patch159
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0804-drivers-media-Remove-the-downstream-version-of-bcm28.patch3175
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0805-include-media-Add-vfl_devnode_type-of-VFL_TYPE_VIDEO.patch25
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0806-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch3150
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0807-media-bcm2835-unicam-Add-support-for-get_mbus_config.patch56
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0808-media-bcm2835-unicam-Always-service-interrupts.patch51
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0809-media-bcm2835-unicam-Fix-uninitialized-warning.patch21
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0810-media-bcm2835-unicam-Fixup-review-comments-from-Hans.patch242
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0811-media-bcm2835-unicam-Retain-packing-information-on-G.patch48
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0812-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch28
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0813-dt-dtoverlays-Fix-up-base-DT-and-overlays-for-update.patch144
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0814-media-bcm2835-unicam-Avoid-gcc-warning-over-0-on-end.patch27
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0815-media-dt-bindings-media-i2c-Add-IMX290-CMOS-sensor-b.patch98
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0816-media-i2c-Add-IMX290-CMOS-image-sensor-driver.patch939
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0817-media-i2c-imx290-set-the-format-before-VIDIOC_SUBDEV.patch50
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0818-media-i2c-imx290-fix-the-order-of-the-args-in-SET_RU.patch30
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0819-media-i2c-imx290-fix-reset-GPIO-pin-handling.patch61
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0820-media-i2c-imx290-Add-support-for-2-data-lanes.patch314
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0821-media-i2c-imx290-Add-configurable-link-frequency-and.patch307
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0822-media-i2c-imx290-Add-support-for-test-pattern-genera.patch110
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0823-media-i2c-imx290-Add-RAW12-mode-support.patch109
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0824-media-i2c-imx290-Add-support-to-enumerate-all-frame-.patch58
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0825-media-i2c-imx290-Move-the-settle-time-delay-out-of-l.patch37
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0826-media-i2c-imx290-set-bus_type-before-calling-v4l2_fw.patch137
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0827-media-i2c-imx290-Add-support-for-74.25MHz-clock.patch264
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0828-media-i2c-imx290-Correct-range-for-V4L2_CID_GAIN-to-.patch26
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0829-media-i2c-imx290-Convert-HMAX-setting-into-V4L2_CID_.patch159
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0830-media-i2c-imx290-Add-support-for-V4L2_CID_VBLANK.patch141
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0831-media-i2c-imx290-Add-exposure-control-to-the-driver.patch93
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0832-media-i2c-imx290-Add-H-and-V-flip-controls.patch83
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0833-media-dt-bindings-media-i2c-Add-mono-version-to-IMX2.patch36
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0834-media-i2c-imx290-Add-support-for-the-mono-sensor-var.patch185
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0835-media-i2c-imx290-Switch-set_hmax-to-use-imx290_write.patch43
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0836-dtoverlays-Add-an-overlay-for-the-Sony-IMX290-image-.patch236
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0837-vc4_hdmi-Set-HD_CTL_WHOLSMP-and-HD_CTL_CHALIGN_SET.patch38
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0838-staging-vc04_services-isp-Fixup-g-s_selection-implem.patch129
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0839-staging-vc04_services-isp-Reorder-operations-during-.patch92
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0840-uapi-bcm2835-isp-Fixups-for-bcm2835-isp-uapi-structu.patch34
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0841-ARM-dts-Add-Bluetooth-nodes-for-Raspberry-Pi.patch283
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0842-drm-vc4-Allow-interlaced-HDMI-modes-from-FKMS.patch37
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0843-serial-8250-bcm2835aux-defer-if-clock-is-zero.patch28
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0844-media-v4l-Add-14-bit-raw-bayer-pixel-formats.patch151
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0845-media-v4l-Add-14-bit-raw-greyscale-pixel-format.patch131
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0846-media-v4l-Add-1X14-14-bit-greyscale-media-bus-code-d.patch88
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0847-media-Add-a-pixel-format-for-MIPI-packed-12bit-luma-.patch95
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0848-media-Add-a-pixel-format-for-MIPI-packed-14bit-luma-.patch104
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0849-staging-vc04_services-isp-Add-support-for-14bit-Baye.patch75
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0850-staging-vc04_services-isp-Add-monochrome-image-forma.patch92
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0851-staging-vc04_services-isp-Increase-the-number-of-sup.patch29
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0852-staging-vc04_services-codec-Increase-the-number-of-s.patch29
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0853-staging-vc04_services-codec-Add-support-for-mono-for.patch64
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0854-staging-vc04_services-codec-Add-support-for-14bit-Ba.patch57
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0855-media-bcm2835-unicam-Add-support-for-12bit-mono-pack.patch25
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0856-media-bcm2835-unicam-Add-support-for-14bit-mono-sour.patch29
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0857-media-bcm2835-unicam-Add-support-for-unpacked-14bit-.patch42
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0858-overlays-Fix-miniuart-bt-krnbt-parameter.patch32
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0859-drm-vc4-Make-FKMS-max-refresh-rate-a-module-paramete.patch55
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0860-drm-vc4-FKMS-Block-modes-with-odd-horizontal-timing-.patch74
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0861-dt-Use-rpi-firmware-kms-2711-on-2711-platforms.patch37
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0862-drm-vc4-FKMS-Put-includes-in-alphabetical-order-and-.patch57
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0863-irqchip-bcm2835-Quiesce-IRQs-left-enabled-by-bootloa.patch105
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0864-dtoverlays-Fixup-imx219-and-imx477-overlays-due-to-p.patch42
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0865-overlays-rpi-ft5406-Fix-boolean-parameters.patch27
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0866-ARM-dts-Copy-kernel-BT-changes-to-CM4.patch29
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0867-ARM-dts-Make-bcm2711-dts-more-like-5.7.patch696
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0868-bcm2835-dma-Add-NO_WAIT_RESP-flag.patch54
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0869-ARM-dts-Restore-the-old-2711-scb-ranges-property.patch24
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0870-media-i2c-add-ov9281-driver.patch1218
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0871-media-i2c-ov9281-fix-mclk-issue-when-probe-multiple-.patch60
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0872-media-i2c-ov9281-add-enum_frame_interval-function-fo.patch97
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0873-media-i2c-ov9281-Fixup-for-recent-kernel-releases-an.patch693
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0874-media-i2c-ov9281-Read-chip-ID-via-2-reads.patch42
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0875-dtoverlay-Add-overlay-for-Omnivision-OV9281-image-se.patch157
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0876-Bluetooth-hci_bcm-Fix-RTS-handling-during-startup.patch33
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0877-Bluetooth-hci_bcm-Add-compatible-string-for-BCM43540.patch28
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0878-Bluetooth-btbcm-Add-entry-for-BCM4335A0-UART-bluetoo.patch58
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0879-Bluetooth-hci_bcm-Disallow-set_baudrate-for-BCM4354.patch115
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0880-Bluetooth-btbcm-Support-pcm-configuration.patch124
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0881-Bluetooth-hci_bcm-Support-pcm-params-in-dts.patch74
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0882-Bluetooth-hci_bcm-Drive-RTS-only-for-BCM43438.patch92
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0883-Enhances-the-DAC-driver-to-control-the-optional-head.patch134
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0884-ARM-dts-hifiberry-dacplus-headphone-amp-support.patch24
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0885-media-i2c-imx290-Explicitly-set-v-h-blank-on-mode-ch.patch46
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0886-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch156
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0887-media-i2c-imx290-Set-the-colorspace-fields-in-the-fo.patch31
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0888-media-bcm2835-unicam-Reinstate-V4L2_CAP_READWRITE-in.patch28
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0889-media-bcm2835-unicam-Ensure-type-is-VIDEO_CAPTURE-in.patch36
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0890-dtoverlays-Create-an-overlay-for-the-Omnivision-OV72.patch157
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0891-vc4_hdmi-Set-HDMI_MAI_FMT.patch124
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0892-drm-vc4-add-iec958-controls-to-vc4_hdmi.patch119
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0893-drm-vc4-move-setup-from-hw_params-to-prepare.patch56
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0894-drm-vc4-enable-HBR-MAI-format-on-HBR-streams.patch25
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0895-vc4_hdmi-Remove-firmware-logic-for-MAI-threshold-set.patch47
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0896-vc_hdmi-Set-VC4_HDMI_MAI_CONFIG_FORMAT_REVERSE.patch24
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0897-dts-Enable-NO_WAIT_RESP-for-hdmi-audio-dma.patch45
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0898-SQUASH-dts-Further-simplify-firmware-clocks.patch69
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0899-media-bcm2835-unicam-Set-VPU-min-clock-freq-to-250Mh.patch154
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0900-dt-bindings-bcm2835-unicam-Update-documentation-with.patch38
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0901-correct-SND_SOC_DAILINK_DEFS.patch21
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0902-media-dt-bindings-video-interfaces-Document-orientat.patch43
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0903-media-dt-bindings-video-interface-Replace-rotation-d.patch390
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0904-media-v4l2-ctrl-Document-V4L2_CID_CAMERA_ORIENTATION.patch61
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0905-media-v4l2-ctrl-Document-V4L2_CID_CAMERA_SENSOR_ROTA.patch151
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0906-media-v4l2-ctrls-Add-camera-orientation-and-rotation.patch89
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0907-media-v4l2-fwnode-Add-helper-to-parse-device-propert.patch138
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0908-media-v4l2-ctrls-Add-helper-to-register-properties.patch114
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0909-media-i2c-ov5647-Parse-and-register-properties.patch49
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0910-media-i2c-imx219-Parse-and-register-properties.patch51
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0911-media-i2c-imx477-Parse-and-register-properties.patch45
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0912-dt-dtoverlays-ov5647-Add-parameter-to-set-camera-mod.patch49
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0913-dt-dtoverlays-imx219-Add-parameter-to-set-camera-mod.patch50
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0914-dt-dtoverlays-imx477-Add-parameter-to-set-camera-mod.patch50
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0915-drm-vc4-Add-DRM_MODE_FLAG_DBLCLK-support-to-vc4-fkms.patch54
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0916-leds-Add-the-actpwr-trigger.patch236
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0917-ARM-dts-Select-the-actpwr-LED-trigger-on-Zeroes.patch41
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0918-staging-vc04_services-isp-Rework-lens-shading-to-tak.patch87
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0919-Mute-bug-fix-for-the-Audioinjector.net-isolated-soun.patch64
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0920-vc4-Report-channel-mapping-back-to-userspace.patch504
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0921-SQUASH-leds-actpwr-delete-unused-variable.patch20
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0922-staging-vchiq_arm-children-inherit-DMA-config.patch36
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0923-ARM-dts-2711-DMA-can-address-36-bits.patch25
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0924-bcm2835-dma-Advertise-the-full-DMA-range.patch77
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0925-ARM-dts-Add-UART-skip-init-properties-for-U-boot.patch35
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0926-drm-vc4-Remove-UIF-from-the-list-of-modifiers-return.patch29
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0927-ARM-proc-v7-Force-misalignment-of-early-stmia.patch60
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0928-overlays-Fix-sc16is75x-overlays-w.r.t.-serdev.patch182
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0929-overlays-Delete-spi0-hw-cs.patch87
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0930-backlight-gpio-Explicitly-set-the-direction-of-the-G.patch88
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0931-overlays-Add-maxtherm-overlay-for-MAX6675-31855.patch238
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0932-dtoverlays-Add-the-iio_hwmon-driver-to-correct-ADC-i.patch40
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0933-dts-bcm2711-Disable-DVP-by-default.patch44
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0934-ARM-dts-Add-required-USB-power-domain-for-XCHI.patch24
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0935-overlays-Regenerate-upstream-pi4.patch28
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0936-drm-vc4-Increase-the-number-of-planes-per-crtc-in-FK.patch105
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0937-drm-vc4-Set-the-possible-crtcs-mask-correctly-for-pl.patch40
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0938-staging-vc04_services-codec-Fix-incorrect-buffer-cle.patch52
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0939-staging-vc04_service-codec-Allow-start_streaming-to-.patch70
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0940-staging-vc04_services-codec-Fix-component-enable-dis.patch38
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0941-update-rpi-display-overlay.dts-pins-for-5.4.patch32
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0942-Bluetooth-btrtl-Add-support-for-RTL8761B.patch77
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0943-dtoverlays-Add-overlay-for-the-PCA953x-family-of-GPI.patch315
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0944-rtc-rv3028-Write-BSM-and-TCE-TCR-to-EEPROM.patch120
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0945-rtc-rv3028-Refresh-RAM-on-EEPROM-write.patch92
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0946-dt-overlays-Add-PiFace-Digital-Device-Tree-Overlay.patch199
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0947-overlays-Updated-MCP3008-compatible-strings.patch84
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0948-RESET_CONTROLLER-needs-to-be-activated-to-compile-Br.patch20
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0949-media-dvbsky-use-a-single-mutex-and-state-buffers-fo.patch64
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0950-ARM-dts-bcm2711-Enable-support-for-DDR52-eMMC.patch22
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0951-staging-vc04_services-ISP-Fix-dmabuf-error-check-in-.patch25
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0952-ARM-dts-bcm2708.dtsi-Don-t-delete-the-cpus-node.patch26
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0953-ARM-dts-bcm2835-Use-the-L2-non-allocating-alias.patch30
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0954-media-bcm2835-unicam-Drop-WARN-on-uing-direct-cache-.patch34
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0955-media-i2c-tc358743-Only-allow-supported-pixel-fmts-i.patch30
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0956-media-i2c-ov9281-Add-support-for-8-bit-readout.patch188
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0957-overlays-Add-spi0-1cs-and-spi0-2cs.patch199
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0958-overlays-Fix-error-in-README.patch23
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0959-overlays-Minor-README-correction.patch21
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0960-staging-fbtft-Add-support-for-display-variants.patch204
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0961-overlays-Add-adafruit18-and-sainsmart18-overlays.patch169
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0962-ARM-dts-Limit-BT-modem-baud-rate-on-3B.patch28
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0963-overlays-Update-i2c0-overlay-to-disable-the-i2c0mux.patch70
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0964-dt-Remove-duplicate-assignment-for-i2c0-pinctrl-conf.patch155
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0965-overlays-Add-option-for-composite-to-vc4-kms-v3d-pi4.patch68
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0966-minor-typo-in-directions.patch20
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0967-overlays-Regenerate-upstream-pi4-overlay.patch31
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0968-overlays-Add-parameters-to-adafruit18-sainsmart18.patch94
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0969-rpivid_h265-Fix-width-height-typo.patch21
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0970-overlays-Add-extra-CMA-sizes-up-to-512M.patch78
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0971-overlays-Add-note-to-BCM2711-overlays.patch150
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0972-overlays-adafruit18-sainsmart18-default-bgr-to-off.patch53
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0973-net-bcmgenet-Reset-RBUF-on-first-open.patch70
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0974-ASoC-cs42xx8-Only-define-cs42xx8_of_match-once.patch43
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0975-staging-bcm2835-codec-Use-a-define-the-completion-ti.patch35
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0976-staging-bcm2835-codec-Correct-buffer-number-change-o.patch30
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0977-USB-gadget-f_hid-avoid-crashes-and-log-spam.patch56
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0978-Update-hy28b-overlay.dts.patch21
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0979-overlays-Update-display-GPIO-declarations.patch170
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0980-SQUASH-USB-gadget-f_hid-remove-more-spam.patch26
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0981-overlays-Add-sd3078-to-the-i2c-rtc-overlay.patch58
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0982-dwc_otg-initialise-sched_frame-for-periodic-QHs-that.patch33
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0983-staging-bcm2835-camera-Replace-deprecated-V4L2_PIX_F.patch30
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0984-staging-bcm2835-codec-Replace-deprecated-V4L2_PIX_FM.patch27
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0985-ARM-bcm2711-rpi.dts-Unlock-DMA-channels-9-10.patch33
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0986-gpio-Add-gpio-fsm-driver.patch1182
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0987-overlays-Add-fsm-demo-overlay.patch151
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0988-overlays-Add-ghost-amp-overlay.patch163
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0989-Bluetooth-Disable-High-Speed-by-default.patch26
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0990-Fixes-a-problem-when-module-probes-before-i2c-module.patch46
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0991-uapi-Update-V4L2_CID_USER_BCM2835_ISP_BASE-due-to-up.patch41
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0992-dtoverlays-Correct-CSI2-settings-for-ov9281.patch36
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0993-xhci-quirks-add-link-TRB-quirk-for-VL805.patch61
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0994-dts-Add-CM4-to-arm64-dt-files.patch28
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0995-dts-Tidy-the-Raspberry-Pi-Makefile-entries.patch43
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0996-staging-bcm2835-audio-Add-disable-headphones-flag.patch34
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0997-ARM-dts-Disable-headphone-audio-on-Zeroes-CM4.patch42
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0998-overlays-Enable-headphone-audio-in-audremap.patch26
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0999-rpisense-fb-Set-pseudo_pallete-to-prevent-crash-on-f.patch30
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1000-PiFi-40-Devicetree-files.patch91
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1001-PiFi-40-driver-Makefile-and-Kconfig.patch331
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1002-dwc_otg-Minimise-header-and-fix-build-warnings.patch747
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1003-gpio-fsm-Fix-a-build-warning.patch22
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1004-rpivid_h625-Fix-build-warnings.patch68
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1005-dwc_otg-Fix-more-build-warnings.patch149
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1006-bcm2708_fb-Fix-a-build-warning.patch22
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1007-bcm2835-pcm-Fix-up-multichannel-pcm-audio.patch55
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1008-watchdog-bcm2835-Ignore-params-after-the-partition-n.patch29
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1009-firmware-raspberrypi-Add-support-for-tryonce-reboot-.patch72
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1010-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch71
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1011-phy-broadcom-Add-bcm54213pe-configuration.patch35
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1012-Allo-boss2-driver.patch1185
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1013-Add-allo-boss2-overlay.patch98
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1014-Revert-mailbox-avoid-timer-start-from-callback.patch60
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1015-ARM-dts-Add-bcm2711-rpi-400.dts.patch627
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1016-overlays-Deprecate-and-delete-the-sdtweak-overlay.patch64
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1017-overlays-Complete-the-sdtweak-excision.patch57
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1018-ARM-dts-bcm27xx-Remove-enable_headphones-setting.patch110
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1019-staging-vcsm-cma-Fix-memory-leak-from-not-detaching-.patch77
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1020-Update-Allo-Piano-Dac-Driver-for-5.4.y-kernels.patch246
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1021-Overlay-Update-Allo-Piano-Plus-dac-driver-for-5.4.y-.patch30
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1022-Update-volume-controls-in-Allo-Piano-Dac-Plus.patch141
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1023-media-i2c-imx219-Selection-compliance-fixes.patch80
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1024-media-bcm2835-unicam-Correctly-handle-error-propagat.patch27
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1025-media-bcm2835-unicam-Return-early-from-stop_streamin.patch64
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1026-media-bcm2835-unicam-Clear-clock-state-when-stopping.patch25
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1027-ARM-dts-CM4-audio-pins-are-not-connected.patch21
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1028-overlays-Add-PCF85063-and-PCF85063A-to-i2c-rtc.patch339
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1029-overlays-Fix-cut-and-paste-error-in-README.patch24
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1030-media-i2c-imx477-Selection-compliance-fixes.patch80
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1031-net-lan78xx-Ack-pending-PHY-ints-when-resetting.patch32
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1032-overlays-mpu6050-Add-addr-parameter.patch36
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1033-overlays-Add-missing-addresses-to-ads1015-ads1115.patch41
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1034-media-i2c-ov5647-Selection-compliance-fixes.patch88
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1035-Add-overlay-for-Seeed-Studio-CAN-BUS-FD-HAT-4034.patch217
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1036-overlays-Rebuild-upstream-with-latest-ovmerge.patch173
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1037-overlays-give-Seeed-Studio-CAN-BUS-FD-HAT-a-v2-postf.patch286
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1038-overlays-Add-overlay-for-Seeed-Studio-CAN-BUS-FD-HAT.patch192
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1039-overlays-add-wm8960-soundcard-overlay.patch129
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1040-overlays-add-spi-override-to-merus-amp-overlay.patch44
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1041-overlays-seeed-can-fd-hat-clarify-how-to-identify-HA.patch45
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1042-uapi-bcm2835-isp-Add-colour-denoise-configuration.patch56
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1043-staging-vc04_services-ISP-Add-colour-denoise-control.patch75
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1044-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch31
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1045-Adds-the-DT-overlays-to-support-Hifiberry-AMP100.patch132
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1046-Enhances-the-Hifiberry-DAC-driver-for-Hifiberry-AMP1.patch238
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1047-ARM-dts-Declare-Pi400-and-CM4-have-no-audio-pins.patch41
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-1048-Hifiberry-DAC-ADC-Pro-fix-for-the-PLL-when-changing-.patch56
922 files changed, 41563 insertions, 292 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Disable-forced-software-CS.patch b/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Disable-forced-software-CS.patch
new file mode 100644
index 0000000000..0abe5059c0
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Disable-forced-software-CS.patch
@@ -0,0 +1,47 @@
+From dc1e3fefce7abd7532fbc74e26df61a8ced1dcd6 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 15 Jan 2019 12:41:15 +0000
+Subject: [PATCH] spi: spi-bcm2835: Disable forced software CS
+
+With GPIO CS used by the DTBs, allow hardware CS to be selected by an
+overlay.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ drivers/spi/spi-bcm2835.c | 37 -------------------------------------
+ 1 file changed, 37 deletions(-)
+
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -1230,31 +1230,6 @@ static int bcm2835_spi_setup(struct spi_
+ return -EINVAL;
+ }
+
+- /*
+- * Translate native CS to GPIO
+- *
+- * FIXME: poking around in the gpiolib internals like this is
+- * not very good practice. Find a way to locate the real problem
+- * and fix it. Why is the GPIO descriptor in spi->cs_gpiod
+- * sometimes not assigned correctly? Erroneous device trees?
+- */
+-
+- /* get the gpio chip for the base */
+- chip = gpiochip_find("pinctrl-bcm2835", chip_match_name);
+- if (!chip)
+- return 0;
+-
+- spi->cs_gpiod = gpiochip_request_own_desc(chip, 8 - spi->chip_select,
+- DRV_NAME,
+- GPIO_LOOKUP_FLAGS_DEFAULT,
+- GPIOD_OUT_LOW);
+- if (IS_ERR(spi->cs_gpiod))
+- return PTR_ERR(spi->cs_gpiod);
+-
+- /* and set up the "mode" and level */
+- dev_info(&spi->dev, "setting up native-CS%i to use GPIO\n",
+- spi->chip_select);
+-
+ return 0;
+ }
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Re-enable-HW-CS.patch b/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Re-enable-HW-CS.patch
deleted file mode 100644
index 13dd356f93..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Re-enable-HW-CS.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From 33b150a792ccde6eded4240dea0e3ec784b07d7c Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Tue, 15 Jan 2019 12:39:50 +0000
-Subject: [PATCH] spi: spi-bcm2835: Re-enable HW CS
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- drivers/spi/spi-bcm2835.c | 53 +++++++++++++++++++++++++++++++++++++--
- 1 file changed, 51 insertions(+), 2 deletions(-)
-
---- a/drivers/spi/spi-bcm2835.c
-+++ b/drivers/spi/spi-bcm2835.c
-@@ -1169,9 +1169,57 @@ static void bcm2835_spi_handle_err(struc
- bcm2835_spi_reset_hw(ctlr);
- }
-
--static int chip_match_name(struct gpio_chip *chip, void *data)
-+static void bcm2835_spi_set_cs(struct spi_device *spi, bool gpio_level)
- {
-- return !strcmp(chip->label, data);
-+ /*
-+ * we can assume that we are "native" as per spi_set_cs
-+ * calling us ONLY when cs_gpio is not set
-+ * we can also assume that we are CS < 3 as per bcm2835_spi_setup
-+ * we would not get called because of error handling there.
-+ * the level passed is the electrical level not enabled/disabled
-+ * so it has to get translated back to enable/disable
-+ * see spi_set_cs in spi.c for the implementation
-+ */
-+
-+ struct spi_master *master = spi->master;
-+ struct bcm2835_spi *bs = spi_master_get_devdata(master);
-+ u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
-+ bool enable;
-+
-+ /* calculate the enable flag from the passed gpio_level */
-+ enable = (spi->mode & SPI_CS_HIGH) ? gpio_level : !gpio_level;
-+
-+ /* set flags for "reverse" polarity in the registers */
-+ if (spi->mode & SPI_CS_HIGH) {
-+ /* set the correct CS-bits */
-+ cs |= BCM2835_SPI_CS_CSPOL;
-+ cs |= BCM2835_SPI_CS_CSPOL0 << spi->chip_select;
-+ } else {
-+ /* clean the CS-bits */
-+ cs &= ~BCM2835_SPI_CS_CSPOL;
-+ cs &= ~(BCM2835_SPI_CS_CSPOL0 << spi->chip_select);
-+ }
-+
-+ /* select the correct chip_select depending on disabled/enabled */
-+ if (enable) {
-+ /* set cs correctly */
-+ if (spi->mode & SPI_NO_CS) {
-+ /* use the "undefined" chip-select */
-+ cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01;
-+ } else {
-+ /* set the chip select */
-+ cs &= ~(BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01);
-+ cs |= spi->chip_select;
-+ }
-+ } else {
-+ /* disable CSPOL which puts HW-CS into deselected state */
-+ cs &= ~BCM2835_SPI_CS_CSPOL;
-+ /* use the "undefined" chip-select as precaution */
-+ cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01;
-+ }
-+
-+ /* finally set the calculated flags in SPI_CS */
-+ bcm2835_wr(bs, BCM2835_SPI_CS, cs);
- }
-
- static int bcm2835_spi_setup(struct spi_device *spi)
-@@ -1276,6 +1324,7 @@ static int bcm2835_spi_probe(struct plat
- ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
- ctlr->num_chipselect = BCM2835_SPI_NUM_CS;
- ctlr->setup = bcm2835_spi_setup;
-+ ctlr->set_cs = bcm2835_spi_set_cs;
- ctlr->transfer_one = bcm2835_spi_transfer_one;
- ctlr->handle_err = bcm2835_spi_handle_err;
- ctlr->prepare_message = bcm2835_spi_prepare_message;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0136-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch b/target/linux/bcm27xx/patches-5.4/950-0135-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch
index cc379f55e1..cc379f55e1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0136-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0135-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0135-spi-spi-bcm2835-Disable-forced-software-CS.patch b/target/linux/bcm27xx/patches-5.4/950-0135-spi-spi-bcm2835-Disable-forced-software-CS.patch
deleted file mode 100644
index 752464087f..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0135-spi-spi-bcm2835-Disable-forced-software-CS.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From dc1e3fefce7abd7532fbc74e26df61a8ced1dcd6 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Tue, 15 Jan 2019 12:41:15 +0000
-Subject: [PATCH] spi: spi-bcm2835: Disable forced software CS
-
-With GPIO CS used by the DTBs, allow hardware CS to be selected by an
-overlay.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- drivers/spi/spi-bcm2835.c | 37 -------------------------------------
- 1 file changed, 37 deletions(-)
-
---- a/drivers/spi/spi-bcm2835.c
-+++ b/drivers/spi/spi-bcm2835.c
-@@ -1278,31 +1278,6 @@ static int bcm2835_spi_setup(struct spi_
- return -EINVAL;
- }
-
-- /*
-- * Translate native CS to GPIO
-- *
-- * FIXME: poking around in the gpiolib internals like this is
-- * not very good practice. Find a way to locate the real problem
-- * and fix it. Why is the GPIO descriptor in spi->cs_gpiod
-- * sometimes not assigned correctly? Erroneous device trees?
-- */
--
-- /* get the gpio chip for the base */
-- chip = gpiochip_find("pinctrl-bcm2835", chip_match_name);
-- if (!chip)
-- return 0;
--
-- spi->cs_gpiod = gpiochip_request_own_desc(chip, 8 - spi->chip_select,
-- DRV_NAME,
-- GPIO_LOOKUP_FLAGS_DEFAULT,
-- GPIOD_OUT_LOW);
-- if (IS_ERR(spi->cs_gpiod))
-- return PTR_ERR(spi->cs_gpiod);
--
-- /* and set up the "mode" and level */
-- dev_info(&spi->dev, "setting up native-CS%i to use GPIO\n",
-- spi->chip_select);
--
- return 0;
- }
-
diff --git a/target/linux/bcm27xx/patches-5.4/950-0137-configs-Enable-the-AD193x-codecs.patch b/target/linux/bcm27xx/patches-5.4/950-0136-configs-Enable-the-AD193x-codecs.patch
index bbf7c5a634..bbf7c5a634 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0137-configs-Enable-the-AD193x-codecs.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0136-configs-Enable-the-AD193x-codecs.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0138-lan78xx-EEE-support-is-now-a-PHY-property.patch b/target/linux/bcm27xx/patches-5.4/950-0137-lan78xx-EEE-support-is-now-a-PHY-property.patch
index 2778f40a94..2778f40a94 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0138-lan78xx-EEE-support-is-now-a-PHY-property.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0137-lan78xx-EEE-support-is-now-a-PHY-property.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0139-Revert-staging-vchiq-delete-vchiq_killable.h.patch b/target/linux/bcm27xx/patches-5.4/950-0138-Revert-staging-vchiq-delete-vchiq_killable.h.patch
index 0e314ec396..0e314ec396 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0139-Revert-staging-vchiq-delete-vchiq_killable.h.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0138-Revert-staging-vchiq-delete-vchiq_killable.h.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0140-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch b/target/linux/bcm27xx/patches-5.4/950-0139-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch
index 09bfb7acad..09bfb7acad 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0140-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0139-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0141-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0140-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch
index 288281916c..288281916c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0141-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0140-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0142-bcm2835-dma-Add-support-for-per-channel-flags.patch b/target/linux/bcm27xx/patches-5.4/950-0141-bcm2835-dma-Add-support-for-per-channel-flags.patch
index 8f68768588..8f68768588 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0142-bcm2835-dma-Add-support-for-per-channel-flags.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0141-bcm2835-dma-Add-support-for-per-channel-flags.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0143-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch b/target/linux/bcm27xx/patches-5.4/950-0142-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch
index 0ec79adb27..0ec79adb27 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0143-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0142-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0144-rtc-rv3028-Add-backup-switchover-mode-support.patch b/target/linux/bcm27xx/patches-5.4/950-0143-rtc-rv3028-Add-backup-switchover-mode-support.patch
index 375bd6e6b7..375bd6e6b7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0144-rtc-rv3028-Add-backup-switchover-mode-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0143-rtc-rv3028-Add-backup-switchover-mode-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0145-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0144-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch
index 501e81092e..501e81092e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0145-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0144-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0146-lan78xx-use-default-alignment-for-rx-buffers.patch b/target/linux/bcm27xx/patches-5.4/950-0145-lan78xx-use-default-alignment-for-rx-buffers.patch
index 1c2daad764..1c2daad764 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0146-lan78xx-use-default-alignment-for-rx-buffers.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0145-lan78xx-use-default-alignment-for-rx-buffers.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0147-Added-IQaudIO-Pi-Codec-board-support-2969.patch b/target/linux/bcm27xx/patches-5.4/950-0146-Added-IQaudIO-Pi-Codec-board-support-2969.patch
index 2e4039c6b1..2e4039c6b1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0147-Added-IQaudIO-Pi-Codec-board-support-2969.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0146-Added-IQaudIO-Pi-Codec-board-support-2969.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0148-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch b/target/linux/bcm27xx/patches-5.4/950-0147-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch
index 838508559e..838508559e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0148-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0147-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0149-media-ov5647-Add-set_fmt-and-get_fmt-calls.patch b/target/linux/bcm27xx/patches-5.4/950-0148-media-ov5647-Add-set_fmt-and-get_fmt-calls.patch
index 6b5aa2b664..6b5aa2b664 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0149-media-ov5647-Add-set_fmt-and-get_fmt-calls.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0148-media-ov5647-Add-set_fmt-and-get_fmt-calls.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0150-media-Documentation-DT-add-device-tree-for-PWDN-cont.patch b/target/linux/bcm27xx/patches-5.4/950-0149-media-Documentation-DT-add-device-tree-for-PWDN-cont.patch
index 6d2cd03daa..6d2cd03daa 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0150-media-Documentation-DT-add-device-tree-for-PWDN-cont.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0149-media-Documentation-DT-add-device-tree-for-PWDN-cont.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0151-media-ov5647-Add-support-for-PWDN-GPIO.patch b/target/linux/bcm27xx/patches-5.4/950-0150-media-ov5647-Add-support-for-PWDN-GPIO.patch
index 24b678f858..24b678f858 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0151-media-ov5647-Add-support-for-PWDN-GPIO.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0150-media-ov5647-Add-support-for-PWDN-GPIO.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0152-media-ov5647-Add-support-for-non-continuous-clock-mo.patch b/target/linux/bcm27xx/patches-5.4/950-0151-media-ov5647-Add-support-for-non-continuous-clock-mo.patch
index 0fc4fa3420..0fc4fa3420 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0152-media-ov5647-Add-support-for-non-continuous-clock-mo.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0151-media-ov5647-Add-support-for-non-continuous-clock-mo.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0153-media-tc358743-Increase-FIFO-level-to-374.patch b/target/linux/bcm27xx/patches-5.4/950-0152-media-tc358743-Increase-FIFO-level-to-374.patch
index 8ec643f102..8ec643f102 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0153-media-tc358743-Increase-FIFO-level-to-374.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0152-media-tc358743-Increase-FIFO-level-to-374.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0154-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch b/target/linux/bcm27xx/patches-5.4/950-0153-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch
index 2357c878d7..2357c878d7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0154-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0153-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0155-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch b/target/linux/bcm27xx/patches-5.4/950-0154-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch
index 18ee169b1c..18ee169b1c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0155-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0154-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0156-media-tc358743-Check-I2C-succeeded-during-probe.patch b/target/linux/bcm27xx/patches-5.4/950-0155-media-tc358743-Check-I2C-succeeded-during-probe.patch
index 653602b306..653602b306 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0156-media-tc358743-Check-I2C-succeeded-during-probe.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0155-media-tc358743-Check-I2C-succeeded-during-probe.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0157-media-adv7180-Default-to-the-first-valid-input.patch b/target/linux/bcm27xx/patches-5.4/950-0156-media-adv7180-Default-to-the-first-valid-input.patch
index 7e2066b211..7e2066b211 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0157-media-adv7180-Default-to-the-first-valid-input.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0156-media-adv7180-Default-to-the-first-valid-input.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0158-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch b/target/linux/bcm27xx/patches-5.4/950-0157-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch
index 75323fceb2..75323fceb2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0158-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0157-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0159-media-videodev2-Add-helper-defines-for-printing-FOUR.patch b/target/linux/bcm27xx/patches-5.4/950-0158-media-videodev2-Add-helper-defines-for-printing-FOUR.patch
index 683e5611e1..683e5611e1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0159-media-videodev2-Add-helper-defines-for-printing-FOUR.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0158-media-videodev2-Add-helper-defines-for-printing-FOUR.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0160-dt-bindings-Document-BCM283x-CSI2-CCP2-receiver.patch b/target/linux/bcm27xx/patches-5.4/950-0159-dt-bindings-Document-BCM283x-CSI2-CCP2-receiver.patch
index d091a14bc5..d091a14bc5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0160-dt-bindings-Document-BCM283x-CSI2-CCP2-receiver.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0159-dt-bindings-Document-BCM283x-CSI2-CCP2-receiver.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0161-MAINTAINERS-Add-entry-for-BCM2835-Unicam-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0160-MAINTAINERS-Add-entry-for-BCM2835-Unicam-driver.patch
index 4b8b3aa431..4b8b3aa431 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0161-MAINTAINERS-Add-entry-for-BCM2835-Unicam-driver.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0160-MAINTAINERS-Add-entry-for-BCM2835-Unicam-driver.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0162-media-tc358743-Return-an-appropriate-colorspace-from.patch b/target/linux/bcm27xx/patches-5.4/950-0161-media-tc358743-Return-an-appropriate-colorspace-from.patch
index b5b9105f4f..b5b9105f4f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0162-media-tc358743-Return-an-appropriate-colorspace-from.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0161-media-tc358743-Return-an-appropriate-colorspace-from.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0164-staging-bcm2835-camera-Fix-logical-continuation-spli.patch b/target/linux/bcm27xx/patches-5.4/950-0162-staging-bcm2835-camera-Fix-logical-continuation-spli.patch
index c1cbff5671..c1cbff5671 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0164-staging-bcm2835-camera-Fix-logical-continuation-spli.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0162-staging-bcm2835-camera-Fix-logical-continuation-spli.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0165-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch b/target/linux/bcm27xx/patches-5.4/950-0163-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch
index c9e18874ab..c9e18874ab 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0165-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0163-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0166-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch b/target/linux/bcm27xx/patches-5.4/950-0164-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch
index 278d57b1bd..278d57b1bd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0166-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0164-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0167-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch b/target/linux/bcm27xx/patches-5.4/950-0165-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch
index 53a6c07e9d..53a6c07e9d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0167-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0165-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0168-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch b/target/linux/bcm27xx/patches-5.4/950-0166-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch
index 31f7c8a525..31f7c8a525 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0168-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0166-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0169-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch b/target/linux/bcm27xx/patches-5.4/950-0167-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch
index fa37fff35f..fa37fff35f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0169-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0167-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0170-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch b/target/linux/bcm27xx/patches-5.4/950-0168-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch
index 95f5885c4a..95f5885c4a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0170-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0168-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0171-staging-mmal-vchiq-Add-support-for-event-callbacks.patch b/target/linux/bcm27xx/patches-5.4/950-0169-staging-mmal-vchiq-Add-support-for-event-callbacks.patch
index 125f9d552e..125f9d552e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0171-staging-mmal-vchiq-Add-support-for-event-callbacks.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0169-staging-mmal-vchiq-Add-support-for-event-callbacks.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0172-staging-vc04_services-Support-sending-data-to-MMAL-p.patch b/target/linux/bcm27xx/patches-5.4/950-0170-staging-vc04_services-Support-sending-data-to-MMAL-p.patch
index 5dec3c4127..5dec3c4127 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0172-staging-vc04_services-Support-sending-data-to-MMAL-p.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0170-staging-vc04_services-Support-sending-data-to-MMAL-p.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0173-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch b/target/linux/bcm27xx/patches-5.4/950-0171-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch
index 7dd50f75bf..7dd50f75bf 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0173-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0171-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0174-staging-vc04_services-Add-new-vc-sm-cma-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0172-staging-vc04_services-Add-new-vc-sm-cma-driver.patch
index d1d3df0890..d1d3df0890 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0174-staging-vc04_services-Add-new-vc-sm-cma-driver.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0172-staging-vc04_services-Add-new-vc-sm-cma-driver.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0175-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch b/target/linux/bcm27xx/patches-5.4/950-0173-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch
index 62cce8a94e..62cce8a94e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0175-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0173-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0176-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch b/target/linux/bcm27xx/patches-5.4/950-0174-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch
index 74d03540ad..74d03540ad 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0176-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0174-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0177-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0175-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch
index 2093cf05cc..2093cf05cc 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0177-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0175-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0178-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch b/target/linux/bcm27xx/patches-5.4/950-0176-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch
index 5c64238741..5c64238741 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0178-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0176-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0179-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch b/target/linux/bcm27xx/patches-5.4/950-0177-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch
index c8acb1a378..c8acb1a378 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0179-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0177-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0180-media-ov5647-Use-gpiod_set_value_cansleep.patch b/target/linux/bcm27xx/patches-5.4/950-0178-media-ov5647-Use-gpiod_set_value_cansleep.patch
index d141349f98..d141349f98 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0180-media-ov5647-Use-gpiod_set_value_cansleep.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0178-media-ov5647-Use-gpiod_set_value_cansleep.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0181-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch b/target/linux/bcm27xx/patches-5.4/950-0179-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch
index ecb867ba89..ecb867ba89 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0181-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0179-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0182-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch b/target/linux/bcm27xx/patches-5.4/950-0180-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch
index bfda5a48c9..bfda5a48c9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0182-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0180-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0183-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch b/target/linux/bcm27xx/patches-5.4/950-0181-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch
index 715061a917..715061a917 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0183-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0181-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0184-staging-mmal-vchiq-Always-return-the-param-size-from.patch b/target/linux/bcm27xx/patches-5.4/950-0182-staging-mmal-vchiq-Always-return-the-param-size-from.patch
index a8c8aebe1c..a8c8aebe1c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0184-staging-mmal-vchiq-Always-return-the-param-size-from.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0182-staging-mmal-vchiq-Always-return-the-param-size-from.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0185-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch b/target/linux/bcm27xx/patches-5.4/950-0183-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch
index 60550ede00..60550ede00 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0185-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0183-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0186-staging-bcm2835_codec-Query-supported-formats-from-t.patch b/target/linux/bcm27xx/patches-5.4/950-0184-staging-bcm2835_codec-Query-supported-formats-from-t.patch
index 00c3837c3c..00c3837c3c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0186-staging-bcm2835_codec-Query-supported-formats-from-t.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0184-staging-bcm2835_codec-Query-supported-formats-from-t.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0187-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch b/target/linux/bcm27xx/patches-5.4/950-0185-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch
index 3bbe6814c3..3bbe6814c3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0187-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0185-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0188-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch b/target/linux/bcm27xx/patches-5.4/950-0186-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch
index 911612621c..911612621c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0188-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0186-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0189-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch b/target/linux/bcm27xx/patches-5.4/950-0187-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch
index f2aeb91620..f2aeb91620 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0189-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0187-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0190-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch b/target/linux/bcm27xx/patches-5.4/950-0188-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch
index 1198880531..1198880531 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0190-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0188-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0191-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch b/target/linux/bcm27xx/patches-5.4/950-0189-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch
index b552698797..b552698797 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0191-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0189-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0192-staging-bcm2835-codec-NULL-component-handle-on-queue.patch b/target/linux/bcm27xx/patches-5.4/950-0190-staging-bcm2835-codec-NULL-component-handle-on-queue.patch
index 45ba5acba0..45ba5acba0 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0192-staging-bcm2835-codec-NULL-component-handle-on-queue.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0190-staging-bcm2835-codec-NULL-component-handle-on-queue.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0193-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch b/target/linux/bcm27xx/patches-5.4/950-0191-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch
index 8b110ca42e..8b110ca42e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0193-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0191-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0194-staging-bcm2835-codec-Refactor-default-resolution-co.patch b/target/linux/bcm27xx/patches-5.4/950-0192-staging-bcm2835-codec-Refactor-default-resolution-co.patch
index 42ab46c1c4..42ab46c1c4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0194-staging-bcm2835-codec-Refactor-default-resolution-co.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0192-staging-bcm2835-codec-Refactor-default-resolution-co.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0195-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch b/target/linux/bcm27xx/patches-5.4/950-0193-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch
index cf57c4cc5f..cf57c4cc5f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0195-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0193-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0196-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch b/target/linux/bcm27xx/patches-5.4/950-0194-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch
index 7a94ffa663..7a94ffa663 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0196-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0194-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0197-staging-mmal-vchiq-Free-the-event-context-for-contro.patch b/target/linux/bcm27xx/patches-5.4/950-0195-staging-mmal-vchiq-Free-the-event-context-for-contro.patch
index c510e64c47..c510e64c47 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0197-staging-mmal-vchiq-Free-the-event-context-for-contro.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0195-staging-mmal-vchiq-Free-the-event-context-for-contro.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0198-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch b/target/linux/bcm27xx/patches-5.4/950-0196-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch
index 6e846e4c7d..6e846e4c7d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0198-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0196-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0200-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch b/target/linux/bcm27xx/patches-5.4/950-0197-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch
index 481ca484d5..481ca484d5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0200-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0197-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0201-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch b/target/linux/bcm27xx/patches-5.4/950-0198-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch
index dca6c2402b..dca6c2402b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0201-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0198-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0199-Bluetooth-Check-key-sizes-only-when-Secure-Simple-Pa.patch b/target/linux/bcm27xx/patches-5.4/950-0199-Bluetooth-Check-key-sizes-only-when-Secure-Simple-Pa.patch
deleted file mode 100644
index 0de55097c5..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0199-Bluetooth-Check-key-sizes-only-when-Secure-Simple-Pa.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 3e2981c7e55d75dc93a2f2e9bb6be2b9704c05f5 Mon Sep 17 00:00:00 2001
-From: Marcel Holtmann <marcel@holtmann.org>
-Date: Wed, 22 May 2019 09:05:40 +0200
-Subject: [PATCH] Bluetooth: Check key sizes only when Secure Simple
- Pairing is enabled
-
-The encryption is only mandatory to be enforced when both sides are using
-Secure Simple Pairing and this means the key size check makes only sense
-in that case.
-
-On legacy Bluetooth 2.0 and earlier devices like mice the encryption was
-optional and thus causing an issue if the key size check is not bound to
-using Secure Simple Pairing.
-
-Fixes: d5bb334a8e17 ("Bluetooth: Align minimum encryption key size for LE and BR/EDR connections")
-Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-Cc: stable@vger.kernel.org
----
- net/bluetooth/hci_conn.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
-
---- a/net/bluetooth/hci_conn.c
-+++ b/net/bluetooth/hci_conn.c
-@@ -1302,8 +1302,13 @@ int hci_conn_check_link_mode(struct hci_
- return 0;
- }
-
-- if (hci_conn_ssp_enabled(conn) &&
-- !test_bit(HCI_CONN_ENCRYPT, &conn->flags))
-+ /* If Secure Simple Pairing is not enabled, then legacy connection
-+ * setup is used and no encryption or key sizes can be enforced.
-+ */
-+ if (!hci_conn_ssp_enabled(conn))
-+ return 1;
-+
-+ if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
- return 0;
-
- return 1;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0202-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch b/target/linux/bcm27xx/patches-5.4/950-0199-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch
index c8d656a1cf..c8d656a1cf 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0202-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0199-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0203-arm-bcm2835-Fix-FIQ-early-ioremap.patch b/target/linux/bcm27xx/patches-5.4/950-0200-arm-bcm2835-Fix-FIQ-early-ioremap.patch
index 1521476de1..1521476de1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0203-arm-bcm2835-Fix-FIQ-early-ioremap.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0200-arm-bcm2835-Fix-FIQ-early-ioremap.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0204-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch b/target/linux/bcm27xx/patches-5.4/950-0201-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch
index fc6efceacd..fc6efceacd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0204-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0201-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0205-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch b/target/linux/bcm27xx/patches-5.4/950-0202-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch
index d4ff3165b3..d4ff3165b3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0205-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0202-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0206-arm-bcm2835-DMA-can-only-address-1GB.patch b/target/linux/bcm27xx/patches-5.4/950-0203-arm-bcm2835-DMA-can-only-address-1GB.patch
index 86ad707b95..86ad707b95 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0206-arm-bcm2835-DMA-can-only-address-1GB.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0203-arm-bcm2835-DMA-can-only-address-1GB.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0207-hwrng-iproc-rng200-Add-BCM2838-support.patch b/target/linux/bcm27xx/patches-5.4/950-0204-hwrng-iproc-rng200-Add-BCM2838-support.patch
index c9eac88066..c9eac88066 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0207-hwrng-iproc-rng200-Add-BCM2838-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0204-hwrng-iproc-rng200-Add-BCM2838-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0208-vchiq-Add-36-bit-address-support.patch b/target/linux/bcm27xx/patches-5.4/950-0205-vchiq-Add-36-bit-address-support.patch
index ca2a40488a..ca2a40488a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0208-vchiq-Add-36-bit-address-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0205-vchiq-Add-36-bit-address-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0209-bcm2835-pcm.c-Support-multichannel-audio.patch b/target/linux/bcm27xx/patches-5.4/950-0206-bcm2835-pcm.c-Support-multichannel-audio.patch
index 133d346afb..133d346afb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0209-bcm2835-pcm.c-Support-multichannel-audio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0206-bcm2835-pcm.c-Support-multichannel-audio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0210-bcmgenet-constrain-max-DMA-burst-length.patch b/target/linux/bcm27xx/patches-5.4/950-0207-bcmgenet-constrain-max-DMA-burst-length.patch
index 5f683b506b..5f683b506b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0210-bcmgenet-constrain-max-DMA-burst-length.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0207-bcmgenet-constrain-max-DMA-burst-length.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0211-bcmgenet-Better-coalescing-parameter-defaults.patch b/target/linux/bcm27xx/patches-5.4/950-0208-bcmgenet-Better-coalescing-parameter-defaults.patch
index 3a38f64436..3a38f64436 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0211-bcmgenet-Better-coalescing-parameter-defaults.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0208-bcmgenet-Better-coalescing-parameter-defaults.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0212-net-genet-enable-link-energy-detect-powerdown-for-ex.patch b/target/linux/bcm27xx/patches-5.4/950-0209-net-genet-enable-link-energy-detect-powerdown-for-ex.patch
index ab43dfdfe5..ab43dfdfe5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0212-net-genet-enable-link-energy-detect-powerdown-for-ex.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0209-net-genet-enable-link-energy-detect-powerdown-for-ex.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0213-usb-xhci-Disable-the-XHCI-5-second-timeout.patch b/target/linux/bcm27xx/patches-5.4/950-0210-usb-xhci-Disable-the-XHCI-5-second-timeout.patch
index 2f5e08b7a2..2f5e08b7a2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0213-usb-xhci-Disable-the-XHCI-5-second-timeout.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0210-usb-xhci-Disable-the-XHCI-5-second-timeout.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0214-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch b/target/linux/bcm27xx/patches-5.4/950-0211-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch
index b2a8279da2..b2a8279da2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0214-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0211-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0212-spi-bcm2835-enable-shared-interrupt-support.patch b/target/linux/bcm27xx/patches-5.4/950-0212-spi-bcm2835-enable-shared-interrupt-support.patch
new file mode 100644
index 0000000000..f82ae7d9f6
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0212-spi-bcm2835-enable-shared-interrupt-support.patch
@@ -0,0 +1,35 @@
+From ac94635b678715af00a685ada0a1b60dfb54c771 Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Mon, 13 May 2019 11:05:27 +0000
+Subject: [PATCH] spi: bcm2835: enable shared interrupt support
+
+Add shared interrupt support for this driver.
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+---
+ drivers/spi/spi-bcm2835.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -379,6 +379,10 @@ static irqreturn_t bcm2835_spi_interrupt
+ if (bs->tx_len && cs & BCM2835_SPI_CS_DONE)
+ bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE);
+
++ /* check if we got interrupt enabled */
++ if (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_INTR))
++ return IRQ_NONE;
++
+ /* Read as many bytes as possible from FIFO */
+ bcm2835_rd_fifo(bs);
+ /* Write as many bytes as possible to FIFO */
+@@ -1281,7 +1285,8 @@ static int bcm2835_spi_probe(struct plat
+ bcm2835_wr(bs, BCM2835_SPI_CS,
+ BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX);
+
+- err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0,
++ err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt,
++ IRQF_SHARED,
+ dev_name(&pdev->dev), ctlr);
+ if (err) {
+ dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0216-clk-bcm2835-Don-t-wait-for-pllh-lock.patch b/target/linux/bcm27xx/patches-5.4/950-0213-clk-bcm2835-Don-t-wait-for-pllh-lock.patch
index 77625e8e23..77625e8e23 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0216-clk-bcm2835-Don-t-wait-for-pllh-lock.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0213-clk-bcm2835-Don-t-wait-for-pllh-lock.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0217-soc-bcm-bcm2835-pm-Add-support-for-2711.patch b/target/linux/bcm27xx/patches-5.4/950-0214-soc-bcm-bcm2835-pm-Add-support-for-2711.patch
index 61bf911f28..61bf911f28 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0217-soc-bcm-bcm2835-pm-Add-support-for-2711.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0214-soc-bcm-bcm2835-pm-Add-support-for-2711.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0218-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch b/target/linux/bcm27xx/patches-5.4/950-0215-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch
index 4e3805d9a7..4e3805d9a7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0218-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0215-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0215-spi-bcm2835-enable-shared-interrupt-support.patch b/target/linux/bcm27xx/patches-5.4/950-0215-spi-bcm2835-enable-shared-interrupt-support.patch
deleted file mode 100644
index 35a4e71245..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0215-spi-bcm2835-enable-shared-interrupt-support.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From ac94635b678715af00a685ada0a1b60dfb54c771 Mon Sep 17 00:00:00 2001
-From: Martin Sperl <kernel@martin.sperl.org>
-Date: Mon, 13 May 2019 11:05:27 +0000
-Subject: [PATCH] spi: bcm2835: enable shared interrupt support
-
-Add shared interrupt support for this driver.
-
-Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
----
- drivers/spi/spi-bcm2835.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
---- a/drivers/spi/spi-bcm2835.c
-+++ b/drivers/spi/spi-bcm2835.c
-@@ -379,6 +379,10 @@ static irqreturn_t bcm2835_spi_interrupt
- if (bs->tx_len && cs & BCM2835_SPI_CS_DONE)
- bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE);
-
-+ /* check if we got interrupt enabled */
-+ if (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_INTR))
-+ return IRQ_NONE;
-+
- /* Read as many bytes as possible from FIFO */
- bcm2835_rd_fifo(bs);
- /* Write as many bytes as possible to FIFO */
-@@ -1330,7 +1334,8 @@ static int bcm2835_spi_probe(struct plat
- bcm2835_wr(bs, BCM2835_SPI_CS,
- BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX);
-
-- err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0,
-+ err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt,
-+ IRQF_SHARED,
- dev_name(&pdev->dev), ctlr);
- if (err) {
- dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0219-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch b/target/linux/bcm27xx/patches-5.4/950-0216-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch
index 3227f8c914..3227f8c914 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0219-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0216-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0220-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch b/target/linux/bcm27xx/patches-5.4/950-0217-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch
index bae0f84e1a..bae0f84e1a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0220-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0217-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0221-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch b/target/linux/bcm27xx/patches-5.4/950-0218-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch
index 127e91cd24..127e91cd24 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0221-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0218-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0222-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch b/target/linux/bcm27xx/patches-5.4/950-0219-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch
index 5c241536dd..5c241536dd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0222-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0219-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0223-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch b/target/linux/bcm27xx/patches-5.4/950-0220-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch
index bf88c40780..bf88c40780 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0223-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0220-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0224-arm-bcm2835-Add-bcm2838-compatible-string.patch b/target/linux/bcm27xx/patches-5.4/950-0221-arm-bcm2835-Add-bcm2838-compatible-string.patch
index f11ccb44e9..f11ccb44e9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0224-arm-bcm2835-Add-bcm2838-compatible-string.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0221-arm-bcm2835-Add-bcm2838-compatible-string.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0225-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch b/target/linux/bcm27xx/patches-5.4/950-0222-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch
index f95c8778a6..f95c8778a6 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0225-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0222-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0226-drm-v3d-Add-support-for-2711.patch b/target/linux/bcm27xx/patches-5.4/950-0223-drm-v3d-Add-support-for-2711.patch
index 328c303083..328c303083 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0226-drm-v3d-Add-support-for-2711.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0223-drm-v3d-Add-support-for-2711.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0227-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch b/target/linux/bcm27xx/patches-5.4/950-0224-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch
index 1581cc0070..1581cc0070 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0227-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0224-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0228-drm-v3d-Hook-up-the-runtime-PM-ops.patch b/target/linux/bcm27xx/patches-5.4/950-0225-drm-v3d-Hook-up-the-runtime-PM-ops.patch
index 438922177d..438922177d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0228-drm-v3d-Hook-up-the-runtime-PM-ops.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0225-drm-v3d-Hook-up-the-runtime-PM-ops.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0229-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch b/target/linux/bcm27xx/patches-5.4/950-0226-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch
index ccd6de065c..ccd6de065c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0229-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0226-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch b/target/linux/bcm27xx/patches-5.4/950-0227-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch
index cb5b6d5aa7..cb5b6d5aa7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0227-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0231-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch b/target/linux/bcm27xx/patches-5.4/950-0228-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch
index 3b03c98088..3b03c98088 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0231-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0228-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0232-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch b/target/linux/bcm27xx/patches-5.4/950-0229-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch
index fc84f535de..fc84f535de 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0232-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0229-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0233-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch b/target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch
index 6878a0c26a..6878a0c26a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0233-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Increase-max-screen-size-to-4096x4096.patch b/target/linux/bcm27xx/patches-5.4/950-0231-drm-vc4-Increase-max-screen-size-to-4096x4096.patch
index 92d3d35ead..92d3d35ead 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Increase-max-screen-size-to-4096x4096.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0231-drm-vc4-Increase-max-screen-size-to-4096x4096.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch b/target/linux/bcm27xx/patches-5.4/950-0232-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch
index cbba43bf2e..cbba43bf2e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0232-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Fix-build-warning.patch b/target/linux/bcm27xx/patches-5.4/950-0233-drm-vc4-Fix-build-warning.patch
index 63246286a2..63246286a2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Fix-build-warning.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0233-drm-vc4-Fix-build-warning.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0237-drm-vc4-Select-display-to-blank-during-initialisatio.patch b/target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Select-display-to-blank-during-initialisatio.patch
index 693292d04f..693292d04f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0237-drm-vc4-Select-display-to-blank-during-initialisatio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Select-display-to-blank-during-initialisatio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Remove-now-unused-structure.patch b/target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Remove-now-unused-structure.patch
index e6e4950e9a..e6e4950e9a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Remove-now-unused-structure.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Remove-now-unused-structure.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch b/target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch
index 6e463e70eb..6e463e70eb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Set-the-display-number-when-querying-the-dis.patch b/target/linux/bcm27xx/patches-5.4/950-0237-drm-vc4-Set-the-display-number-when-querying-the-dis.patch
index 7b8efc7e73..7b8efc7e73 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Set-the-display-number-when-querying-the-dis.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0237-drm-vc4-Set-the-display-number-when-querying-the-dis.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch b/target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch
index 635340c082..635340c082 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch b/target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch
index 43a2ffab16..43a2ffab16 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch b/target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch
index 6740f7fc6e..6740f7fc6e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch b/target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch
index 05f50cd913..05f50cd913 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch b/target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch
index 10a655ade1..10a655ade1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Increase-max_width-height-to-7680.patch b/target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Increase-max_width-height-to-7680.patch
index 69d1470663..69d1470663 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Increase-max_width-height-to-7680.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Increase-max_width-height-to-7680.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch b/target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch
index 92400560ac..92400560ac 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch b/target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch
index 2a365798f5..2a365798f5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-Log-flags-in-fkms-mode-set.patch b/target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Log-flags-in-fkms-mode-set.patch
index caca1c9f82..caca1c9f82 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-Log-flags-in-fkms-mode-set.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Log-flags-in-fkms-mode-set.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-firmware-kms-Fix-DSI-display-support.patch b/target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-firmware-kms-Fix-DSI-display-support.patch
index 450c156602..450c156602 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-firmware-kms-Fix-DSI-display-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-firmware-kms-Fix-DSI-display-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch b/target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch
index a917540869..a917540869 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-handle-the-case-where-there-are-no-available.patch b/target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-handle-the-case-where-there-are-no-available.patch
index 72b205c2e4..72b205c2e4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-handle-the-case-where-there-are-no-available.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-handle-the-case-where-there-are-no-available.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-Support-the-VEC-in-FKMS.patch b/target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-Support-the-VEC-in-FKMS.patch
index 87aeacd616..87aeacd616 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-Support-the-VEC-in-FKMS.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-Support-the-VEC-in-FKMS.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch b/target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch
index 8008619639..8008619639 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-Correct-SAND-support-for-FKMS.patch b/target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-Correct-SAND-support-for-FKMS.patch
index dcf57e07e7..dcf57e07e7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-Correct-SAND-support-for-FKMS.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-Correct-SAND-support-for-FKMS.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch b/target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch
index 186a7c891f..186a7c891f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch b/target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch
index 63931bf611..63931bf611 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch b/target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch
index 5d6171ce40..5d6171ce40 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch b/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch
index 06e073b2ea..06e073b2ea 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Add-status-of-which-display-is-updated-throu.patch b/target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-Add-status-of-which-display-is-updated-throu.patch
index 8dd4caad1c..8dd4caad1c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Add-status-of-which-display-is-updated-throu.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-Add-status-of-which-display-is-updated-throu.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch b/target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch
index 38b12e049f..38b12e049f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-Limit-fkms-to-modes-85Hz.patch b/target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Limit-fkms-to-modes-85Hz.patch
index 128ac5d54b..128ac5d54b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-Limit-fkms-to-modes-85Hz.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Limit-fkms-to-modes-85Hz.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0263-drm-vc4-Ignore-HVS-unless-initialised.patch b/target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Ignore-HVS-unless-initialised.patch
index f17f4be37d..f17f4be37d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0263-drm-vc4-Ignore-HVS-unless-initialised.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Ignore-HVS-unless-initialised.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0264-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch b/target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch
index 9fd796850f..9fd796850f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0264-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0265-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch b/target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch
index 619eb811cd..619eb811cd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0265-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0266-tty-amba-pl011-Make-TX-optimisation-conditional.patch b/target/linux/bcm27xx/patches-5.4/950-0263-tty-amba-pl011-Make-TX-optimisation-conditional.patch
index 58829c9e92..58829c9e92 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0266-tty-amba-pl011-Make-TX-optimisation-conditional.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0263-tty-amba-pl011-Make-TX-optimisation-conditional.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0267-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch b/target/linux/bcm27xx/patches-5.4/950-0264-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch
index a125fdcb47..a125fdcb47 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0267-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0264-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0268-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch b/target/linux/bcm27xx/patches-5.4/950-0265-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch
index a3bc6c91b6..a3bc6c91b6 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0268-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0265-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0269-staging-vc04_services-fix-compiling-in-separate-dire.patch b/target/linux/bcm27xx/patches-5.4/950-0266-staging-vc04_services-fix-compiling-in-separate-dire.patch
index b3d57dc2b3..b3d57dc2b3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0269-staging-vc04_services-fix-compiling-in-separate-dire.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0266-staging-vc04_services-fix-compiling-in-separate-dire.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0270-clk-bcm2835-Avoid-null-pointer-exception.patch b/target/linux/bcm27xx/patches-5.4/950-0267-clk-bcm2835-Avoid-null-pointer-exception.patch
index 8a529af7b0..8a529af7b0 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0270-clk-bcm2835-Avoid-null-pointer-exception.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0267-clk-bcm2835-Avoid-null-pointer-exception.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0271-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch b/target/linux/bcm27xx/patches-5.4/950-0268-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch
index e4f178d0a2..e4f178d0a2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0271-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0268-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0272-drm-v3d-HACK-gut-runtime-pm-for-now.patch b/target/linux/bcm27xx/patches-5.4/950-0269-drm-v3d-HACK-gut-runtime-pm-for-now.patch
index ed69f2d157..ed69f2d157 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0272-drm-v3d-HACK-gut-runtime-pm-for-now.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0269-drm-v3d-HACK-gut-runtime-pm-for-now.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0273-drm-v3d-Clock-V3D-down-when-not-in-use.patch b/target/linux/bcm27xx/patches-5.4/950-0270-drm-v3d-Clock-V3D-down-when-not-in-use.patch
index 782cc197d5..782cc197d5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0273-drm-v3d-Clock-V3D-down-when-not-in-use.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0270-drm-v3d-Clock-V3D-down-when-not-in-use.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0274-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch b/target/linux/bcm27xx/patches-5.4/950-0271-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch
index 267725d3ef..267725d3ef 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0274-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0271-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0275-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch b/target/linux/bcm27xx/patches-5.4/950-0272-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch
index b5358cef29..b5358cef29 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0275-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0272-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0276-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch b/target/linux/bcm27xx/patches-5.4/950-0273-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch
index ce73e34541..ce73e34541 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0276-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0273-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0277-drm-vc4-Add-support-for-margins-to-fkms.patch b/target/linux/bcm27xx/patches-5.4/950-0274-drm-vc4-Add-support-for-margins-to-fkms.patch
index 968eb3ff55..968eb3ff55 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0277-drm-vc4-Add-support-for-margins-to-fkms.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0274-drm-vc4-Add-support-for-margins-to-fkms.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0278-drm-vc4-Ensure-zpos-is-always-initialised.patch b/target/linux/bcm27xx/patches-5.4/950-0275-drm-vc4-Ensure-zpos-is-always-initialised.patch
index 32a13d9c86..32a13d9c86 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0278-drm-vc4-Ensure-zpos-is-always-initialised.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0275-drm-vc4-Ensure-zpos-is-always-initialised.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0279-adds-the-Hifiberry-DAC-ADC-PRO-version.patch b/target/linux/bcm27xx/patches-5.4/950-0276-adds-the-Hifiberry-DAC-ADC-PRO-version.patch
index ed6d6db813..ed6d6db813 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0279-adds-the-Hifiberry-DAC-ADC-PRO-version.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0276-adds-the-Hifiberry-DAC-ADC-PRO-version.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0280-drm-vc4-A-present-but-empty-dmas-disables-audio.patch b/target/linux/bcm27xx/patches-5.4/950-0277-drm-vc4-A-present-but-empty-dmas-disables-audio.patch
index b0c5b969f2..b0c5b969f2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0280-drm-vc4-A-present-but-empty-dmas-disables-audio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0277-drm-vc4-A-present-but-empty-dmas-disables-audio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0281-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch b/target/linux/bcm27xx/patches-5.4/950-0278-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch
index 60c9c9b03f..60c9c9b03f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0281-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0278-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0282-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch b/target/linux/bcm27xx/patches-5.4/950-0279-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch
index 3f3c5ea148..3f3c5ea148 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0282-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0279-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0283-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch b/target/linux/bcm27xx/patches-5.4/950-0280-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch
index ee886e31a5..ee886e31a5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0283-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0280-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0284-drm-vc4-Add-Broadcast-RGB-connector-property.patch b/target/linux/bcm27xx/patches-5.4/950-0281-drm-vc4-Add-Broadcast-RGB-connector-property.patch
index e221e41189..e221e41189 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0284-drm-vc4-Add-Broadcast-RGB-connector-property.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0281-drm-vc4-Add-Broadcast-RGB-connector-property.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0285-drm-vc4-fkms-Set-default-state-margin-at-reset.patch b/target/linux/bcm27xx/patches-5.4/950-0282-drm-vc4-fkms-Set-default-state-margin-at-reset.patch
index 51664f3f98..51664f3f98 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0285-drm-vc4-fkms-Set-default-state-margin-at-reset.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0282-drm-vc4-fkms-Set-default-state-margin-at-reset.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0286-staging-bcm2835-codec-switch-to-multi-planar-API.patch b/target/linux/bcm27xx/patches-5.4/950-0283-staging-bcm2835-codec-switch-to-multi-planar-API.patch
index c4eab3a02a..c4eab3a02a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0286-staging-bcm2835-codec-switch-to-multi-planar-API.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0283-staging-bcm2835-codec-switch-to-multi-planar-API.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0287-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch b/target/linux/bcm27xx/patches-5.4/950-0284-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch
index 6e4af3e38d..6e4af3e38d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0287-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0284-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0288-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch b/target/linux/bcm27xx/patches-5.4/950-0285-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch
index a194eaba14..a194eaba14 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0288-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0285-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0289-Add-HDMI1-facility-to-the-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0286-Add-HDMI1-facility-to-the-driver.patch
index b18d1458fd..b18d1458fd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0289-Add-HDMI1-facility-to-the-driver.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0286-Add-HDMI1-facility-to-the-driver.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0290-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch b/target/linux/bcm27xx/patches-5.4/950-0287-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch
index e50bdee8ae..e50bdee8ae 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0290-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0287-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0291-drm-vc4-Remove-unused-mode-variable.patch b/target/linux/bcm27xx/patches-5.4/950-0288-drm-vc4-Remove-unused-mode-variable.patch
index e82fc421d2..e82fc421d2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0291-drm-vc4-Remove-unused-mode-variable.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0288-drm-vc4-Remove-unused-mode-variable.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0292-staging-bcm2835-codec-Expand-logging-on-format-setti.patch b/target/linux/bcm27xx/patches-5.4/950-0289-staging-bcm2835-codec-Expand-logging-on-format-setti.patch
index d2ebeea7f7..d2ebeea7f7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0292-staging-bcm2835-codec-Expand-logging-on-format-setti.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0289-staging-bcm2835-codec-Expand-logging-on-format-setti.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0293-staging-bcm2835-codec-Correct-bytesperline-on-format.patch b/target/linux/bcm27xx/patches-5.4/950-0290-staging-bcm2835-codec-Correct-bytesperline-on-format.patch
index eaba48466a..eaba48466a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0293-staging-bcm2835-codec-Correct-bytesperline-on-format.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0290-staging-bcm2835-codec-Correct-bytesperline-on-format.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0294-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch b/target/linux/bcm27xx/patches-5.4/950-0291-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch
index f29ba4dc5d..f29ba4dc5d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0294-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0291-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0295-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch b/target/linux/bcm27xx/patches-5.4/950-0292-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch
index db1866d6e7..db1866d6e7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0295-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0292-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0296-xhci-Use-more-event-ring-segment-table-entries.patch b/target/linux/bcm27xx/patches-5.4/950-0293-xhci-Use-more-event-ring-segment-table-entries.patch
index 4b4766f739..4b4766f739 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0296-xhci-Use-more-event-ring-segment-table-entries.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0293-xhci-Use-more-event-ring-segment-table-entries.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0297-configs-arm64-bcm2711-Enable-V3D.patch b/target/linux/bcm27xx/patches-5.4/950-0294-configs-arm64-bcm2711-Enable-V3D.patch
index f079fcf9ac..f079fcf9ac 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0297-configs-arm64-bcm2711-Enable-V3D.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0294-configs-arm64-bcm2711-Enable-V3D.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0298-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch b/target/linux/bcm27xx/patches-5.4/950-0295-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch
index 42baf4c7d4..42baf4c7d4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0298-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0295-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0299-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch b/target/linux/bcm27xx/patches-5.4/950-0296-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch
index d2a50860d2..d2a50860d2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0299-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0296-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0300-arch-arm-Add-model-string-to-cpuinfo.patch b/target/linux/bcm27xx/patches-5.4/950-0297-arch-arm-Add-model-string-to-cpuinfo.patch
index 83c1592df9..83c1592df9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0300-arch-arm-Add-model-string-to-cpuinfo.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0297-arch-arm-Add-model-string-to-cpuinfo.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0301-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch b/target/linux/bcm27xx/patches-5.4/950-0298-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch
index af76b81f31..af76b81f31 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0301-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0298-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0302-staging-bcm2835-codec-Fix-non-documentation-comment-.patch b/target/linux/bcm27xx/patches-5.4/950-0299-staging-bcm2835-codec-Fix-non-documentation-comment-.patch
index e1ec7d9e69..e1ec7d9e69 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0302-staging-bcm2835-codec-Fix-non-documentation-comment-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0299-staging-bcm2835-codec-Fix-non-documentation-comment-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0303-staging-bcm2835-codec-Fix-declaration-of-roles.patch b/target/linux/bcm27xx/patches-5.4/950-0300-staging-bcm2835-codec-Fix-declaration-of-roles.patch
index 6e544199ba..6e544199ba 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0303-staging-bcm2835-codec-Fix-declaration-of-roles.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0300-staging-bcm2835-codec-Fix-declaration-of-roles.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0304-staging-bcm2835-codec-Add-role-to-device-name.patch b/target/linux/bcm27xx/patches-5.4/950-0301-staging-bcm2835-codec-Add-role-to-device-name.patch
index e1539f4a71..e1539f4a71 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0304-staging-bcm2835-codec-Add-role-to-device-name.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0301-staging-bcm2835-codec-Add-role-to-device-name.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0305-staging-bcm2835-codec-Pass-driver-context-to-create-.patch b/target/linux/bcm27xx/patches-5.4/950-0302-staging-bcm2835-codec-Pass-driver-context-to-create-.patch
index a0b86db2d6..a0b86db2d6 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0305-staging-bcm2835-codec-Pass-driver-context-to-create-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0302-staging-bcm2835-codec-Pass-driver-context-to-create-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0306-staging-bcm2835-codec-add-media-controller-support.patch b/target/linux/bcm27xx/patches-5.4/950-0303-staging-bcm2835-codec-add-media-controller-support.patch
index f0ac32340c..f0ac32340c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0306-staging-bcm2835-codec-add-media-controller-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0303-staging-bcm2835-codec-add-media-controller-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0307-v4l2-Add-a-Greyworld-AWB-mode.patch b/target/linux/bcm27xx/patches-5.4/950-0304-v4l2-Add-a-Greyworld-AWB-mode.patch
index 459646e7e7..459646e7e7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0307-v4l2-Add-a-Greyworld-AWB-mode.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0304-v4l2-Add-a-Greyworld-AWB-mode.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0308-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch b/target/linux/bcm27xx/patches-5.4/950-0305-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch
index e29c3800c4..e29c3800c4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0308-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0305-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0309-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch b/target/linux/bcm27xx/patches-5.4/950-0306-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch
index f6391e0b96..f6391e0b96 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0309-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0306-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0310-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch b/target/linux/bcm27xx/patches-5.4/950-0307-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch
index 5855d0057b..5855d0057b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0310-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0307-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0311-staging-bcm2835-codec-Allow-height-of-1920.patch b/target/linux/bcm27xx/patches-5.4/950-0308-staging-bcm2835-codec-Allow-height-of-1920.patch
index 862737f383..862737f383 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0311-staging-bcm2835-codec-Allow-height-of-1920.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0308-staging-bcm2835-codec-Allow-height-of-1920.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0312-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch b/target/linux/bcm27xx/patches-5.4/950-0309-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch
index a91bcc3111..a91bcc3111 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0312-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0309-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0313-drm-v3d-Delete-pm_runtime-support.patch b/target/linux/bcm27xx/patches-5.4/950-0310-drm-v3d-Delete-pm_runtime-support.patch
index 642be233ad..642be233ad 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0313-drm-v3d-Delete-pm_runtime-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0310-drm-v3d-Delete-pm_runtime-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0314-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch b/target/linux/bcm27xx/patches-5.4/950-0311-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch
index c7eccdeed4..c7eccdeed4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0314-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0311-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0315-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch b/target/linux/bcm27xx/patches-5.4/950-0312-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch
index 961c0cc92b..961c0cc92b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0315-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0312-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0316-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch b/target/linux/bcm27xx/patches-5.4/950-0313-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch
index d36f3eb802..d36f3eb802 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0316-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0313-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0317-dma-direct-Temporary-DMA-fix-on-arm64.patch b/target/linux/bcm27xx/patches-5.4/950-0314-dma-direct-Temporary-DMA-fix-on-arm64.patch
index 327a77c424..327a77c424 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0317-dma-direct-Temporary-DMA-fix-on-arm64.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0314-dma-direct-Temporary-DMA-fix-on-arm64.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0318-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch b/target/linux/bcm27xx/patches-5.4/950-0315-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch
index 254a621c83..254a621c83 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0318-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0315-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0319-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch b/target/linux/bcm27xx/patches-5.4/950-0316-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch
index 2ad17cb17c..2ad17cb17c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0319-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0316-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0320-vchiq_2835_arm-suppress-warning.patch b/target/linux/bcm27xx/patches-5.4/950-0317-vchiq_2835_arm-suppress-warning.patch
index 1be935caf4..1be935caf4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0320-vchiq_2835_arm-suppress-warning.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0317-vchiq_2835_arm-suppress-warning.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0321-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch b/target/linux/bcm27xx/patches-5.4/950-0318-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch
index 8ec836621d..8ec836621d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0321-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0318-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0322-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch b/target/linux/bcm27xx/patches-5.4/950-0319-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch
index d7e6bbc561..d7e6bbc561 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0322-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0319-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0323-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch b/target/linux/bcm27xx/patches-5.4/950-0320-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch
index f98002e99c..f98002e99c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0323-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0320-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0324-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch b/target/linux/bcm27xx/patches-5.4/950-0321-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch
index 6f487bf7c6..6f487bf7c6 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0324-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0321-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0325-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch b/target/linux/bcm27xx/patches-5.4/950-0322-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch
index 71e218d9ec..71e218d9ec 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0325-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0322-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0326-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch b/target/linux/bcm27xx/patches-5.4/950-0323-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch
index ab3a971608..ab3a971608 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0326-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0323-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0327-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch b/target/linux/bcm27xx/patches-5.4/950-0324-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch
index fb60b16e56..fb60b16e56 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0327-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0324-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0328-staging-bcm2835-codec-Set-default-and-error-check-ti.patch b/target/linux/bcm27xx/patches-5.4/950-0325-staging-bcm2835-codec-Set-default-and-error-check-ti.patch
index 124b7ae742..124b7ae742 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0328-staging-bcm2835-codec-Set-default-and-error-check-ti.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0325-staging-bcm2835-codec-Set-default-and-error-check-ti.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0329-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch b/target/linux/bcm27xx/patches-5.4/950-0326-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch
index f0fdfd29c8..f0fdfd29c8 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0329-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0326-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0330-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch b/target/linux/bcm27xx/patches-5.4/950-0327-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch
index 812f69643f..812f69643f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0330-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0327-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0331-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch b/target/linux/bcm27xx/patches-5.4/950-0328-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch
index f2cf28433a..f2cf28433a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0331-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0328-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0332-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch b/target/linux/bcm27xx/patches-5.4/950-0329-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch
index a4a9dc817b..a4a9dc817b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0332-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0329-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0333-drm-v3d-Suppress-all-but-the-first-MMU-error.patch b/target/linux/bcm27xx/patches-5.4/950-0330-drm-v3d-Suppress-all-but-the-first-MMU-error.patch
index 58f3a44aff..58f3a44aff 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0333-drm-v3d-Suppress-all-but-the-first-MMU-error.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0330-drm-v3d-Suppress-all-but-the-first-MMU-error.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0334-drm-v3d-Plug-dma_fence-leak.patch b/target/linux/bcm27xx/patches-5.4/950-0331-drm-v3d-Plug-dma_fence-leak.patch
index a79912df1e..a79912df1e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0334-drm-v3d-Plug-dma_fence-leak.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0331-drm-v3d-Plug-dma_fence-leak.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0335-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch b/target/linux/bcm27xx/patches-5.4/950-0332-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch
index cf8d563c72..cf8d563c72 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0335-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0332-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0336-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch b/target/linux/bcm27xx/patches-5.4/950-0333-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch
index 9e1b777cac..9e1b777cac 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0336-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0333-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0337-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch b/target/linux/bcm27xx/patches-5.4/950-0334-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch
index 915ca1a29f..915ca1a29f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0337-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0334-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0339-net-bcmgenet-The-second-IRQ-is-optional.patch b/target/linux/bcm27xx/patches-5.4/950-0335-net-bcmgenet-The-second-IRQ-is-optional.patch
index d48e6948d3..d48e6948d3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0339-net-bcmgenet-The-second-IRQ-is-optional.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0335-net-bcmgenet-The-second-IRQ-is-optional.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0340-drm-v3d-The-third-IRQ-is-optional.patch b/target/linux/bcm27xx/patches-5.4/950-0336-drm-v3d-The-third-IRQ-is-optional.patch
index 97ff76a6a3..97ff76a6a3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0340-drm-v3d-The-third-IRQ-is-optional.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0336-drm-v3d-The-third-IRQ-is-optional.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0341-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch b/target/linux/bcm27xx/patches-5.4/950-0337-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch
index afd72da286..afd72da286 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0341-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0337-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0342-rpi-poe-fan-fix-def_pwm1-writes.patch b/target/linux/bcm27xx/patches-5.4/950-0338-rpi-poe-fan-fix-def_pwm1-writes.patch
index 8792d5954c..8792d5954c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0342-rpi-poe-fan-fix-def_pwm1-writes.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0338-rpi-poe-fan-fix-def_pwm1-writes.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0343-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch b/target/linux/bcm27xx/patches-5.4/950-0339-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch
index b3e237fdf5..b3e237fdf5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0343-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0339-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0344-overlays-smi-fix-typo-in-comment-3320.patch b/target/linux/bcm27xx/patches-5.4/950-0340-overlays-smi-fix-typo-in-comment-3320.patch
index 0a4f630a4c..0a4f630a4c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0344-overlays-smi-fix-typo-in-comment-3320.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0340-overlays-smi-fix-typo-in-comment-3320.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0345-net-phy-2711-Change-the-default-ethernet-LED-actions.patch b/target/linux/bcm27xx/patches-5.4/950-0341-net-phy-2711-Change-the-default-ethernet-LED-actions.patch
index d76fd0ec0d..d76fd0ec0d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0345-net-phy-2711-Change-the-default-ethernet-LED-actions.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0341-net-phy-2711-Change-the-default-ethernet-LED-actions.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0346-overlays-Add-apds9960-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0342-overlays-Add-apds9960-overlay.patch
index f0f5368076..f0f5368076 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0346-overlays-Add-apds9960-overlay.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0342-overlays-Add-apds9960-overlay.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0347-overlays-Remove-hack-from-uart0-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0343-overlays-Remove-hack-from-uart0-overlay.patch
index ac70b35413..ac70b35413 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0347-overlays-Remove-hack-from-uart0-overlay.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0343-overlays-Remove-hack-from-uart0-overlay.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0348-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch b/target/linux/bcm27xx/patches-5.4/950-0344-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch
index ba19abb895..ba19abb895 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0348-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0344-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0349-v3d_drv-Handle-missing-clock-more-gracefully.patch b/target/linux/bcm27xx/patches-5.4/950-0345-v3d_drv-Handle-missing-clock-more-gracefully.patch
index 812d6f1311..812d6f1311 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0349-v3d_drv-Handle-missing-clock-more-gracefully.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0345-v3d_drv-Handle-missing-clock-more-gracefully.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0350-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch b/target/linux/bcm27xx/patches-5.4/950-0346-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch
index 1892a145fa..1892a145fa 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0350-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0346-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0351-clk-bcm2835-Disable-v3d-clock.patch b/target/linux/bcm27xx/patches-5.4/950-0347-clk-bcm2835-Disable-v3d-clock.patch
index a7a5221fab..a7a5221fab 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0351-clk-bcm2835-Disable-v3d-clock.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0347-clk-bcm2835-Disable-v3d-clock.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0353-arm-dts-Correct-Pi-4B-LED-values.patch b/target/linux/bcm27xx/patches-5.4/950-0348-arm-dts-Correct-Pi-4B-LED-values.patch
index a3bae521e7..a3bae521e7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0353-arm-dts-Correct-Pi-4B-LED-values.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0348-arm-dts-Correct-Pi-4B-LED-values.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0354-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch b/target/linux/bcm27xx/patches-5.4/950-0349-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch
index 67cdd44f29..67cdd44f29 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0354-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0349-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0355-arm-dts-2711-Add-pcie0-alias.patch b/target/linux/bcm27xx/patches-5.4/950-0350-arm-dts-2711-Add-pcie0-alias.patch
index fa00fb1974..fa00fb1974 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0355-arm-dts-2711-Add-pcie0-alias.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0350-arm-dts-2711-Add-pcie0-alias.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0356-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch b/target/linux/bcm27xx/patches-5.4/950-0351-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch
index 61f49d5ae4..61f49d5ae4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0356-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0351-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0352-raspberrypi-cpufreq-Only-report-integer-pll-divisor-.patch b/target/linux/bcm27xx/patches-5.4/950-0352-raspberrypi-cpufreq-Only-report-integer-pll-divisor-.patch
deleted file mode 100644
index 192b13b69a..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0352-raspberrypi-cpufreq-Only-report-integer-pll-divisor-.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 814af1a008845b61a08111f2f9cf7e66511ab362 Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix@gmail.com>
-Date: Fri, 13 Sep 2019 13:45:11 +0100
-Subject: [PATCH] raspberrypi-cpufreq: Only report integer pll divisor
- frequencies
-
----
- drivers/cpufreq/raspberrypi-cpufreq.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
---- a/drivers/cpufreq/raspberrypi-cpufreq.c
-+++ b/drivers/cpufreq/raspberrypi-cpufreq.c
-@@ -8,6 +8,7 @@
- #include <linux/clk.h>
- #include <linux/cpu.h>
- #include <linux/cpufreq.h>
-+#include <linux/math64.h>
- #include <linux/module.h>
- #include <linux/platform_device.h>
- #include <linux/pm_opp.h>
-@@ -22,6 +23,7 @@ static int raspberrypi_cpufreq_probe(str
- unsigned long min, max;
- unsigned long rate;
- struct clk *clk;
-+ int div;
- int ret;
-
- cpu_dev = get_cpu_device(0);
-@@ -44,7 +46,10 @@ static int raspberrypi_cpufreq_probe(str
- max = roundup(clk_round_rate(clk, ULONG_MAX), RASPBERRYPI_FREQ_INTERVAL);
- clk_put(clk);
-
-- for (rate = min; rate <= max; rate += RASPBERRYPI_FREQ_INTERVAL) {
-+ for (div = 2; ; div++) {
-+ rate = div_u64((u64)max * 2, div);
-+ if (rate < min)
-+ break;
- ret = dev_pm_opp_add(cpu_dev, rate, 0);
- if (ret)
- goto remove_opp;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0357-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch b/target/linux/bcm27xx/patches-5.4/950-0352-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch
index 0a6660b893..0a6660b893 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0357-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0352-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0358-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch b/target/linux/bcm27xx/patches-5.4/950-0353-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch
index eb35a81023..eb35a81023 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0358-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0353-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0359-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch b/target/linux/bcm27xx/patches-5.4/950-0354-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch
index 3bc9abde27..3bc9abde27 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0359-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0354-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0360-overlays-Make-mcp342x-run-time-compatible.patch b/target/linux/bcm27xx/patches-5.4/950-0355-overlays-Make-mcp342x-run-time-compatible.patch
index 1b4809db0d..1b4809db0d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0360-overlays-Make-mcp342x-run-time-compatible.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0355-overlays-Make-mcp342x-run-time-compatible.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0361-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch b/target/linux/bcm27xx/patches-5.4/950-0356-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch
index e1ffd3b0b7..e1ffd3b0b7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0361-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0356-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0362-sound-soc-only-first-codec-is-master-in-multicodec-s.patch b/target/linux/bcm27xx/patches-5.4/950-0357-sound-soc-only-first-codec-is-master-in-multicodec-s.patch
index 263f3532f3..263f3532f3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0362-sound-soc-only-first-codec-is-master-in-multicodec-s.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0357-sound-soc-only-first-codec-is-master-in-multicodec-s.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0363-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch b/target/linux/bcm27xx/patches-5.4/950-0358-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch
index d0d1e28757..d0d1e28757 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0363-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0358-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0364-overlays-dht11-Allow-multiple-instantiation.patch b/target/linux/bcm27xx/patches-5.4/950-0359-overlays-dht11-Allow-multiple-instantiation.patch
index b75f1d4988..b75f1d4988 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0364-overlays-dht11-Allow-multiple-instantiation.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0359-overlays-dht11-Allow-multiple-instantiation.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0365-overlays-i2c-rtc-Add-pcf85363-support.patch b/target/linux/bcm27xx/patches-5.4/950-0360-overlays-i2c-rtc-Add-pcf85363-support.patch
index 93a699a66a..93a699a66a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0365-overlays-i2c-rtc-Add-pcf85363-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0360-overlays-i2c-rtc-Add-pcf85363-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0366-pinctrl-bcm2835-Remove-gpiochip-on-error.patch b/target/linux/bcm27xx/patches-5.4/950-0361-pinctrl-bcm2835-Remove-gpiochip-on-error.patch
index 31a1a24caf..31a1a24caf 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0366-pinctrl-bcm2835-Remove-gpiochip-on-error.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0361-pinctrl-bcm2835-Remove-gpiochip-on-error.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0367-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch b/target/linux/bcm27xx/patches-5.4/950-0362-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch
index 3865ae11fb..3865ae11fb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0367-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0362-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0368-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch b/target/linux/bcm27xx/patches-5.4/950-0363-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch
index 0221803993..0221803993 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0368-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0363-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0369-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0364-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch
index db90055343..db90055343 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0369-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0364-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0370-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch b/target/linux/bcm27xx/patches-5.4/950-0365-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch
index 3ececc8f92..3ececc8f92 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0370-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0365-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0371-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch b/target/linux/bcm27xx/patches-5.4/950-0366-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch
index 218a846fa3..218a846fa3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0371-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0366-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0372-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch b/target/linux/bcm27xx/patches-5.4/950-0367-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch
index 1acf84b7ce..1acf84b7ce 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0372-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0367-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0373-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch b/target/linux/bcm27xx/patches-5.4/950-0368-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch
index ce0b8811d0..ce0b8811d0 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0373-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0368-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0374-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch b/target/linux/bcm27xx/patches-5.4/950-0369-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch
index fb3a6a3806..fb3a6a3806 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0374-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0369-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0375-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch b/target/linux/bcm27xx/patches-5.4/950-0370-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch
index ef26293498..ef26293498 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0375-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0370-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0376-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch b/target/linux/bcm27xx/patches-5.4/950-0371-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch
index 0e2a78649f..0e2a78649f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0376-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0371-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0377-net-bcmgenet-Add-RGMII_RXID-support.patch b/target/linux/bcm27xx/patches-5.4/950-0372-net-bcmgenet-Add-RGMII_RXID-support.patch
index 0e13394c7f..0e13394c7f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0377-net-bcmgenet-Add-RGMII_RXID-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0372-net-bcmgenet-Add-RGMII_RXID-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0378-ARM-dts-bcm2838-Backport-genet-from-upstream.patch b/target/linux/bcm27xx/patches-5.4/950-0373-ARM-dts-bcm2838-Backport-genet-from-upstream.patch
index ffd7d8e540..ffd7d8e540 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0378-ARM-dts-bcm2838-Backport-genet-from-upstream.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0373-ARM-dts-bcm2838-Backport-genet-from-upstream.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0379-ARM-bcm-Backport-BCM2711-support-from-upstream.patch b/target/linux/bcm27xx/patches-5.4/950-0374-ARM-bcm-Backport-BCM2711-support-from-upstream.patch
index 8d16152154..8d16152154 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0379-ARM-bcm-Backport-BCM2711-support-from-upstream.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0374-ARM-bcm-Backport-BCM2711-support-from-upstream.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0380-hwrng-iproc-rng200-Add-support-for-BCM2711.patch b/target/linux/bcm27xx/patches-5.4/950-0375-hwrng-iproc-rng200-Add-support-for-BCM2711.patch
index 7a47128837..7a47128837 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0380-hwrng-iproc-rng200-Add-support-for-BCM2711.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0375-hwrng-iproc-rng200-Add-support-for-BCM2711.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0381-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch b/target/linux/bcm27xx/patches-5.4/950-0376-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch
index 2feda7389e..2feda7389e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0381-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0376-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0382-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch b/target/linux/bcm27xx/patches-5.4/950-0377-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch
index 49d885cd73..49d885cd73 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0382-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0377-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0383-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch b/target/linux/bcm27xx/patches-5.4/950-0378-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch
index b61e2c5cfe..b61e2c5cfe 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0383-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0378-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0384-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch b/target/linux/bcm27xx/patches-5.4/950-0379-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch
index 52aa87ed04..52aa87ed04 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0384-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0379-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0385-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch b/target/linux/bcm27xx/patches-5.4/950-0380-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch
index 26d0c9894b..26d0c9894b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0385-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0380-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0386-driver-char-rpimem-Add-SPDX-licence-header.patch b/target/linux/bcm27xx/patches-5.4/950-0381-driver-char-rpimem-Add-SPDX-licence-header.patch
index 86b9400ac6..86b9400ac6 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0386-driver-char-rpimem-Add-SPDX-licence-header.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0381-driver-char-rpimem-Add-SPDX-licence-header.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0387-driver-char-rpivid-Fix-access-to-freed-memory.patch b/target/linux/bcm27xx/patches-5.4/950-0382-driver-char-rpivid-Fix-access-to-freed-memory.patch
index 67147fa58d..67147fa58d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0387-driver-char-rpivid-Fix-access-to-freed-memory.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0382-driver-char-rpivid-Fix-access-to-freed-memory.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0388-add-BME680-to-i2c-sensor-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0383-add-BME680-to-i2c-sensor-overlay.patch
index 0c2fe6aa8a..0c2fe6aa8a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0388-add-BME680-to-i2c-sensor-overlay.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0383-add-BME680-to-i2c-sensor-overlay.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0389-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch b/target/linux/bcm27xx/patches-5.4/950-0384-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch
index 4de95a5449..4de95a5449 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0389-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0384-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0390-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch b/target/linux/bcm27xx/patches-5.4/950-0385-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch
index 0a7356ffa2..0a7356ffa2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0390-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0385-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0391-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch b/target/linux/bcm27xx/patches-5.4/950-0386-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch
index e986f425ff..e986f425ff 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0391-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0386-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0392-Add-universal-device-tree-overlay-for-SPI-devices.patch b/target/linux/bcm27xx/patches-5.4/950-0387-Add-universal-device-tree-overlay-for-SPI-devices.patch
index cb8fa91bef..cb8fa91bef 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0392-Add-universal-device-tree-overlay-for-SPI-devices.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0387-Add-universal-device-tree-overlay-for-SPI-devices.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0393-sound-Add-the-HiFiBerry-DAC-HD-version.patch b/target/linux/bcm27xx/patches-5.4/950-0388-sound-Add-the-HiFiBerry-DAC-HD-version.patch
index 6b9a6bd29c..6b9a6bd29c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0393-sound-Add-the-HiFiBerry-DAC-HD-version.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0388-sound-Add-the-HiFiBerry-DAC-HD-version.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0394-Initialise-rpi-firmware-before-clk-bcm2835.patch b/target/linux/bcm27xx/patches-5.4/950-0389-Initialise-rpi-firmware-before-clk-bcm2835.patch
index cdd5e7e9ab..cdd5e7e9ab 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0394-Initialise-rpi-firmware-before-clk-bcm2835.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0389-Initialise-rpi-firmware-before-clk-bcm2835.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0395-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch b/target/linux/bcm27xx/patches-5.4/950-0390-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch
index 54b366f65a..54b366f65a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0395-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0390-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0396-overlays-Use-preferred-compatible-strings.patch b/target/linux/bcm27xx/patches-5.4/950-0391-overlays-Use-preferred-compatible-strings.patch
index 6a246050cf..6a246050cf 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0396-overlays-Use-preferred-compatible-strings.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0391-overlays-Use-preferred-compatible-strings.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0397-tty-amba-pl011-Add-un-throttle-support.patch b/target/linux/bcm27xx/patches-5.4/950-0392-tty-amba-pl011-Add-un-throttle-support.patch
index ced0bf2b79..ced0bf2b79 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0397-tty-amba-pl011-Add-un-throttle-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0392-tty-amba-pl011-Add-un-throttle-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0398-Fix-i2c-pwm-pca9685a-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0393-Fix-i2c-pwm-pca9685a-overlay.patch
index 17bdf3984e..17bdf3984e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0398-Fix-i2c-pwm-pca9685a-overlay.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0393-Fix-i2c-pwm-pca9685a-overlay.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0399-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch b/target/linux/bcm27xx/patches-5.4/950-0394-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch
index 397a2c3331..397a2c3331 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0399-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0394-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0400-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch b/target/linux/bcm27xx/patches-5.4/950-0395-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch
index bd8f405ef8..bd8f405ef8 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0400-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0395-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0401-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch b/target/linux/bcm27xx/patches-5.4/950-0396-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch
index a5c3d40512..a5c3d40512 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0401-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0396-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0402-pisound-Added-reading-Pisound-board-hardware-revisio.patch b/target/linux/bcm27xx/patches-5.4/950-0397-pisound-Added-reading-Pisound-board-hardware-revisio.patch
index df6f526e2e..df6f526e2e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0402-pisound-Added-reading-Pisound-board-hardware-revisio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0397-pisound-Added-reading-Pisound-board-hardware-revisio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0403-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch b/target/linux/bcm27xx/patches-5.4/950-0398-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch
index 4713dde247..4713dde247 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0403-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0398-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0404-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch b/target/linux/bcm27xx/patches-5.4/950-0399-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch
index a69feb50b4..a69feb50b4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0404-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0399-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0405-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch b/target/linux/bcm27xx/patches-5.4/950-0400-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch
index 2f5d87b004..2f5d87b004 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0405-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0400-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0406-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch b/target/linux/bcm27xx/patches-5.4/950-0401-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch
index 10c5d23b46..10c5d23b46 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0406-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0401-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0407-tty-amba-pl011-Avoid-rare-write-when-full-error.patch b/target/linux/bcm27xx/patches-5.4/950-0402-tty-amba-pl011-Avoid-rare-write-when-full-error.patch
index 6283b83e17..6283b83e17 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0407-tty-amba-pl011-Avoid-rare-write-when-full-error.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0402-tty-amba-pl011-Avoid-rare-write-when-full-error.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0408-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch b/target/linux/bcm27xx/patches-5.4/950-0403-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch
index 06e979a462..06e979a462 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0408-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0403-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0409-overlays-Correct-the-eth_led-colour-assignments.patch b/target/linux/bcm27xx/patches-5.4/950-0404-overlays-Correct-the-eth_led-colour-assignments.patch
index f1f3290bad..f1f3290bad 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0409-overlays-Correct-the-eth_led-colour-assignments.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0404-overlays-Correct-the-eth_led-colour-assignments.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0410-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch b/target/linux/bcm27xx/patches-5.4/950-0405-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch
index fef644e1c9..fef644e1c9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0410-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0405-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0411-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch b/target/linux/bcm27xx/patches-5.4/950-0406-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch
index 77bf63e2e2..77bf63e2e2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0411-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0406-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0412-overlays-dwc2-Increase-RX-FIFO-size.patch b/target/linux/bcm27xx/patches-5.4/950-0407-overlays-dwc2-Increase-RX-FIFO-size.patch
index 23bc39b3d8..23bc39b3d8 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0412-overlays-dwc2-Increase-RX-FIFO-size.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0407-overlays-dwc2-Increase-RX-FIFO-size.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0413-overlays-Fix-mcp23017-s-addr-parameter.patch b/target/linux/bcm27xx/patches-5.4/950-0408-overlays-Fix-mcp23017-s-addr-parameter.patch
index 29ad87227d..29ad87227d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0413-overlays-Fix-mcp23017-s-addr-parameter.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0408-overlays-Fix-mcp23017-s-addr-parameter.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0409-SQUASH-Fix-spi-driver-compiler-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0409-SQUASH-Fix-spi-driver-compiler-warnings.patch
new file mode 100644
index 0000000000..4413439101
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0409-SQUASH-Fix-spi-driver-compiler-warnings.patch
@@ -0,0 +1,22 @@
+From 69811ede9ad350beb531082177bdc6da92c7fdb9 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 4 Feb 2020 16:35:12 +0000
+Subject: [PATCH] SQUASH: Fix spi driver compiler warnings
+
+Squash with "spi: spi-bcm2835: Disable forced software CS"
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/spi/spi-bcm2835.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -1182,7 +1182,6 @@ static int bcm2835_spi_setup(struct spi_
+ {
+ struct spi_controller *ctlr = spi->controller;
+ struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
+- struct gpio_chip *chip;
+ u32 cs;
+
+ /*
diff --git a/target/linux/bcm27xx/patches-5.4/950-0415-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0410-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch
index e94f15196b..e94f15196b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0415-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0410-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0416-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch b/target/linux/bcm27xx/patches-5.4/950-0411-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch
index 403f534baf..403f534baf 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0416-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0411-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0417-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch b/target/linux/bcm27xx/patches-5.4/950-0412-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch
index a66202a2c9..a66202a2c9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0417-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0412-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0418-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch b/target/linux/bcm27xx/patches-5.4/950-0413-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch
index 15e4f53a0a..15e4f53a0a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0418-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0413-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0419-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch b/target/linux/bcm27xx/patches-5.4/950-0414-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch
index 44f60d610f..44f60d610f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0419-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0414-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0414-SQUASH-Fix-spi-driver-compiler-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0414-SQUASH-Fix-spi-driver-compiler-warnings.patch
deleted file mode 100644
index f233c4aedc..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0414-SQUASH-Fix-spi-driver-compiler-warnings.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 69811ede9ad350beb531082177bdc6da92c7fdb9 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.com>
-Date: Tue, 4 Feb 2020 16:35:12 +0000
-Subject: [PATCH] SQUASH: Fix spi driver compiler warnings
-
-Squash with "spi: spi-bcm2835: Disable forced software CS"
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.com>
----
- drivers/spi/spi-bcm2835.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/spi/spi-bcm2835.c
-+++ b/drivers/spi/spi-bcm2835.c
-@@ -1230,7 +1230,6 @@ static int bcm2835_spi_setup(struct spi_
- {
- struct spi_controller *ctlr = spi->controller;
- struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
-- struct gpio_chip *chip;
- u32 cs;
-
- /*
diff --git a/target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch b/target/linux/bcm27xx/patches-5.4/950-0415-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch
index e204859fbd..e204859fbd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0415-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0421-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch b/target/linux/bcm27xx/patches-5.4/950-0416-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch
index ed0be9b9a3..ed0be9b9a3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0421-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0416-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0422-ARM-dts-Rebuild-downstream-DTS-files.patch b/target/linux/bcm27xx/patches-5.4/950-0417-ARM-dts-Rebuild-downstream-DTS-files.patch
index 8d230d0edb..8d230d0edb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0422-ARM-dts-Rebuild-downstream-DTS-files.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0417-ARM-dts-Rebuild-downstream-DTS-files.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0423-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch b/target/linux/bcm27xx/patches-5.4/950-0418-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch
index 4436c0a39d..4436c0a39d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0423-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0418-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0424-hwrng-iproc-rng200-Correct-SoC-name.patch b/target/linux/bcm27xx/patches-5.4/950-0419-hwrng-iproc-rng200-Correct-SoC-name.patch
index f4e93308b1..f4e93308b1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0424-hwrng-iproc-rng200-Correct-SoC-name.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0419-hwrng-iproc-rng200-Correct-SoC-name.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0425-ARM-dts-Correct-SoC-name.patch b/target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-Correct-SoC-name.patch
index c18eb8af3c..c18eb8af3c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0425-ARM-dts-Correct-SoC-name.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-Correct-SoC-name.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0426-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch b/target/linux/bcm27xx/patches-5.4/950-0421-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch
index 2c093459da..2c093459da 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0426-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0421-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0427-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch b/target/linux/bcm27xx/patches-5.4/950-0422-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch
index 7fb3443fa9..7fb3443fa9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0427-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0422-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0429-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch b/target/linux/bcm27xx/patches-5.4/950-0423-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch
index b5e59e6464..b5e59e6464 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0429-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0423-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0430-ARM-dts-overlays-Create-custom-clocks-in.patch b/target/linux/bcm27xx/patches-5.4/950-0424-ARM-dts-overlays-Create-custom-clocks-in.patch
index ac50884bce..ac50884bce 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0430-ARM-dts-overlays-Create-custom-clocks-in.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0424-ARM-dts-overlays-Create-custom-clocks-in.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0431-staging-vc04_services-Fix-vcsm-overflow-bug-when-cou.patch b/target/linux/bcm27xx/patches-5.4/950-0425-staging-vc04_services-Fix-vcsm-overflow-bug-when-cou.patch
index 4774fd2326..4774fd2326 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0431-staging-vc04_services-Fix-vcsm-overflow-bug-when-cou.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0425-staging-vc04_services-Fix-vcsm-overflow-bug-when-cou.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0432-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch b/target/linux/bcm27xx/patches-5.4/950-0426-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch
index 213e8b8d9d..213e8b8d9d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0432-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0426-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0433-of-overlay-Correct-symbol-path-fixups.patch b/target/linux/bcm27xx/patches-5.4/950-0427-of-overlay-Correct-symbol-path-fixups.patch
index 4b005876de..4b005876de 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0433-of-overlay-Correct-symbol-path-fixups.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0427-of-overlay-Correct-symbol-path-fixups.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0434-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch b/target/linux/bcm27xx/patches-5.4/950-0428-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch
index 636ad26a91..636ad26a91 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0434-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0428-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0435-of-address-Introduce-of_get_next_dma_parent-helper.patch b/target/linux/bcm27xx/patches-5.4/950-0429-of-address-Introduce-of_get_next_dma_parent-helper.patch
index 1056cfc60d..1056cfc60d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0435-of-address-Introduce-of_get_next_dma_parent-helper.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0429-of-address-Introduce-of_get_next_dma_parent-helper.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0436-of-address-Follow-DMA-parent-for-dma-coherent.patch b/target/linux/bcm27xx/patches-5.4/950-0430-of-address-Follow-DMA-parent-for-dma-coherent.patch
index 76af58a126..76af58a126 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0436-of-address-Follow-DMA-parent-for-dma-coherent.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0430-of-address-Follow-DMA-parent-for-dma-coherent.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0437-of-Factor-out-addr-size-cells-parsing.patch b/target/linux/bcm27xx/patches-5.4/950-0431-of-Factor-out-addr-size-cells-parsing.patch
index 045ee9827f..045ee9827f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0437-of-Factor-out-addr-size-cells-parsing.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0431-of-Factor-out-addr-size-cells-parsing.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0438-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch b/target/linux/bcm27xx/patches-5.4/950-0432-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch
index 28d1987a9c..28d1987a9c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0438-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0432-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0439-of-Make-of_dma_get_range-work-on-bus-nodes.patch b/target/linux/bcm27xx/patches-5.4/950-0433-of-Make-of_dma_get_range-work-on-bus-nodes.patch
index 1cac2dfcd8..1cac2dfcd8 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0439-of-Make-of_dma_get_range-work-on-bus-nodes.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0433-of-Make-of_dma_get_range-work-on-bus-nodes.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0440-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch b/target/linux/bcm27xx/patches-5.4/950-0434-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch
index c697494f8a..c697494f8a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0440-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0434-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0441-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch b/target/linux/bcm27xx/patches-5.4/950-0435-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch
index df184f53ee..df184f53ee 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0441-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0435-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0442-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch b/target/linux/bcm27xx/patches-5.4/950-0436-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch
index ccb2071f17..ccb2071f17 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0442-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0436-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0443-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch b/target/linux/bcm27xx/patches-5.4/950-0437-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch
index 23811e0b6e..23811e0b6e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0443-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0437-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0444-resource-Add-a-resource_list_first_type-helper.patch b/target/linux/bcm27xx/patches-5.4/950-0438-resource-Add-a-resource_list_first_type-helper.patch
index c2c959a3c1..c2c959a3c1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0444-resource-Add-a-resource_list_first_type-helper.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0438-resource-Add-a-resource_list_first_type-helper.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0445-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch b/target/linux/bcm27xx/patches-5.4/950-0439-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch
index ab04d64b72..ab04d64b72 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0445-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0439-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0446-x86-PCI-sta2x11-use-default-DMA-address-translation.patch b/target/linux/bcm27xx/patches-5.4/950-0440-x86-PCI-sta2x11-use-default-DMA-address-translation.patch
index 51fd4be35e..51fd4be35e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0446-x86-PCI-sta2x11-use-default-DMA-address-translation.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0440-x86-PCI-sta2x11-use-default-DMA-address-translation.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0447-PCI-of-Add-inbound-resource-parsing-to-helpers.patch b/target/linux/bcm27xx/patches-5.4/950-0441-PCI-of-Add-inbound-resource-parsing-to-helpers.patch
index 493ea63825..493ea63825 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0447-PCI-of-Add-inbound-resource-parsing-to-helpers.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0441-PCI-of-Add-inbound-resource-parsing-to-helpers.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0448-dma-direct-unify-the-dma_capable-definitions.patch b/target/linux/bcm27xx/patches-5.4/950-0442-dma-direct-unify-the-dma_capable-definitions.patch
index d115f0eb80..d115f0eb80 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0448-dma-direct-unify-the-dma_capable-definitions.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0442-dma-direct-unify-the-dma_capable-definitions.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0449-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch b/target/linux/bcm27xx/patches-5.4/950-0443-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch
index a98f1d3852..a98f1d3852 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0449-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0443-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0450-dma-direct-exclude-dma_direct_map_resource-from-the-.patch b/target/linux/bcm27xx/patches-5.4/950-0444-dma-direct-exclude-dma_direct_map_resource-from-the-.patch
index 2534b71b73..2534b71b73 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0450-dma-direct-exclude-dma_direct_map_resource-from-the-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0444-dma-direct-exclude-dma_direct_map_resource-from-the-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0451-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch b/target/linux/bcm27xx/patches-5.4/950-0445-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch
index d968e93153..d968e93153 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0451-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0445-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0452-ARM-dts-bcm2711-Enable-PCIe-controller.patch b/target/linux/bcm27xx/patches-5.4/950-0446-ARM-dts-bcm2711-Enable-PCIe-controller.patch
index 9f114c1633..9f114c1633 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0452-ARM-dts-bcm2711-Enable-PCIe-controller.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0446-ARM-dts-bcm2711-Enable-PCIe-controller.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0453-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch b/target/linux/bcm27xx/patches-5.4/950-0447-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch
index ca97a1966e..ca97a1966e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0453-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0447-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0454-PCI-brcmstb-Add-MSI-support.patch b/target/linux/bcm27xx/patches-5.4/950-0448-PCI-brcmstb-Add-MSI-support.patch
index a27259bd19..a27259bd19 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0454-PCI-brcmstb-Add-MSI-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0448-PCI-brcmstb-Add-MSI-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0455-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch b/target/linux/bcm27xx/patches-5.4/950-0449-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch
index 6bb45ccb1f..6bb45ccb1f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0455-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0449-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0456-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch b/target/linux/bcm27xx/patches-5.4/950-0450-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch
index 729d6e68ba..729d6e68ba 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0456-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0450-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0457-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch b/target/linux/bcm27xx/patches-5.4/950-0451-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch
index c93f4501c4..c93f4501c4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0457-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0451-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0458-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch b/target/linux/bcm27xx/patches-5.4/950-0452-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch
index 4ca345f2ad..4ca345f2ad 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0458-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0452-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0459-overlays-imx219-Correct-link-frequency-to-match-the-.patch b/target/linux/bcm27xx/patches-5.4/950-0453-overlays-imx219-Correct-link-frequency-to-match-the-.patch
index e9eed21451..e9eed21451 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0459-overlays-imx219-Correct-link-frequency-to-match-the-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0453-overlays-imx219-Correct-link-frequency-to-match-the-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0460-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch b/target/linux/bcm27xx/patches-5.4/950-0454-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch
index b1cd7bffbe..b1cd7bffbe 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0460-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0454-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0461-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch b/target/linux/bcm27xx/patches-5.4/950-0455-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch
index c7e10cbdc1..c7e10cbdc1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0461-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0455-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0462-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch b/target/linux/bcm27xx/patches-5.4/950-0456-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch
index 5846e96af8..5846e96af8 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0462-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0456-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0463-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch b/target/linux/bcm27xx/patches-5.4/950-0457-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch
index 907bab5cfd..907bab5cfd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0463-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0457-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0464-media-ov5647-Add-extra-10-bit-sensor-modes.patch b/target/linux/bcm27xx/patches-5.4/950-0458-media-ov5647-Add-extra-10-bit-sensor-modes.patch
index 9e40b5164a..9e40b5164a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0464-media-ov5647-Add-extra-10-bit-sensor-modes.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0458-media-ov5647-Add-extra-10-bit-sensor-modes.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0465-media-ov5647-change-defaults-to-better-match-raw-cam.patch b/target/linux/bcm27xx/patches-5.4/950-0459-media-ov5647-change-defaults-to-better-match-raw-cam.patch
index 58d23b7bcb..58d23b7bcb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0465-media-ov5647-change-defaults-to-better-match-raw-cam.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0459-media-ov5647-change-defaults-to-better-match-raw-cam.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0466-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch b/target/linux/bcm27xx/patches-5.4/950-0460-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch
index 0b48018c1e..0b48018c1e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0466-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0460-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0467-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch b/target/linux/bcm27xx/patches-5.4/950-0461-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch
index ac4fe1698b..ac4fe1698b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0467-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0461-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0468-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch b/target/linux/bcm27xx/patches-5.4/950-0462-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch
index f6264ff04a..f6264ff04a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0468-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0462-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0469-gpio-ir-overlay-add-parameter-to-configure-signal-po.patch b/target/linux/bcm27xx/patches-5.4/950-0463-gpio-ir-overlay-add-parameter-to-configure-signal-po.patch
index cdd14f7940..cdd14f7940 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0469-gpio-ir-overlay-add-parameter-to-configure-signal-po.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0463-gpio-ir-overlay-add-parameter-to-configure-signal-po.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0470-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch b/target/linux/bcm27xx/patches-5.4/950-0464-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch
index 8e66bccf6e..8e66bccf6e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0470-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0464-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0471-ARM-dts-bcm2711-Add-32-bit-PMU-compatibility.patch b/target/linux/bcm27xx/patches-5.4/950-0465-ARM-dts-bcm2711-Add-32-bit-PMU-compatibility.patch
index f549e73fd3..f549e73fd3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0471-ARM-dts-bcm2711-Add-32-bit-PMU-compatibility.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0465-ARM-dts-bcm2711-Add-32-bit-PMU-compatibility.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0472-ARM-dts-bcm271x-Use-a53-pmu-drop-RPI364.patch b/target/linux/bcm27xx/patches-5.4/950-0466-ARM-dts-bcm271x-Use-a53-pmu-drop-RPI364.patch
index 9504bb3982..9504bb3982 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0472-ARM-dts-bcm271x-Use-a53-pmu-drop-RPI364.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0466-ARM-dts-bcm271x-Use-a53-pmu-drop-RPI364.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0473-net-bcmgenet-Clear-ID_MODE_DIS-in-EXT_RGMII_OOB_CTRL.patch b/target/linux/bcm27xx/patches-5.4/950-0467-net-bcmgenet-Clear-ID_MODE_DIS-in-EXT_RGMII_OOB_CTRL.patch
index 9d8090441a..9d8090441a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0473-net-bcmgenet-Clear-ID_MODE_DIS-in-EXT_RGMII_OOB_CTRL.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0467-net-bcmgenet-Clear-ID_MODE_DIS-in-EXT_RGMII_OOB_CTRL.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0474-drm-modes-parse_cmdline-Fix-possible-reference-past-.patch b/target/linux/bcm27xx/patches-5.4/950-0468-drm-modes-parse_cmdline-Fix-possible-reference-past-.patch
index 9b514c3a25..9b514c3a25 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0474-drm-modes-parse_cmdline-Fix-possible-reference-past-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0468-drm-modes-parse_cmdline-Fix-possible-reference-past-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0475-drm-modes-parse_cmdline-Make-various-char-pointers-c.patch b/target/linux/bcm27xx/patches-5.4/950-0469-drm-modes-parse_cmdline-Make-various-char-pointers-c.patch
index 6abe7beb32..6abe7beb32 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0475-drm-modes-parse_cmdline-Make-various-char-pointers-c.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0469-drm-modes-parse_cmdline-Make-various-char-pointers-c.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0476-drm-modes-parse_cmdline-Stop-parsing-extras-after-bp.patch b/target/linux/bcm27xx/patches-5.4/950-0470-drm-modes-parse_cmdline-Stop-parsing-extras-after-bp.patch
index 1d356eb6ab..1d356eb6ab 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0476-drm-modes-parse_cmdline-Stop-parsing-extras-after-bp.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0470-drm-modes-parse_cmdline-Stop-parsing-extras-after-bp.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0477-drm-modes-parse_cmdline-Accept-extras-directly-after.patch b/target/linux/bcm27xx/patches-5.4/950-0471-drm-modes-parse_cmdline-Accept-extras-directly-after.patch
index 8d9a92ec0d..8d9a92ec0d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0477-drm-modes-parse_cmdline-Accept-extras-directly-after.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0471-drm-modes-parse_cmdline-Accept-extras-directly-after.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0478-drm-modes-parse_cmdline-Rework-drm_mode_parse_cmdlin.patch b/target/linux/bcm27xx/patches-5.4/950-0472-drm-modes-parse_cmdline-Rework-drm_mode_parse_cmdlin.patch
index 1716ebd7be..1716ebd7be 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0478-drm-modes-parse_cmdline-Rework-drm_mode_parse_cmdlin.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0472-drm-modes-parse_cmdline-Rework-drm_mode_parse_cmdlin.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0479-drm-modes-parse_cmdline-Add-freestanding-argument-to.patch b/target/linux/bcm27xx/patches-5.4/950-0473-drm-modes-parse_cmdline-Add-freestanding-argument-to.patch
index 6ed952bd45..6ed952bd45 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0479-drm-modes-parse_cmdline-Add-freestanding-argument-to.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0473-drm-modes-parse_cmdline-Add-freestanding-argument-to.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0480-drm-modes-parse_cmdline-Set-bpp-refresh_specified-af.patch b/target/linux/bcm27xx/patches-5.4/950-0474-drm-modes-parse_cmdline-Set-bpp-refresh_specified-af.patch
index ac973e1d4e..ac973e1d4e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0480-drm-modes-parse_cmdline-Set-bpp-refresh_specified-af.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0474-drm-modes-parse_cmdline-Set-bpp-refresh_specified-af.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0481-drm-modes-parse_cmdline-Allow-specifying-stand-alone.patch b/target/linux/bcm27xx/patches-5.4/950-0475-drm-modes-parse_cmdline-Allow-specifying-stand-alone.patch
index 746f35f83b..746f35f83b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0481-drm-modes-parse_cmdline-Allow-specifying-stand-alone.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0475-drm-modes-parse_cmdline-Allow-specifying-stand-alone.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0482-drm-modes-parse_cmdline-Add-support-for-specifying-p.patch b/target/linux/bcm27xx/patches-5.4/950-0476-drm-modes-parse_cmdline-Add-support-for-specifying-p.patch
index cbda9ecc10..cbda9ecc10 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0482-drm-modes-parse_cmdline-Add-support-for-specifying-p.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0476-drm-modes-parse_cmdline-Add-support-for-specifying-p.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0483-drm-modes-parse_cmdline-Remove-some-unnecessary-code.patch b/target/linux/bcm27xx/patches-5.4/950-0477-drm-modes-parse_cmdline-Remove-some-unnecessary-code.patch
index fb4a7f1cda..fb4a7f1cda 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0483-drm-modes-parse_cmdline-Remove-some-unnecessary-code.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0477-drm-modes-parse_cmdline-Remove-some-unnecessary-code.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0484-drm-modes-parse_cmdline-Explicitly-memset-the-passed.patch b/target/linux/bcm27xx/patches-5.4/950-0478-drm-modes-parse_cmdline-Explicitly-memset-the-passed.patch
index 372cd0d665..372cd0d665 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0484-drm-modes-parse_cmdline-Explicitly-memset-the-passed.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0478-drm-modes-parse_cmdline-Explicitly-memset-the-passed.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0485-drm-v3d-Replace-wait_for-macros-to-remove-use-of-msl.patch b/target/linux/bcm27xx/patches-5.4/950-0479-drm-v3d-Replace-wait_for-macros-to-remove-use-of-msl.patch
index 830bc1125e..830bc1125e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0485-drm-v3d-Replace-wait_for-macros-to-remove-use-of-msl.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0479-drm-v3d-Replace-wait_for-macros-to-remove-use-of-msl.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0486-Reduce-noise-from-rpi-poe-hat-fan.patch b/target/linux/bcm27xx/patches-5.4/950-0480-Reduce-noise-from-rpi-poe-hat-fan.patch
index 7c50843102..7c50843102 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0486-Reduce-noise-from-rpi-poe-hat-fan.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0480-Reduce-noise-from-rpi-poe-hat-fan.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0487-add-Sensirion-SPS30-to-i2c-sensor-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0481-add-Sensirion-SPS30-to-i2c-sensor-overlay.patch
index 72941b59bb..72941b59bb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0487-add-Sensirion-SPS30-to-i2c-sensor-overlay.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0481-add-Sensirion-SPS30-to-i2c-sensor-overlay.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0488-media-add-V4L2_CTRL_TYPE_AREA-control-type.patch b/target/linux/bcm27xx/patches-5.4/950-0482-media-add-V4L2_CTRL_TYPE_AREA-control-type.patch
index d82c3196b8..d82c3196b8 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0488-media-add-V4L2_CTRL_TYPE_AREA-control-type.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0482-media-add-V4L2_CTRL_TYPE_AREA-control-type.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0489-media-add-V4L2_CID_UNIT_CELL_SIZE-control.patch b/target/linux/bcm27xx/patches-5.4/950-0483-media-add-V4L2_CID_UNIT_CELL_SIZE-control.patch
index 0c860c7e4a..0c860c7e4a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0489-media-add-V4L2_CID_UNIT_CELL_SIZE-control.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0483-media-add-V4L2_CID_UNIT_CELL_SIZE-control.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0490-media-v4l2-common-add-pixel-encoding-support.patch b/target/linux/bcm27xx/patches-5.4/950-0484-media-v4l2-common-add-pixel-encoding-support.patch
index aa127ab5e7..aa127ab5e7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0490-media-v4l2-common-add-pixel-encoding-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0484-media-v4l2-common-add-pixel-encoding-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0491-media-v4l2-common-add-RGB565-and-RGB55-to-v4l2_forma.patch b/target/linux/bcm27xx/patches-5.4/950-0485-media-v4l2-common-add-RGB565-and-RGB55-to-v4l2_forma.patch
index 0171cdf821..0171cdf821 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0491-media-v4l2-common-add-RGB565-and-RGB55-to-v4l2_forma.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0485-media-v4l2-common-add-RGB565-and-RGB55-to-v4l2_forma.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0492-media-vb2-add-V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF.patch b/target/linux/bcm27xx/patches-5.4/950-0486-media-vb2-add-V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF.patch
index b05c34ccbe..b05c34ccbe 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0492-media-vb2-add-V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0486-media-vb2-add-V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0493-media-v4l2-mem2mem-support-held-capture-buffers.patch b/target/linux/bcm27xx/patches-5.4/950-0487-media-v4l2-mem2mem-support-held-capture-buffers.patch
index bb66baf07d..bb66baf07d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0493-media-v4l2-mem2mem-support-held-capture-buffers.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0487-media-v4l2-mem2mem-support-held-capture-buffers.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0494-media-videodev2.h-add-V4L2_DEC_CMD_FLUSH.patch b/target/linux/bcm27xx/patches-5.4/950-0488-media-videodev2.h-add-V4L2_DEC_CMD_FLUSH.patch
index 56fee1e029..56fee1e029 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0494-media-videodev2.h-add-V4L2_DEC_CMD_FLUSH.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0488-media-videodev2.h-add-V4L2_DEC_CMD_FLUSH.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0495-media-v4l2-mem2mem-add-stateless_-try_-decoder_cmd-i.patch b/target/linux/bcm27xx/patches-5.4/950-0489-media-v4l2-mem2mem-add-stateless_-try_-decoder_cmd-i.patch
index 0b74dbf123..0b74dbf123 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0495-media-v4l2-mem2mem-add-stateless_-try_-decoder_cmd-i.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0489-media-v4l2-mem2mem-add-stateless_-try_-decoder_cmd-i.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0496-media-v4l2-mem2mem-add-new_frame-detection.patch b/target/linux/bcm27xx/patches-5.4/950-0490-media-v4l2-mem2mem-add-new_frame-detection.patch
index 3c777922f1..3c777922f1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0496-media-v4l2-mem2mem-add-new_frame-detection.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0490-media-v4l2-mem2mem-add-new_frame-detection.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0497-media-Documentation-media-Document-V4L2_CTRL_TYPE_AR.patch b/target/linux/bcm27xx/patches-5.4/950-0491-media-Documentation-media-Document-V4L2_CTRL_TYPE_AR.patch
index 1d478fc68a..1d478fc68a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0497-media-Documentation-media-Document-V4L2_CTRL_TYPE_AR.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0491-media-Documentation-media-Document-V4L2_CTRL_TYPE_AR.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0498-media-v4l-Add-definitions-for-HEVC-stateless-decodin.patch b/target/linux/bcm27xx/patches-5.4/950-0492-media-v4l-Add-definitions-for-HEVC-stateless-decodin.patch
index 0fe0f8cea4..0fe0f8cea4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0498-media-v4l-Add-definitions-for-HEVC-stateless-decodin.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0492-media-v4l-Add-definitions-for-HEVC-stateless-decodin.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0499-media-v4l2-mem2mem-Fix-hold-buf-flag-checks.patch b/target/linux/bcm27xx/patches-5.4/950-0493-media-v4l2-mem2mem-Fix-hold-buf-flag-checks.patch
index 18073a8f9d..18073a8f9d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0499-media-v4l2-mem2mem-Fix-hold-buf-flag-checks.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0493-media-v4l2-mem2mem-Fix-hold-buf-flag-checks.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0500-media-pixfmt-Document-the-HEVC-slice-pixel-format.patch b/target/linux/bcm27xx/patches-5.4/950-0494-media-pixfmt-Document-the-HEVC-slice-pixel-format.patch
index 7398807782..7398807782 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0500-media-pixfmt-Document-the-HEVC-slice-pixel-format.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0494-media-pixfmt-Document-the-HEVC-slice-pixel-format.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0501-media-uapi-hevc-Add-scaling-matrix-control.patch b/target/linux/bcm27xx/patches-5.4/950-0495-media-uapi-hevc-Add-scaling-matrix-control.patch
index c2cf27a40e..c2cf27a40e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0501-media-uapi-hevc-Add-scaling-matrix-control.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0495-media-uapi-hevc-Add-scaling-matrix-control.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0502-media-uapi-hevc-Add-segment-address-field.patch b/target/linux/bcm27xx/patches-5.4/950-0496-media-uapi-hevc-Add-segment-address-field.patch
index 91f195b4ae..91f195b4ae 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0502-media-uapi-hevc-Add-segment-address-field.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0496-media-uapi-hevc-Add-segment-address-field.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0503-media-hevc_ctrls-Add-slice-param-dependent-slice-seg.patch b/target/linux/bcm27xx/patches-5.4/950-0497-media-hevc_ctrls-Add-slice-param-dependent-slice-seg.patch
index 1353480476..1353480476 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0503-media-hevc_ctrls-Add-slice-param-dependent-slice-seg.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0497-media-hevc_ctrls-Add-slice-param-dependent-slice-seg.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0504-media-uapi-Add-hevc-ctrls-for-WPP-decoding.patch b/target/linux/bcm27xx/patches-5.4/950-0498-media-uapi-Add-hevc-ctrls-for-WPP-decoding.patch
index 234cb82b2a..234cb82b2a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0504-media-uapi-Add-hevc-ctrls-for-WPP-decoding.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0498-media-uapi-Add-hevc-ctrls-for-WPP-decoding.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0505-media-videodev2.h-Add-a-format-for-column-YUV4-2-0-m.patch b/target/linux/bcm27xx/patches-5.4/950-0499-media-videodev2.h-Add-a-format-for-column-YUV4-2-0-m.patch
index 5a309827e2..5a309827e2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0505-media-videodev2.h-Add-a-format-for-column-YUV4-2-0-m.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0499-media-videodev2.h-Add-a-format-for-column-YUV4-2-0-m.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0506-media-v4l2-mem2mem-allow-request-job-buffer-processi.patch b/target/linux/bcm27xx/patches-5.4/950-0500-media-v4l2-mem2mem-allow-request-job-buffer-processi.patch
index a3023cae2b..a3023cae2b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0506-media-v4l2-mem2mem-allow-request-job-buffer-processi.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0500-media-v4l2-mem2mem-allow-request-job-buffer-processi.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0507-media-dt-bindings-media-Add-binding-for-the-Raspberr.patch b/target/linux/bcm27xx/patches-5.4/950-0501-media-dt-bindings-media-Add-binding-for-the-Raspberr.patch
index 203e112466..203e112466 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0507-media-dt-bindings-media-Add-binding-for-the-Raspberr.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0501-media-dt-bindings-media-Add-binding-for-the-Raspberr.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0508-staging-media-Add-Raspberry-Pi-V4L2-H265-decoder.patch b/target/linux/bcm27xx/patches-5.4/950-0502-staging-media-Add-Raspberry-Pi-V4L2-H265-decoder.patch
index 134a685f0e..134a685f0e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0508-staging-media-Add-Raspberry-Pi-V4L2-H265-decoder.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0502-staging-media-Add-Raspberry-Pi-V4L2-H265-decoder.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0509-dtoverlays-Add-overlay-to-enable-the-HEVC-V4L2-drive.patch b/target/linux/bcm27xx/patches-5.4/950-0503-dtoverlays-Add-overlay-to-enable-the-HEVC-V4L2-drive.patch
index ee92ada02f..ee92ada02f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0509-dtoverlays-Add-overlay-to-enable-the-HEVC-V4L2-drive.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0503-dtoverlays-Add-overlay-to-enable-the-HEVC-V4L2-drive.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0510-mmc-sdhci-Silence-MMC-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0504-mmc-sdhci-Silence-MMC-warnings.patch
index 38349280bb..38349280bb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0510-mmc-sdhci-Silence-MMC-warnings.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0504-mmc-sdhci-Silence-MMC-warnings.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0511-dt-bindings-i2c-brcmstb-Convert-the-BRCMSTB-binding-.patch b/target/linux/bcm27xx/patches-5.4/950-0505-dt-bindings-i2c-brcmstb-Convert-the-BRCMSTB-binding-.patch
index 01bdfee303..01bdfee303 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0511-dt-bindings-i2c-brcmstb-Convert-the-BRCMSTB-binding-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0505-dt-bindings-i2c-brcmstb-Convert-the-BRCMSTB-binding-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0512-dt-bindings-i2c-brcmstb-Add-BCM2711-BSC-AUTO-I2C-bin.patch b/target/linux/bcm27xx/patches-5.4/950-0506-dt-bindings-i2c-brcmstb-Add-BCM2711-BSC-AUTO-I2C-bin.patch
index 2716a13d25..2716a13d25 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0512-dt-bindings-i2c-brcmstb-Add-BCM2711-BSC-AUTO-I2C-bin.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0506-dt-bindings-i2c-brcmstb-Add-BCM2711-BSC-AUTO-I2C-bin.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0513-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch b/target/linux/bcm27xx/patches-5.4/950-0507-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch
index 76ce7403da..76ce7403da 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0513-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0507-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0514-i2c-brcmstb-Allow-to-compile-it-on-BCM2835.patch b/target/linux/bcm27xx/patches-5.4/950-0508-i2c-brcmstb-Allow-to-compile-it-on-BCM2835.patch
index a21035b69b..a21035b69b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0514-i2c-brcmstb-Allow-to-compile-it-on-BCM2835.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0508-i2c-brcmstb-Allow-to-compile-it-on-BCM2835.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0515-dt-bindings-clock-Add-a-binding-for-the-RPi-Firmware.patch b/target/linux/bcm27xx/patches-5.4/950-0509-dt-bindings-clock-Add-a-binding-for-the-RPi-Firmware.patch
index f3587060d1..f3587060d1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0515-dt-bindings-clock-Add-a-binding-for-the-RPi-Firmware.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0509-dt-bindings-clock-Add-a-binding-for-the-RPi-Firmware.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0516-clk-bcm-rpi-Allow-the-driver-to-be-probed-by-DT.patch b/target/linux/bcm27xx/patches-5.4/950-0510-clk-bcm-rpi-Allow-the-driver-to-be-probed-by-DT.patch
index d622d9ded5..d622d9ded5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0516-clk-bcm-rpi-Allow-the-driver-to-be-probed-by-DT.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0510-clk-bcm-rpi-Allow-the-driver-to-be-probed-by-DT.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0517-clk-bcm-rpi-Statically-init-clk_init_data.patch b/target/linux/bcm27xx/patches-5.4/950-0511-clk-bcm-rpi-Statically-init-clk_init_data.patch
index 5c7cb2b437..5c7cb2b437 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0517-clk-bcm-rpi-Statically-init-clk_init_data.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0511-clk-bcm-rpi-Statically-init-clk_init_data.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0518-clk-bcm-rpi-Use-clk_hw_register-for-pllb_arm.patch b/target/linux/bcm27xx/patches-5.4/950-0512-clk-bcm-rpi-Use-clk_hw_register-for-pllb_arm.patch
index 55f86ae340..55f86ae340 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0518-clk-bcm-rpi-Use-clk_hw_register-for-pllb_arm.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0512-clk-bcm-rpi-Use-clk_hw_register-for-pllb_arm.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0519-clk-bcm-rpi-Remove-global-pllb_arm-clock-pointer.patch b/target/linux/bcm27xx/patches-5.4/950-0513-clk-bcm-rpi-Remove-global-pllb_arm-clock-pointer.patch
index 32fc94c675..32fc94c675 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0519-clk-bcm-rpi-Remove-global-pllb_arm-clock-pointer.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0513-clk-bcm-rpi-Remove-global-pllb_arm-clock-pointer.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0520-clk-bcm-rpi-Make-sure-pllb_arm-is-removed.patch b/target/linux/bcm27xx/patches-5.4/950-0514-clk-bcm-rpi-Make-sure-pllb_arm-is-removed.patch
index 425830d5c4..425830d5c4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0520-clk-bcm-rpi-Make-sure-pllb_arm-is-removed.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0514-clk-bcm-rpi-Make-sure-pllb_arm-is-removed.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0521-clk-bcm-rpi-Remove-pllb_arm_lookup-global-pointer.patch b/target/linux/bcm27xx/patches-5.4/950-0515-clk-bcm-rpi-Remove-pllb_arm_lookup-global-pointer.patch
index e193b7906a..e193b7906a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0521-clk-bcm-rpi-Remove-pllb_arm_lookup-global-pointer.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0515-clk-bcm-rpi-Remove-pllb_arm_lookup-global-pointer.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0522-clk-bcm-rpi-Switch-to-clk_hw_register_clkdev.patch b/target/linux/bcm27xx/patches-5.4/950-0516-clk-bcm-rpi-Switch-to-clk_hw_register_clkdev.patch
index e4a129f233..e4a129f233 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0522-clk-bcm-rpi-Switch-to-clk_hw_register_clkdev.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0516-clk-bcm-rpi-Switch-to-clk_hw_register_clkdev.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0523-clk-bcm-rpi-Make-sure-the-clkdev-lookup-is-removed.patch b/target/linux/bcm27xx/patches-5.4/950-0517-clk-bcm-rpi-Make-sure-the-clkdev-lookup-is-removed.patch
index 7c887795ee..7c887795ee 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0523-clk-bcm-rpi-Make-sure-the-clkdev-lookup-is-removed.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0517-clk-bcm-rpi-Make-sure-the-clkdev-lookup-is-removed.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0524-clk-bcm-rpi-Create-a-data-structure-for-the-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0518-clk-bcm-rpi-Create-a-data-structure-for-the-clocks.patch
index 85b6f4a6e2..85b6f4a6e2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0524-clk-bcm-rpi-Create-a-data-structure-for-the-clocks.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0518-clk-bcm-rpi-Create-a-data-structure-for-the-clocks.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0525-clk-bcm-rpi-Add-clock-id-to-data.patch b/target/linux/bcm27xx/patches-5.4/950-0519-clk-bcm-rpi-Add-clock-id-to-data.patch
index 09f023e09c..09f023e09c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0525-clk-bcm-rpi-Add-clock-id-to-data.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0519-clk-bcm-rpi-Add-clock-id-to-data.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0526-clk-bcm-rpi-Pass-the-clocks-data-to-the-firmware-fun.patch b/target/linux/bcm27xx/patches-5.4/950-0520-clk-bcm-rpi-Pass-the-clocks-data-to-the-firmware-fun.patch
index 7822ff0d11..7822ff0d11 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0526-clk-bcm-rpi-Pass-the-clocks-data-to-the-firmware-fun.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0520-clk-bcm-rpi-Pass-the-clocks-data-to-the-firmware-fun.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0527-clk-bcm-rpi-Rename-is_prepared-function.patch b/target/linux/bcm27xx/patches-5.4/950-0521-clk-bcm-rpi-Rename-is_prepared-function.patch
index 1a6c9813de..1a6c9813de 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0527-clk-bcm-rpi-Rename-is_prepared-function.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0521-clk-bcm-rpi-Rename-is_prepared-function.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0528-clk-bcm-rpi-Split-pllb-clock-hooks.patch b/target/linux/bcm27xx/patches-5.4/950-0522-clk-bcm-rpi-Split-pllb-clock-hooks.patch
index 38720b89bd..38720b89bd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0528-clk-bcm-rpi-Split-pllb-clock-hooks.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0522-clk-bcm-rpi-Split-pllb-clock-hooks.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0529-clk-bcm-rpi-Make-the-PLLB-registration-function-retu.patch b/target/linux/bcm27xx/patches-5.4/950-0523-clk-bcm-rpi-Make-the-PLLB-registration-function-retu.patch
index 633cf18782..633cf18782 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0529-clk-bcm-rpi-Make-the-PLLB-registration-function-retu.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0523-clk-bcm-rpi-Make-the-PLLB-registration-function-retu.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0530-clk-bcm-rpi-Add-DT-provider-for-the-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0524-clk-bcm-rpi-Add-DT-provider-for-the-clocks.patch
index 99fdf8fbd6..99fdf8fbd6 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0530-clk-bcm-rpi-Add-DT-provider-for-the-clocks.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0524-clk-bcm-rpi-Add-DT-provider-for-the-clocks.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0531-clk-bcm-rpi-Discover-the-firmware-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0525-clk-bcm-rpi-Discover-the-firmware-clocks.patch
index eaa4a81141..eaa4a81141 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0531-clk-bcm-rpi-Discover-the-firmware-clocks.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0525-clk-bcm-rpi-Discover-the-firmware-clocks.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0532-ARM-dts-bcm2711-Add-firmware-clocks-node.patch b/target/linux/bcm27xx/patches-5.4/950-0526-ARM-dts-bcm2711-Add-firmware-clocks-node.patch
index 098903d2e1..098903d2e1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0532-ARM-dts-bcm2711-Add-firmware-clocks-node.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0526-ARM-dts-bcm2711-Add-firmware-clocks-node.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0533-reset-Move-reset-simple-header-out-of-drivers-reset.patch b/target/linux/bcm27xx/patches-5.4/950-0527-reset-Move-reset-simple-header-out-of-drivers-reset.patch
index 3df4fde439..3df4fde439 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0533-reset-Move-reset-simple-header-out-of-drivers-reset.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0527-reset-Move-reset-simple-header-out-of-drivers-reset.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0534-reset-simple-Add-reset-callback.patch b/target/linux/bcm27xx/patches-5.4/950-0528-reset-simple-Add-reset-callback.patch
index 035c9d6aa0..035c9d6aa0 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0534-reset-simple-Add-reset-callback.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0528-reset-simple-Add-reset-callback.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0535-dt-bindings-clock-Add-BCM2711-DVP-binding.patch b/target/linux/bcm27xx/patches-5.4/950-0529-dt-bindings-clock-Add-BCM2711-DVP-binding.patch
index ca87cbac83..ca87cbac83 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0535-dt-bindings-clock-Add-BCM2711-DVP-binding.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0529-dt-bindings-clock-Add-BCM2711-DVP-binding.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0536-clk-bcm-Add-BCM2711-DVP-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0530-clk-bcm-Add-BCM2711-DVP-driver.patch
index 23105057a9..23105057a9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0536-clk-bcm-Add-BCM2711-DVP-driver.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0530-clk-bcm-Add-BCM2711-DVP-driver.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0537-ARM-dts-bcm2711-Add-HDMI-DVP.patch b/target/linux/bcm27xx/patches-5.4/950-0531-ARM-dts-bcm2711-Add-HDMI-DVP.patch
index c4d230e730..c4d230e730 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0537-ARM-dts-bcm2711-Add-HDMI-DVP.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0531-ARM-dts-bcm2711-Add-HDMI-DVP.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0538-dt-bindings-display-Convert-VC4-bindings-to-schemas.patch b/target/linux/bcm27xx/patches-5.4/950-0532-dt-bindings-display-Convert-VC4-bindings-to-schemas.patch
index d9482649cc..d9482649cc 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0538-dt-bindings-display-Convert-VC4-bindings-to-schemas.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0532-dt-bindings-display-Convert-VC4-bindings-to-schemas.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0539-dt-bindings-display-vc4-dpi-Add-missing-clock-names-.patch b/target/linux/bcm27xx/patches-5.4/950-0533-dt-bindings-display-vc4-dpi-Add-missing-clock-names-.patch
index 2150f0abec..2150f0abec 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0539-dt-bindings-display-vc4-dpi-Add-missing-clock-names-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0533-dt-bindings-display-vc4-dpi-Add-missing-clock-names-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0540-dt-bindings-display-vc4-dsi-Add-missing-clock-proper.patch b/target/linux/bcm27xx/patches-5.4/950-0534-dt-bindings-display-vc4-dsi-Add-missing-clock-proper.patch
index 4cb313f152..4cb313f152 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0540-dt-bindings-display-vc4-dsi-Add-missing-clock-proper.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0534-dt-bindings-display-vc4-dsi-Add-missing-clock-proper.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0541-dt-bindings-display-vc4-hdmi-Add-missing-clock-names.patch b/target/linux/bcm27xx/patches-5.4/950-0535-dt-bindings-display-vc4-hdmi-Add-missing-clock-names.patch
index 5ef4eaeab9..5ef4eaeab9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0541-dt-bindings-display-vc4-hdmi-Add-missing-clock-names.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0535-dt-bindings-display-vc4-hdmi-Add-missing-clock-names.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0542-dt-bindings-display-vc4-Document-BCM2711-VC5.patch b/target/linux/bcm27xx/patches-5.4/950-0536-dt-bindings-display-vc4-Document-BCM2711-VC5.patch
index 2499dee0c9..2499dee0c9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0542-dt-bindings-display-vc4-Document-BCM2711-VC5.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0536-dt-bindings-display-vc4-Document-BCM2711-VC5.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0543-drm-vc4-drv-Add-include-guards.patch b/target/linux/bcm27xx/patches-5.4/950-0537-drm-vc4-drv-Add-include-guards.patch
index 16f8b0ad82..16f8b0ad82 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0543-drm-vc4-drv-Add-include-guards.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0537-drm-vc4-drv-Add-include-guards.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0544-drm-vc4-drv-Support-BCM2711.patch b/target/linux/bcm27xx/patches-5.4/950-0538-drm-vc4-drv-Support-BCM2711.patch
index 21018e11b7..21018e11b7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0544-drm-vc4-drv-Support-BCM2711.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0538-drm-vc4-drv-Support-BCM2711.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0545-drm-vc4-drv-Add-support-for-the-BCM2711-HVS5.patch b/target/linux/bcm27xx/patches-5.4/950-0539-drm-vc4-drv-Add-support-for-the-BCM2711-HVS5.patch
index a02663ac8b..a02663ac8b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0545-drm-vc4-drv-Add-support-for-the-BCM2711-HVS5.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0539-drm-vc4-drv-Add-support-for-the-BCM2711-HVS5.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0546-drm-vc4-plane-Improve-LBM-usage.patch b/target/linux/bcm27xx/patches-5.4/950-0540-drm-vc4-plane-Improve-LBM-usage.patch
index 5342e0ad23..5342e0ad23 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0546-drm-vc4-plane-Improve-LBM-usage.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0540-drm-vc4-plane-Improve-LBM-usage.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0547-drm-vc4-plane-Move-planes-creation-to-its-own-functi.patch b/target/linux/bcm27xx/patches-5.4/950-0541-drm-vc4-plane-Move-planes-creation-to-its-own-functi.patch
index 025efee0e3..025efee0e3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0547-drm-vc4-plane-Move-planes-creation-to-its-own-functi.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0541-drm-vc4-plane-Move-planes-creation-to-its-own-functi.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0548-drm-vc4-plane-Move-additional-planes-creation-to-dri.patch b/target/linux/bcm27xx/patches-5.4/950-0542-drm-vc4-plane-Move-additional-planes-creation-to-dri.patch
index b2e9f15647..b2e9f15647 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0548-drm-vc4-plane-Move-additional-planes-creation-to-dri.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0542-drm-vc4-plane-Move-additional-planes-creation-to-dri.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0549-drm-vc4-plane-Register-all-the-planes-at-once.patch b/target/linux/bcm27xx/patches-5.4/950-0543-drm-vc4-plane-Register-all-the-planes-at-once.patch
index 28277f1e56..28277f1e56 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0549-drm-vc4-plane-Register-all-the-planes-at-once.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0543-drm-vc4-plane-Register-all-the-planes-at-once.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0550-drm-vc4-plane-Create-overlays-for-any-CRTC.patch b/target/linux/bcm27xx/patches-5.4/950-0544-drm-vc4-plane-Create-overlays-for-any-CRTC.patch
index 7b9ec02cf6..7b9ec02cf6 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0550-drm-vc4-plane-Create-overlays-for-any-CRTC.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0544-drm-vc4-plane-Create-overlays-for-any-CRTC.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0551-drm-vc4-plane-Create-more-planes.patch b/target/linux/bcm27xx/patches-5.4/950-0545-drm-vc4-plane-Create-more-planes.patch
index 931e2bdad4..931e2bdad4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0551-drm-vc4-plane-Create-more-planes.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0545-drm-vc4-plane-Create-more-planes.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0552-drm-vc4-crtc-Rename-SoC-data-structures.patch b/target/linux/bcm27xx/patches-5.4/950-0546-drm-vc4-crtc-Rename-SoC-data-structures.patch
index 8b8eeea737..8b8eeea737 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0552-drm-vc4-crtc-Rename-SoC-data-structures.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0546-drm-vc4-crtc-Rename-SoC-data-structures.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0553-drm-vc4-crtc-Move-crtc-state-to-common-header.patch b/target/linux/bcm27xx/patches-5.4/950-0547-drm-vc4-crtc-Move-crtc-state-to-common-header.patch
index 6108f86787..6108f86787 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0553-drm-vc4-crtc-Move-crtc-state-to-common-header.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0547-drm-vc4-crtc-Move-crtc-state-to-common-header.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0554-drm-vc4-crtc-Deal-with-different-number-of-pixel-per.patch b/target/linux/bcm27xx/patches-5.4/950-0548-drm-vc4-crtc-Deal-with-different-number-of-pixel-per.patch
index 5949e616f9..5949e616f9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0554-drm-vc4-crtc-Deal-with-different-number-of-pixel-per.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0548-drm-vc4-crtc-Deal-with-different-number-of-pixel-per.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0555-drm-vc4-crtc-Use-a-shared-interrupt.patch b/target/linux/bcm27xx/patches-5.4/950-0549-drm-vc4-crtc-Use-a-shared-interrupt.patch
index b517b5414b..b517b5414b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0555-drm-vc4-crtc-Use-a-shared-interrupt.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0549-drm-vc4-crtc-Use-a-shared-interrupt.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0556-drm-vc4-crtc-Turn-static-const-variable-into-a-defin.patch b/target/linux/bcm27xx/patches-5.4/950-0550-drm-vc4-crtc-Turn-static-const-variable-into-a-defin.patch
index 3deefc361f..3deefc361f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0556-drm-vc4-crtc-Turn-static-const-variable-into-a-defin.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0550-drm-vc4-crtc-Turn-static-const-variable-into-a-defin.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0557-drm-vc4-crtc-Move-the-cob-allocation-outside-of-bind.patch b/target/linux/bcm27xx/patches-5.4/950-0551-drm-vc4-crtc-Move-the-cob-allocation-outside-of-bind.patch
index 83c49132a3..83c49132a3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0557-drm-vc4-crtc-Move-the-cob-allocation-outside-of-bind.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0551-drm-vc4-crtc-Move-the-cob-allocation-outside-of-bind.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0558-drm-vc4-crtc-Rename-HVS-channel-to-output.patch b/target/linux/bcm27xx/patches-5.4/950-0552-drm-vc4-crtc-Rename-HVS-channel-to-output.patch
index cf854fceb8..cf854fceb8 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0558-drm-vc4-crtc-Rename-HVS-channel-to-output.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0552-drm-vc4-crtc-Rename-HVS-channel-to-output.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0559-drm-vc4-crtc-Use-local-chan-variable.patch b/target/linux/bcm27xx/patches-5.4/950-0553-drm-vc4-crtc-Use-local-chan-variable.patch
index 6f77bace01..6f77bace01 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0559-drm-vc4-crtc-Use-local-chan-variable.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0553-drm-vc4-crtc-Use-local-chan-variable.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0560-drm-vc4-crtc-Enable-and-disable-the-PV-in-atomic_ena.patch b/target/linux/bcm27xx/patches-5.4/950-0554-drm-vc4-crtc-Enable-and-disable-the-PV-in-atomic_ena.patch
index c5f06f20ea..c5f06f20ea 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0560-drm-vc4-crtc-Enable-and-disable-the-PV-in-atomic_ena.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0554-drm-vc4-crtc-Enable-and-disable-the-PV-in-atomic_ena.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0561-drm-vc4-crtc-Assign-output-to-channel-automatically.patch b/target/linux/bcm27xx/patches-5.4/950-0555-drm-vc4-crtc-Assign-output-to-channel-automatically.patch
index d470f3b7f0..d470f3b7f0 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0561-drm-vc4-crtc-Assign-output-to-channel-automatically.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0555-drm-vc4-crtc-Assign-output-to-channel-automatically.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0562-drm-vc4-crtc-Add-FIFO-depth-to-vc4_crtc_data.patch b/target/linux/bcm27xx/patches-5.4/950-0556-drm-vc4-crtc-Add-FIFO-depth-to-vc4_crtc_data.patch
index e920a0be64..e920a0be64 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0562-drm-vc4-crtc-Add-FIFO-depth-to-vc4_crtc_data.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0556-drm-vc4-crtc-Add-FIFO-depth-to-vc4_crtc_data.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0563-drm-vc4-crtc-Add-function-to-compute-FIFO-level-bits.patch b/target/linux/bcm27xx/patches-5.4/950-0557-drm-vc4-crtc-Add-function-to-compute-FIFO-level-bits.patch
index 77952c0eea..77952c0eea 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0563-drm-vc4-crtc-Add-function-to-compute-FIFO-level-bits.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0557-drm-vc4-crtc-Add-function-to-compute-FIFO-level-bits.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0564-drm-vc4-crtc-Rename-HDMI-encoder-type-to-HDMI0.patch b/target/linux/bcm27xx/patches-5.4/950-0558-drm-vc4-crtc-Rename-HDMI-encoder-type-to-HDMI0.patch
index fa6a8f9a63..fa6a8f9a63 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0564-drm-vc4-crtc-Rename-HDMI-encoder-type-to-HDMI0.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0558-drm-vc4-crtc-Rename-HDMI-encoder-type-to-HDMI0.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0565-drm-vc4-crtc-Add-HDMI1-encoder-type.patch b/target/linux/bcm27xx/patches-5.4/950-0559-drm-vc4-crtc-Add-HDMI1-encoder-type.patch
index 00ad755492..00ad755492 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0565-drm-vc4-crtc-Add-HDMI1-encoder-type.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0559-drm-vc4-crtc-Add-HDMI1-encoder-type.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-crtc-Remove-redundant-call-to-drm_crtc_enabl.patch b/target/linux/bcm27xx/patches-5.4/950-0560-drm-vc4-crtc-Remove-redundant-call-to-drm_crtc_enabl.patch
index 5704952569..5704952569 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-crtc-Remove-redundant-call-to-drm_crtc_enabl.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0560-drm-vc4-crtc-Remove-redundant-call-to-drm_crtc_enabl.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0567-drm-vc4-crtc-Disable-color-management-for-HVS5.patch b/target/linux/bcm27xx/patches-5.4/950-0561-drm-vc4-crtc-Disable-color-management-for-HVS5.patch
index bd487df5c4..bd487df5c4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0567-drm-vc4-crtc-Disable-color-management-for-HVS5.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0561-drm-vc4-crtc-Disable-color-management-for-HVS5.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0568-dt-bindings-display-vc4-pv-Add-BCM2711-pixel-valves.patch b/target/linux/bcm27xx/patches-5.4/950-0562-dt-bindings-display-vc4-pv-Add-BCM2711-pixel-valves.patch
index 6bf6ab74c4..6bf6ab74c4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0568-dt-bindings-display-vc4-pv-Add-BCM2711-pixel-valves.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0562-dt-bindings-display-vc4-pv-Add-BCM2711-pixel-valves.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0569-drm-vc4-crtc-Add-BCM2711-pixelvalves.patch b/target/linux/bcm27xx/patches-5.4/950-0563-drm-vc4-crtc-Add-BCM2711-pixelvalves.patch
index 3ff57ef3df..3ff57ef3df 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0569-drm-vc4-crtc-Add-BCM2711-pixelvalves.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0563-drm-vc4-crtc-Add-BCM2711-pixelvalves.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0570-drm-vc4-hdmi-Use-debugfs-private-field.patch b/target/linux/bcm27xx/patches-5.4/950-0564-drm-vc4-hdmi-Use-debugfs-private-field.patch
index 89d8aae28d..89d8aae28d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0570-drm-vc4-hdmi-Use-debugfs-private-field.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0564-drm-vc4-hdmi-Use-debugfs-private-field.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0571-drm-vc4-hdmi-Move-structure-to-header.patch b/target/linux/bcm27xx/patches-5.4/950-0565-drm-vc4-hdmi-Move-structure-to-header.patch
index 430fc0459e..430fc0459e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0571-drm-vc4-hdmi-Move-structure-to-header.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0565-drm-vc4-hdmi-Move-structure-to-header.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0572-drm-vc4-hdmi-rework-connectors-and-encoders.patch b/target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-hdmi-rework-connectors-and-encoders.patch
index ebe6432913..ebe6432913 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0572-drm-vc4-hdmi-rework-connectors-and-encoders.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-hdmi-rework-connectors-and-encoders.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0573-drm-vc4-hdmi-Rename-hdmi-to-vc4_hdmi.patch b/target/linux/bcm27xx/patches-5.4/950-0567-drm-vc4-hdmi-Rename-hdmi-to-vc4_hdmi.patch
index 19296e93ee..19296e93ee 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0573-drm-vc4-hdmi-Rename-hdmi-to-vc4_hdmi.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0567-drm-vc4-hdmi-Rename-hdmi-to-vc4_hdmi.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0574-drm-vc4-hdmi-Move-accessors-to-vc4_hdmi.patch b/target/linux/bcm27xx/patches-5.4/950-0568-drm-vc4-hdmi-Move-accessors-to-vc4_hdmi.patch
index 1e50c0c579..1e50c0c579 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0574-drm-vc4-hdmi-Move-accessors-to-vc4_hdmi.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0568-drm-vc4-hdmi-Move-accessors-to-vc4_hdmi.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0575-drm-vc4-hdmi-Use-local-vc4_hdmi-directly.patch b/target/linux/bcm27xx/patches-5.4/950-0569-drm-vc4-hdmi-Use-local-vc4_hdmi-directly.patch
index 9b60fbb72b..9b60fbb72b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0575-drm-vc4-hdmi-Use-local-vc4_hdmi-directly.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0569-drm-vc4-hdmi-Use-local-vc4_hdmi-directly.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0576-drm-vc4-hdmi-Add-container_of-macros-for-encoders-an.patch b/target/linux/bcm27xx/patches-5.4/950-0570-drm-vc4-hdmi-Add-container_of-macros-for-encoders-an.patch
index 1d70ca851c..1d70ca851c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0576-drm-vc4-hdmi-Add-container_of-macros-for-encoders-an.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0570-drm-vc4-hdmi-Add-container_of-macros-for-encoders-an.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0577-drm-vc4-hdmi-Pass-vc4_hdmi-to-CEC-code.patch b/target/linux/bcm27xx/patches-5.4/950-0571-drm-vc4-hdmi-Pass-vc4_hdmi-to-CEC-code.patch
index 092efc17f5..092efc17f5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0577-drm-vc4-hdmi-Pass-vc4_hdmi-to-CEC-code.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0571-drm-vc4-hdmi-Pass-vc4_hdmi-to-CEC-code.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0578-drm-vc4-hdmi-Remove-vc4_dev-hdmi-pointer.patch b/target/linux/bcm27xx/patches-5.4/950-0572-drm-vc4-hdmi-Remove-vc4_dev-hdmi-pointer.patch
index 24e4229c0e..24e4229c0e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0578-drm-vc4-hdmi-Remove-vc4_dev-hdmi-pointer.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0572-drm-vc4-hdmi-Remove-vc4_dev-hdmi-pointer.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Remove-vc4_hdmi_connector.patch b/target/linux/bcm27xx/patches-5.4/950-0573-drm-vc4-hdmi-Remove-vc4_hdmi_connector.patch
index 15d15c6afe..15d15c6afe 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Remove-vc4_hdmi_connector.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0573-drm-vc4-hdmi-Remove-vc4_hdmi_connector.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0580-drm-vc4-hdmi-Introduce-resource-init-and-variant.patch b/target/linux/bcm27xx/patches-5.4/950-0574-drm-vc4-hdmi-Introduce-resource-init-and-variant.patch
index c3a4a76bad..c3a4a76bad 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0580-drm-vc4-hdmi-Introduce-resource-init-and-variant.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0574-drm-vc4-hdmi-Introduce-resource-init-and-variant.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0581-drm-vc4-hdmi-Implement-a-register-layout-abstraction.patch b/target/linux/bcm27xx/patches-5.4/950-0575-drm-vc4-hdmi-Implement-a-register-layout-abstraction.patch
index dbfb08eebb..dbfb08eebb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0581-drm-vc4-hdmi-Implement-a-register-layout-abstraction.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0575-drm-vc4-hdmi-Implement-a-register-layout-abstraction.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0582-drm-vc4-hdmi-Add-reset-callback.patch b/target/linux/bcm27xx/patches-5.4/950-0576-drm-vc4-hdmi-Add-reset-callback.patch
index 18c11aba45..18c11aba45 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0582-drm-vc4-hdmi-Add-reset-callback.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0576-drm-vc4-hdmi-Add-reset-callback.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0583-drm-vc4-hdmi-Add-PHY-init-and-disable-function.patch b/target/linux/bcm27xx/patches-5.4/950-0577-drm-vc4-hdmi-Add-PHY-init-and-disable-function.patch
index ce295f3fce..ce295f3fce 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0583-drm-vc4-hdmi-Add-PHY-init-and-disable-function.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0577-drm-vc4-hdmi-Add-PHY-init-and-disable-function.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0584-drm-vc4-hdmi-Add-PHY-RNG-enable-disable-function.patch b/target/linux/bcm27xx/patches-5.4/950-0578-drm-vc4-hdmi-Add-PHY-RNG-enable-disable-function.patch
index 0fb6a63bcc..0fb6a63bcc 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0584-drm-vc4-hdmi-Add-PHY-RNG-enable-disable-function.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0578-drm-vc4-hdmi-Add-PHY-RNG-enable-disable-function.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0585-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch b/target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch
index 0106470d93..0106470d93 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0585-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0586-drm-vc4-hdmi-Add-a-set_timings-callback.patch b/target/linux/bcm27xx/patches-5.4/950-0580-drm-vc4-hdmi-Add-a-set_timings-callback.patch
index 064925c61a..064925c61a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0586-drm-vc4-hdmi-Add-a-set_timings-callback.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0580-drm-vc4-hdmi-Add-a-set_timings-callback.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0587-drm-vc4-hdmi-Add-HDMI-ID.patch b/target/linux/bcm27xx/patches-5.4/950-0581-drm-vc4-hdmi-Add-HDMI-ID.patch
index b5d9c7b340..b5d9c7b340 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0587-drm-vc4-hdmi-Add-HDMI-ID.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0581-drm-vc4-hdmi-Add-HDMI-ID.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0588-drm-vc4-hdmi-Deal-with-multiple-debugfs-files.patch b/target/linux/bcm27xx/patches-5.4/950-0582-drm-vc4-hdmi-Deal-with-multiple-debugfs-files.patch
index e25b18a21f..e25b18a21f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0588-drm-vc4-hdmi-Deal-with-multiple-debugfs-files.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0582-drm-vc4-hdmi-Deal-with-multiple-debugfs-files.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0589-drm-vc4-hdmi-Add-an-audio-support-flag.patch b/target/linux/bcm27xx/patches-5.4/950-0583-drm-vc4-hdmi-Add-an-audio-support-flag.patch
index 9c8240714a..9c8240714a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0589-drm-vc4-hdmi-Add-an-audio-support-flag.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0583-drm-vc4-hdmi-Add-an-audio-support-flag.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0590-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch b/target/linux/bcm27xx/patches-5.4/950-0584-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch
index a3efadd2ad..a3efadd2ad 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0590-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0584-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0591-drm-vc4-hdmi-Add-CEC-support-flag.patch b/target/linux/bcm27xx/patches-5.4/950-0585-drm-vc4-hdmi-Add-CEC-support-flag.patch
index 396e8a5523..396e8a5523 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0591-drm-vc4-hdmi-Add-CEC-support-flag.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0585-drm-vc4-hdmi-Add-CEC-support-flag.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0592-drm-vc4-hdmi-Remove-unused-CEC_CLOCK_DIV-define.patch b/target/linux/bcm27xx/patches-5.4/950-0586-drm-vc4-hdmi-Remove-unused-CEC_CLOCK_DIV-define.patch
index 4befec6c05..4befec6c05 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0592-drm-vc4-hdmi-Remove-unused-CEC_CLOCK_DIV-define.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0586-drm-vc4-hdmi-Remove-unused-CEC_CLOCK_DIV-define.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0593-drm-vc4-hdmi-Rename-drm_encoder-pointer-in-mode_vali.patch b/target/linux/bcm27xx/patches-5.4/950-0587-drm-vc4-hdmi-Rename-drm_encoder-pointer-in-mode_vali.patch
index 5c0ab9768b..5c0ab9768b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0593-drm-vc4-hdmi-Rename-drm_encoder-pointer-in-mode_vali.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0587-drm-vc4-hdmi-Rename-drm_encoder-pointer-in-mode_vali.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0594-drm-vc4-hdmi-Adjust-HSM-clock-rate-depending-on-pixe.patch b/target/linux/bcm27xx/patches-5.4/950-0588-drm-vc4-hdmi-Adjust-HSM-clock-rate-depending-on-pixe.patch
index 5b836f8bf8..5b836f8bf8 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0594-drm-vc4-hdmi-Adjust-HSM-clock-rate-depending-on-pixe.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0588-drm-vc4-hdmi-Adjust-HSM-clock-rate-depending-on-pixe.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-hdmi-Support-the-BCM2711-HDMI-controllers.patch b/target/linux/bcm27xx/patches-5.4/950-0589-drm-vc4-hdmi-Support-the-BCM2711-HDMI-controllers.patch
index 8a2772299a..8a2772299a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-hdmi-Support-the-BCM2711-HDMI-controllers.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0589-drm-vc4-hdmi-Support-the-BCM2711-HDMI-controllers.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0596-dt-bindings-display-vc4-hdmi-Add-BCM2711-HDMI-contro.patch b/target/linux/bcm27xx/patches-5.4/950-0590-dt-bindings-display-vc4-hdmi-Add-BCM2711-HDMI-contro.patch
index c41e063fde..c41e063fde 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0596-dt-bindings-display-vc4-hdmi-Add-BCM2711-HDMI-contro.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0590-dt-bindings-display-vc4-hdmi-Add-BCM2711-HDMI-contro.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0597-ARM-dts-bcm2711-Enable-the-display-pipeline.patch b/target/linux/bcm27xx/patches-5.4/950-0591-ARM-dts-bcm2711-Enable-the-display-pipeline.patch
index aae9b9e00d..aae9b9e00d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0597-ARM-dts-bcm2711-Enable-the-display-pipeline.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0591-ARM-dts-bcm2711-Enable-the-display-pipeline.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0598-DOWNSTREAM-ARM-dts-rpi4-Disable-KMS-driver-by-defaul.patch b/target/linux/bcm27xx/patches-5.4/950-0592-DOWNSTREAM-ARM-dts-rpi4-Disable-KMS-driver-by-defaul.patch
index b27d355340..b27d355340 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0598-DOWNSTREAM-ARM-dts-rpi4-Disable-KMS-driver-by-defaul.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0592-DOWNSTREAM-ARM-dts-rpi4-Disable-KMS-driver-by-defaul.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0599-dtoverlays-Add-Pi4-version-of-vc4-kms-v3d.patch b/target/linux/bcm27xx/patches-5.4/950-0593-dtoverlays-Add-Pi4-version-of-vc4-kms-v3d.patch
index 1c46fa4485..1c46fa4485 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0599-dtoverlays-Add-Pi4-version-of-vc4-kms-v3d.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0593-dtoverlays-Add-Pi4-version-of-vc4-kms-v3d.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0600-drm-Checking-of-the-pitch-is-only-valid-for-linear-f.patch b/target/linux/bcm27xx/patches-5.4/950-0594-drm-Checking-of-the-pitch-is-only-valid-for-linear-f.patch
index 3f0aa4aa02..3f0aa4aa02 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0600-drm-Checking-of-the-pitch-is-only-valid-for-linear-f.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0594-drm-Checking-of-the-pitch-is-only-valid-for-linear-f.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0601-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch b/target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch
index a4d5afe406..a4d5afe406 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0601-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0602-Fixup-P030-support.patch b/target/linux/bcm27xx/patches-5.4/950-0596-Fixup-P030-support.patch
index 0963824d9e..0963824d9e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0602-Fixup-P030-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0596-Fixup-P030-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-The-check-for-assigned-HVS-channels-is-not-a.patch b/target/linux/bcm27xx/patches-5.4/950-0597-drm-vc4-The-check-for-assigned-HVS-channels-is-not-a.patch
index 00a65a9b11..00a65a9b11 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-The-check-for-assigned-HVS-channels-is-not-a.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0597-drm-vc4-The-check-for-assigned-HVS-channels-is-not-a.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0604-dt-Update-v3d-to-use-firmware_clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0598-dt-Update-v3d-to-use-firmware_clocks.patch
index b67f38782f..b67f38782f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0604-dt-Update-v3d-to-use-firmware_clocks.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0598-dt-Update-v3d-to-use-firmware_clocks.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0605-drm-vc4-Reset-audio-infoframe-on-encoder_enable-if-p.patch b/target/linux/bcm27xx/patches-5.4/950-0599-drm-vc4-Reset-audio-infoframe-on-encoder_enable-if-p.patch
index 56106a4274..56106a4274 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0605-drm-vc4-Reset-audio-infoframe-on-encoder_enable-if-p.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0599-drm-vc4-Reset-audio-infoframe-on-encoder_enable-if-p.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0606-drm-vc4-Set-the-b-frame-marker-to-the-match-ALSA-s-d.patch b/target/linux/bcm27xx/patches-5.4/950-0600-drm-vc4-Set-the-b-frame-marker-to-the-match-ALSA-s-d.patch
index 4827f96023..4827f96023 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0606-drm-vc4-Set-the-b-frame-marker-to-the-match-ALSA-s-d.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0600-drm-vc4-Set-the-b-frame-marker-to-the-match-ALSA-s-d.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0607-dts-Add-reg-names-for-the-HDMI-registers-on-bcm2835.patch b/target/linux/bcm27xx/patches-5.4/950-0601-dts-Add-reg-names-for-the-HDMI-registers-on-bcm2835.patch
index 65e206c181..65e206c181 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0607-dts-Add-reg-names-for-the-HDMI-registers-on-bcm2835.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0601-dts-Add-reg-names-for-the-HDMI-registers-on-bcm2835.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0608-dt-Add-HDMI-audio-dma-values-to-bcm2711.dtsi.patch b/target/linux/bcm27xx/patches-5.4/950-0602-dt-Add-HDMI-audio-dma-values-to-bcm2711.dtsi.patch
index 9a9fd06eeb..9a9fd06eeb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0608-dt-Add-HDMI-audio-dma-values-to-bcm2711.dtsi.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0602-dt-Add-HDMI-audio-dma-values-to-bcm2711.dtsi.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0609-drm-vc4-Use-reg-names-to-configure-HDMI-audio.patch b/target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-Use-reg-names-to-configure-HDMI-audio.patch
index 2504a07083..2504a07083 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0609-drm-vc4-Use-reg-names-to-configure-HDMI-audio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-Use-reg-names-to-configure-HDMI-audio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0610-drm-vc4-Add-audio-initialisation-for-Pi4.patch b/target/linux/bcm27xx/patches-5.4/950-0604-drm-vc4-Add-audio-initialisation-for-Pi4.patch
index 4388099671..4388099671 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0610-drm-vc4-Add-audio-initialisation-for-Pi4.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0604-drm-vc4-Add-audio-initialisation-for-Pi4.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0611-drm-vc4-Enable-audio-on-Pi4.patch b/target/linux/bcm27xx/patches-5.4/950-0605-drm-vc4-Enable-audio-on-Pi4.patch
index b07a815df4..b07a815df4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0611-drm-vc4-Enable-audio-on-Pi4.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0605-drm-vc4-Enable-audio-on-Pi4.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0612-drm-vc4-Alter-the-HDMI-state-machine-clock-calc-to-a.patch b/target/linux/bcm27xx/patches-5.4/950-0606-drm-vc4-Alter-the-HDMI-state-machine-clock-calc-to-a.patch
index dc2d1a2a04..dc2d1a2a04 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0612-drm-vc4-Alter-the-HDMI-state-machine-clock-calc-to-a.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0606-drm-vc4-Alter-the-HDMI-state-machine-clock-calc-to-a.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0613-dtoverlays-Remove-comment-about-vc4-kms-v3d-locking-.patch b/target/linux/bcm27xx/patches-5.4/950-0607-dtoverlays-Remove-comment-about-vc4-kms-v3d-locking-.patch
index a05bf055ff..a05bf055ff 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0613-dtoverlays-Remove-comment-about-vc4-kms-v3d-locking-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0607-dtoverlays-Remove-comment-about-vc4-kms-v3d-locking-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0614-drm-vc4-Kick-the-core-clock-up-during-a-mode-change.patch b/target/linux/bcm27xx/patches-5.4/950-0608-drm-vc4-Kick-the-core-clock-up-during-a-mode-change.patch
index 871d86a7a9..871d86a7a9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0614-drm-vc4-Kick-the-core-clock-up-during-a-mode-change.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0608-drm-vc4-Kick-the-core-clock-up-during-a-mode-change.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0615-drm-vc4-Fixup-for-firmware-KMS.patch b/target/linux/bcm27xx/patches-5.4/950-0609-drm-vc4-Fixup-for-firmware-KMS.patch
index 62080bffec..62080bffec 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0615-drm-vc4-Fixup-for-firmware-KMS.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0609-drm-vc4-Fixup-for-firmware-KMS.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0616-drm-vc4-Fixup-plane-init-within-firmware-kms.patch b/target/linux/bcm27xx/patches-5.4/950-0610-drm-vc4-Fixup-plane-init-within-firmware-kms.patch
index 8edba988f2..8edba988f2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0616-drm-vc4-Fixup-plane-init-within-firmware-kms.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0610-drm-vc4-Fixup-plane-init-within-firmware-kms.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0617-drm-vc4-hdmi-Give-the-HDMI-audio-instances-different.patch b/target/linux/bcm27xx/patches-5.4/950-0611-drm-vc4-hdmi-Give-the-HDMI-audio-instances-different.patch
index aff182dbec..aff182dbec 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0617-drm-vc4-hdmi-Give-the-HDMI-audio-instances-different.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0611-drm-vc4-hdmi-Give-the-HDMI-audio-instances-different.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0618-i2c-brcmstb-The-interrupt-line-is-optional-so-use-pl.patch b/target/linux/bcm27xx/patches-5.4/950-0612-i2c-brcmstb-The-interrupt-line-is-optional-so-use-pl.patch
index 89285ad25c..89285ad25c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0618-i2c-brcmstb-The-interrupt-line-is-optional-so-use-pl.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0612-i2c-brcmstb-The-interrupt-line-is-optional-so-use-pl.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0619-dt-Drop-I2C-for-Pi4-HDMI-interfaces-to-97.5kHz.patch b/target/linux/bcm27xx/patches-5.4/950-0613-dt-Drop-I2C-for-Pi4-HDMI-interfaces-to-97.5kHz.patch
index cd18cd1309..cd18cd1309 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0619-dt-Drop-I2C-for-Pi4-HDMI-interfaces-to-97.5kHz.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0613-dt-Drop-I2C-for-Pi4-HDMI-interfaces-to-97.5kHz.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0620-overlays-Add-missing-rpi-poe-parameters.patch b/target/linux/bcm27xx/patches-5.4/950-0614-overlays-Add-missing-rpi-poe-parameters.patch
index 716678f078..716678f078 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0620-overlays-Add-missing-rpi-poe-parameters.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0614-overlays-Add-missing-rpi-poe-parameters.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0621-vc4_hdmi_phy-Fix-offset-calculation.patch b/target/linux/bcm27xx/patches-5.4/950-0615-vc4_hdmi_phy-Fix-offset-calculation.patch
index 83d8d25e29..83d8d25e29 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0621-vc4_hdmi_phy-Fix-offset-calculation.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0615-vc4_hdmi_phy-Fix-offset-calculation.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0622-overlays-Add-overlay_map.patch b/target/linux/bcm27xx/patches-5.4/950-0616-overlays-Add-overlay_map.patch
index 20f548328c..20f548328c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0622-overlays-Add-overlay_map.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0616-overlays-Add-overlay_map.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0623-overlays-Formally-rename-deprecate-old-overlays.patch b/target/linux/bcm27xx/patches-5.4/950-0617-overlays-Formally-rename-deprecate-old-overlays.patch
index edcb3792af..edcb3792af 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0623-overlays-Formally-rename-deprecate-old-overlays.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0617-overlays-Formally-rename-deprecate-old-overlays.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0624-overlays-Add-vc4-kms-v3d-pi4-to-overlay_map.patch b/target/linux/bcm27xx/patches-5.4/950-0618-overlays-Add-vc4-kms-v3d-pi4-to-overlay_map.patch
index 4fd5879ec8..4fd5879ec8 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0624-overlays-Add-vc4-kms-v3d-pi4-to-overlay_map.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0618-overlays-Add-vc4-kms-v3d-pi4-to-overlay_map.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0625-Add-upstream-and-upstream-pi4-to-overlay_map.patch b/target/linux/bcm27xx/patches-5.4/950-0619-Add-upstream-and-upstream-pi4-to-overlay_map.patch
index e76367b9da..e76367b9da 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0625-Add-upstream-and-upstream-pi4-to-overlay_map.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0619-Add-upstream-and-upstream-pi4-to-overlay_map.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0626-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch b/target/linux/bcm27xx/patches-5.4/950-0620-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch
index c0422f4ed3..c0422f4ed3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0626-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0620-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0627-Add-support-for-the-AudioInjector.net-Isolated-sound.patch b/target/linux/bcm27xx/patches-5.4/950-0621-Add-support-for-the-AudioInjector.net-Isolated-sound.patch
index e35806962e..e35806962e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0627-Add-support-for-the-AudioInjector.net-Isolated-sound.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0621-Add-support-for-the-AudioInjector.net-Isolated-sound.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0628-overlays-Fix-dtc-warnings-in-i2c-gpio.patch b/target/linux/bcm27xx/patches-5.4/950-0622-overlays-Fix-dtc-warnings-in-i2c-gpio.patch
index 2da57b81de..2da57b81de 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0628-overlays-Fix-dtc-warnings-in-i2c-gpio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0622-overlays-Fix-dtc-warnings-in-i2c-gpio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0629-kbuild-Disable-gcc-plugins.patch b/target/linux/bcm27xx/patches-5.4/950-0623-kbuild-Disable-gcc-plugins.patch
index 66091ca591..66091ca591 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0629-kbuild-Disable-gcc-plugins.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0623-kbuild-Disable-gcc-plugins.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0630-ASoC-ma120x0p-Add-96KHz-rate-support.patch b/target/linux/bcm27xx/patches-5.4/950-0624-ASoC-ma120x0p-Add-96KHz-rate-support.patch
index a5aee43aef..a5aee43aef 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0630-ASoC-ma120x0p-Add-96KHz-rate-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0624-ASoC-ma120x0p-Add-96KHz-rate-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0631-arm64-mm-reserve-CMA-and-crashkernel-in-ZONE_DMA32.patch b/target/linux/bcm27xx/patches-5.4/950-0625-arm64-mm-reserve-CMA-and-crashkernel-in-ZONE_DMA32.patch
index e1a340ec91..e1a340ec91 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0631-arm64-mm-reserve-CMA-and-crashkernel-in-ZONE_DMA32.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0625-arm64-mm-reserve-CMA-and-crashkernel-in-ZONE_DMA32.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0632-arm64-mm-Fix-initialisation-of-DMA-zones-on-non-NUMA.patch b/target/linux/bcm27xx/patches-5.4/950-0626-arm64-mm-Fix-initialisation-of-DMA-zones-on-non-NUMA.patch
index 0f4f09ee1c..0f4f09ee1c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0632-arm64-mm-Fix-initialisation-of-DMA-zones-on-non-NUMA.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0626-arm64-mm-Fix-initialisation-of-DMA-zones-on-non-NUMA.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0633-ARM-dts-bcm283x-Unify-CMA-configuration.patch b/target/linux/bcm27xx/patches-5.4/950-0627-ARM-dts-bcm283x-Unify-CMA-configuration.patch
index a0dfcb3325..a0dfcb3325 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0633-ARM-dts-bcm283x-Unify-CMA-configuration.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0627-ARM-dts-bcm283x-Unify-CMA-configuration.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0634-dma-contiguous-CMA-give-precedence-to-cmdline.patch b/target/linux/bcm27xx/patches-5.4/950-0628-dma-contiguous-CMA-give-precedence-to-cmdline.patch
index d3354bb9e1..d3354bb9e1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0634-dma-contiguous-CMA-give-precedence-to-cmdline.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0628-dma-contiguous-CMA-give-precedence-to-cmdline.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0635-ARM-dts-Use-upstream-CMA-configuration.patch b/target/linux/bcm27xx/patches-5.4/950-0629-ARM-dts-Use-upstream-CMA-configuration.patch
index fb4fe893c0..fb4fe893c0 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0635-ARM-dts-Use-upstream-CMA-configuration.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0629-ARM-dts-Use-upstream-CMA-configuration.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0636-ARM-dts-overlays-Unify-overlay-CMA-handling.patch b/target/linux/bcm27xx/patches-5.4/950-0630-ARM-dts-overlays-Unify-overlay-CMA-handling.patch
index 3c0f1e4388..3c0f1e4388 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0636-ARM-dts-overlays-Unify-overlay-CMA-handling.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0630-ARM-dts-overlays-Unify-overlay-CMA-handling.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0637-ARM-dts-bcm283x-Fix-vc4-s-firmware-bus-DMA-limitatio.patch b/target/linux/bcm27xx/patches-5.4/950-0631-ARM-dts-bcm283x-Fix-vc4-s-firmware-bus-DMA-limitatio.patch
index 31840e5437..31840e5437 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0637-ARM-dts-bcm283x-Fix-vc4-s-firmware-bus-DMA-limitatio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0631-ARM-dts-bcm283x-Fix-vc4-s-firmware-bus-DMA-limitatio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0638-ARM-dts-bcm2711-Restrict-CMA-to-first-768MB.patch b/target/linux/bcm27xx/patches-5.4/950-0632-ARM-dts-bcm2711-Restrict-CMA-to-first-768MB.patch
index 9a1e29e7d1..9a1e29e7d1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0638-ARM-dts-bcm2711-Restrict-CMA-to-first-768MB.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0632-ARM-dts-bcm2711-Restrict-CMA-to-first-768MB.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0639-ARM-dts-Extend-SCB-bus-address-range.patch b/target/linux/bcm27xx/patches-5.4/950-0633-ARM-dts-Extend-SCB-bus-address-range.patch
index 8eb2b16b10..8eb2b16b10 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0639-ARM-dts-Extend-SCB-bus-address-range.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0633-ARM-dts-Extend-SCB-bus-address-range.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0640-dts-bcm2711-Move-emmc2-to-its-own-bus.patch b/target/linux/bcm27xx/patches-5.4/950-0634-dts-bcm2711-Move-emmc2-to-its-own-bus.patch
index 52cf03a382..52cf03a382 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0640-dts-bcm2711-Move-emmc2-to-its-own-bus.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0634-dts-bcm2711-Move-emmc2-to-its-own-bus.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0641-drm-vc4-hdmi-Silence-pixel-clock-error-on-EPROBE_DEF.patch b/target/linux/bcm27xx/patches-5.4/950-0635-drm-vc4-hdmi-Silence-pixel-clock-error-on-EPROBE_DEF.patch
index 0580fc8b93..0580fc8b93 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0641-drm-vc4-hdmi-Silence-pixel-clock-error-on-EPROBE_DEF.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0635-drm-vc4-hdmi-Silence-pixel-clock-error-on-EPROBE_DEF.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0643-Fixes-a-problem-with-clock-settings-of-HiFiBerry-DAC.patch b/target/linux/bcm27xx/patches-5.4/950-0636-Fixes-a-problem-with-clock-settings-of-HiFiBerry-DAC.patch
index f1427ae71f..f1427ae71f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0643-Fixes-a-problem-with-clock-settings-of-HiFiBerry-DAC.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0636-Fixes-a-problem-with-clock-settings-of-HiFiBerry-DAC.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0644-Documentation-media-Update-sub-device-API-intro.patch b/target/linux/bcm27xx/patches-5.4/950-0637-Documentation-media-Update-sub-device-API-intro.patch
index f843a83a7d..f843a83a7d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0644-Documentation-media-Update-sub-device-API-intro.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0637-Documentation-media-Update-sub-device-API-intro.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0645-Documentation-media-Document-read-only-subdevice.patch b/target/linux/bcm27xx/patches-5.4/950-0638-Documentation-media-Document-read-only-subdevice.patch
index 1983334ae1..1983334ae1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0645-Documentation-media-Document-read-only-subdevice.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0638-Documentation-media-Document-read-only-subdevice.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0646-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch b/target/linux/bcm27xx/patches-5.4/950-0639-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch
index 47f2551ec7..47f2551ec7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0646-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0639-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0647-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch b/target/linux/bcm27xx/patches-5.4/950-0640-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch
index e142f598ad..e142f598ad 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0647-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0640-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0648-media-uapi-v4l2-core-Add-sensor-ancillary-data-V4L2-.patch b/target/linux/bcm27xx/patches-5.4/950-0641-media-uapi-v4l2-core-Add-sensor-ancillary-data-V4L2-.patch
index 69414e381c..69414e381c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0648-media-uapi-v4l2-core-Add-sensor-ancillary-data-V4L2-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0641-media-uapi-v4l2-core-Add-sensor-ancillary-data-V4L2-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0649-media-uapi-Add-MEDIA_BUS_FMT_SENSOR_DATA-media-bus-f.patch b/target/linux/bcm27xx/patches-5.4/950-0642-media-uapi-Add-MEDIA_BUS_FMT_SENSOR_DATA-media-bus-f.patch
index 65162cc5d5..65162cc5d5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0649-media-uapi-Add-MEDIA_BUS_FMT_SENSOR_DATA-media-bus-f.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0642-media-uapi-Add-MEDIA_BUS_FMT_SENSOR_DATA-media-bus-f.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0650-media-bcm2835-unicam-Add-support-for-mulitple-device.patch b/target/linux/bcm27xx/patches-5.4/950-0643-media-bcm2835-unicam-Add-support-for-mulitple-device.patch
index 315feff5d3..315feff5d3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0650-media-bcm2835-unicam-Add-support-for-mulitple-device.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0643-media-bcm2835-unicam-Add-support-for-mulitple-device.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0651-media-bcm2835-unicam-Add-embedded-data-node.patch b/target/linux/bcm27xx/patches-5.4/950-0644-media-bcm2835-unicam-Add-embedded-data-node.patch
index a163a6f1a5..a163a6f1a5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0651-media-bcm2835-unicam-Add-embedded-data-node.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0644-media-bcm2835-unicam-Add-embedded-data-node.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0652-media-bcm2835-unicam-Use-dummy-buffer-if-none-have-b.patch b/target/linux/bcm27xx/patches-5.4/950-0645-media-bcm2835-unicam-Use-dummy-buffer-if-none-have-b.patch
index 836ced8a04..836ced8a04 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0652-media-bcm2835-unicam-Use-dummy-buffer-if-none-have-b.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0645-media-bcm2835-unicam-Use-dummy-buffer-if-none-have-b.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0653-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch b/target/linux/bcm27xx/patches-5.4/950-0646-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch
index 42d22c3003..42d22c3003 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0653-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0646-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0654-media-i2c-imx219-Fix-power-sequence.patch b/target/linux/bcm27xx/patches-5.4/950-0647-media-i2c-imx219-Fix-power-sequence.patch
index b85d917878..b85d917878 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0654-media-i2c-imx219-Fix-power-sequence.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0647-media-i2c-imx219-Fix-power-sequence.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0655-media-i2c-imx219-Add-support-for-RAW8-bit-bayer-form.patch b/target/linux/bcm27xx/patches-5.4/950-0648-media-i2c-imx219-Add-support-for-RAW8-bit-bayer-form.patch
index 552516bd67..552516bd67 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0655-media-i2c-imx219-Add-support-for-RAW8-bit-bayer-form.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0648-media-i2c-imx219-Add-support-for-RAW8-bit-bayer-form.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0656-media-i2c-imx219-Add-support-for-cropped-640x480-res.patch b/target/linux/bcm27xx/patches-5.4/950-0649-media-i2c-imx219-Add-support-for-cropped-640x480-res.patch
index 3ad377dfbe..3ad377dfbe 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0656-media-i2c-imx219-Add-support-for-cropped-640x480-res.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0649-media-i2c-imx219-Add-support-for-cropped-640x480-res.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0657-media-i2c-imx219-Fix-a-bug-in-imx219_enum_frame_size.patch b/target/linux/bcm27xx/patches-5.4/950-0650-media-i2c-imx219-Fix-a-bug-in-imx219_enum_frame_size.patch
index ef8eff6c00..ef8eff6c00 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0657-media-i2c-imx219-Fix-a-bug-in-imx219_enum_frame_size.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0650-media-i2c-imx219-Fix-a-bug-in-imx219_enum_frame_size.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0658-media-bcm2835-unicam-Disable-event-related-ioctls-on.patch b/target/linux/bcm27xx/patches-5.4/950-0651-media-bcm2835-unicam-Disable-event-related-ioctls-on.patch
index cb36ce2d96..cb36ce2d96 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0658-media-bcm2835-unicam-Disable-event-related-ioctls-on.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0651-media-bcm2835-unicam-Disable-event-related-ioctls-on.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0659-media-bcm2835-unicam-Add-support-for-the-FRAME_SYNC-.patch b/target/linux/bcm27xx/patches-5.4/950-0652-media-bcm2835-unicam-Add-support-for-the-FRAME_SYNC-.patch
index 544d597a35..544d597a35 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0659-media-bcm2835-unicam-Add-support-for-the-FRAME_SYNC-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0652-media-bcm2835-unicam-Add-support-for-the-FRAME_SYNC-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0660-Revert-firmware-raspberrypi-register-clk-device.patch b/target/linux/bcm27xx/patches-5.4/950-0653-Revert-firmware-raspberrypi-register-clk-device.patch
index 01533d1f3f..01533d1f3f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0660-Revert-firmware-raspberrypi-register-clk-device.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0653-Revert-firmware-raspberrypi-register-clk-device.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0661-media-imx219-Advertise-embedded-data-node-on-media-p.patch b/target/linux/bcm27xx/patches-5.4/950-0654-media-imx219-Advertise-embedded-data-node-on-media-p.patch
index c4c25d1512..c4c25d1512 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0661-media-imx219-Advertise-embedded-data-node-on-media-p.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0654-media-imx219-Advertise-embedded-data-node-on-media-p.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0662-dts-bcm2711-EMMC2-can-address-the-whole-first-GB.patch b/target/linux/bcm27xx/patches-5.4/950-0655-dts-bcm2711-EMMC2-can-address-the-whole-first-GB.patch
index 4c5e50636c..4c5e50636c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0662-dts-bcm2711-EMMC2-can-address-the-whole-first-GB.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0655-dts-bcm2711-EMMC2-can-address-the-whole-first-GB.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0663-driver-char-rpivid-Remove-legacy-name-support.patch b/target/linux/bcm27xx/patches-5.4/950-0656-driver-char-rpivid-Remove-legacy-name-support.patch
index a3896be439..a3896be439 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0663-driver-char-rpivid-Remove-legacy-name-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0656-driver-char-rpivid-Remove-legacy-name-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0664-driver-char-rpivid-Don-t-map-more-than-wanted.patch b/target/linux/bcm27xx/patches-5.4/950-0657-driver-char-rpivid-Don-t-map-more-than-wanted.patch
index afc1a5a6a8..afc1a5a6a8 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0664-driver-char-rpivid-Don-t-map-more-than-wanted.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0657-driver-char-rpivid-Don-t-map-more-than-wanted.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0665-dt-Implement-an-I2C-pinctrl-mux-for-BSC0.patch b/target/linux/bcm27xx/patches-5.4/950-0658-dt-Implement-an-I2C-pinctrl-mux-for-BSC0.patch
index 002ad8686e..002ad8686e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0665-dt-Implement-an-I2C-pinctrl-mux-for-BSC0.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0658-dt-Implement-an-I2C-pinctrl-mux-for-BSC0.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0666-dtoverlays-Update-CSI-overlays-to-use-i2c_csi_dsi.patch b/target/linux/bcm27xx/patches-5.4/950-0659-dtoverlays-Update-CSI-overlays-to-use-i2c_csi_dsi.patch
index f6b6340c7f..f6b6340c7f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0666-dtoverlays-Update-CSI-overlays-to-use-i2c_csi_dsi.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0659-dtoverlays-Update-CSI-overlays-to-use-i2c_csi_dsi.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0667-dt-Update-all-mainline-bcm283x-dt-files-for-i2c0-pin.patch b/target/linux/bcm27xx/patches-5.4/950-0660-dt-Update-all-mainline-bcm283x-dt-files-for-i2c0-pin.patch
index f5e4e4b008..f5e4e4b008 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0667-dt-Update-all-mainline-bcm283x-dt-files-for-i2c0-pin.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0660-dt-Update-all-mainline-bcm283x-dt-files-for-i2c0-pin.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0668-ARM-dts-Create-bcm2708-rpi-b-rev1.dts.patch b/target/linux/bcm27xx/patches-5.4/950-0661-ARM-dts-Create-bcm2708-rpi-b-rev1.dts.patch
index 42067a7816..42067a7816 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0668-ARM-dts-Create-bcm2708-rpi-b-rev1.dts.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0661-ARM-dts-Create-bcm2708-rpi-b-rev1.dts.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0669-dts-bcm2711-set-size-cells-2.patch b/target/linux/bcm27xx/patches-5.4/950-0662-dts-bcm2711-set-size-cells-2.patch
index fa5a2d4f54..fa5a2d4f54 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0669-dts-bcm2711-set-size-cells-2.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0662-dts-bcm2711-set-size-cells-2.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0670-dts-bcm2711-add-High-Peripheral-mode-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0663-dts-bcm2711-add-High-Peripheral-mode-overlay.patch
index e24f5de000..e24f5de000 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0670-dts-bcm2711-add-High-Peripheral-mode-overlay.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0663-dts-bcm2711-add-High-Peripheral-mode-overlay.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0671-Revert-spi-spidev-Fix-CS-polarity-if-GPIO-descriptor.patch b/target/linux/bcm27xx/patches-5.4/950-0664-Revert-spi-spidev-Fix-CS-polarity-if-GPIO-descriptor.patch
index 00bbe98117..00bbe98117 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0671-Revert-spi-spidev-Fix-CS-polarity-if-GPIO-descriptor.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0664-Revert-spi-spidev-Fix-CS-polarity-if-GPIO-descriptor.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0672-spi-use_gpio_descriptor-fixup-moved-to-spi_setup.patch b/target/linux/bcm27xx/patches-5.4/950-0665-spi-use_gpio_descriptor-fixup-moved-to-spi_setup.patch
index 8792faa0c9..8792faa0c9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0672-spi-use_gpio_descriptor-fixup-moved-to-spi_setup.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0665-spi-use_gpio_descriptor-fixup-moved-to-spi_setup.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0673-overlays-rpivid-v4l2-also-needs-size-cells-2.patch b/target/linux/bcm27xx/patches-5.4/950-0666-overlays-rpivid-v4l2-also-needs-size-cells-2.patch
index 4a1757dd44..4a1757dd44 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0673-overlays-rpivid-v4l2-also-needs-size-cells-2.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0666-overlays-rpivid-v4l2-also-needs-size-cells-2.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0674-media-bcm2835-unicam-Re-fetch-mbus-code-from-subdev-.patch b/target/linux/bcm27xx/patches-5.4/950-0667-media-bcm2835-unicam-Re-fetch-mbus-code-from-subdev-.patch
index 4d43c97e56..4d43c97e56 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0674-media-bcm2835-unicam-Re-fetch-mbus-code-from-subdev-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0667-media-bcm2835-unicam-Re-fetch-mbus-code-from-subdev-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0675-uapi-bcm2835-isp-Add-bcm2835-isp-uapi-header-file.patch b/target/linux/bcm27xx/patches-5.4/950-0668-uapi-bcm2835-isp-Add-bcm2835-isp-uapi-header-file.patch
index 9f41783b46..9f41783b46 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0675-uapi-bcm2835-isp-Add-bcm2835-isp-uapi-header-file.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0668-uapi-bcm2835-isp-Add-bcm2835-isp-uapi-header-file.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0676-media-uapi-v4l2-core-Add-ISP-statistics-output-V4L2-.patch b/target/linux/bcm27xx/patches-5.4/950-0669-media-uapi-v4l2-core-Add-ISP-statistics-output-V4L2-.patch
index 082dff510c..082dff510c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0676-media-uapi-v4l2-core-Add-ISP-statistics-output-V4L2-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0669-media-uapi-v4l2-core-Add-ISP-statistics-output-V4L2-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0677-media-uapi-v4l-ctrls-Add-CID-base-for-the-bcm2835-is.patch b/target/linux/bcm27xx/patches-5.4/950-0670-media-uapi-v4l-ctrls-Add-CID-base-for-the-bcm2835-is.patch
index 96e6e124af..96e6e124af 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0677-media-uapi-v4l-ctrls-Add-CID-base-for-the-bcm2835-is.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0670-media-uapi-v4l-ctrls-Add-CID-base-for-the-bcm2835-is.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0678-staging-mmal-vchiq-Fix-formatting-errors-in-mmal_par.patch b/target/linux/bcm27xx/patches-5.4/950-0671-staging-mmal-vchiq-Fix-formatting-errors-in-mmal_par.patch
index f428ce5e9f..f428ce5e9f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0678-staging-mmal-vchiq-Fix-formatting-errors-in-mmal_par.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0671-staging-mmal-vchiq-Fix-formatting-errors-in-mmal_par.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0679-staging-vc04_services-ISP-Add-a-more-complex-ISP-pro.patch b/target/linux/bcm27xx/patches-5.4/950-0672-staging-vc04_services-ISP-Add-a-more-complex-ISP-pro.patch
index 38015cc98a..38015cc98a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0679-staging-vc04_services-ISP-Add-a-more-complex-ISP-pro.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0672-staging-vc04_services-ISP-Add-a-more-complex-ISP-pro.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0680-staging-vchiq-Load-bcm2835_isp-driver-from-vchiq.patch b/target/linux/bcm27xx/patches-5.4/950-0673-staging-vchiq-Load-bcm2835_isp-driver-from-vchiq.patch
index 70fe392a3b..70fe392a3b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0680-staging-vchiq-Load-bcm2835_isp-driver-from-vchiq.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0673-staging-vchiq-Load-bcm2835_isp-driver-from-vchiq.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0681-vc4_hvs-Mark-core-clock-as-optional.patch b/target/linux/bcm27xx/patches-5.4/950-0674-vc4_hvs-Mark-core-clock-as-optional.patch
index 816ca3c589..816ca3c589 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0681-vc4_hvs-Mark-core-clock-as-optional.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0674-vc4_hvs-Mark-core-clock-as-optional.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0682-vc4_hdmi-BCM2835-requires-a-fixed-hsm-clock-for-CEC-.patch b/target/linux/bcm27xx/patches-5.4/950-0675-vc4_hdmi-BCM2835-requires-a-fixed-hsm-clock-for-CEC-.patch
index e5ffc3e96f..e5ffc3e96f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0682-vc4_hdmi-BCM2835-requires-a-fixed-hsm-clock-for-CEC-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0675-vc4_hdmi-BCM2835-requires-a-fixed-hsm-clock-for-CEC-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0683-media-i2c-imx219-Implement-get_selection.patch b/target/linux/bcm27xx/patches-5.4/950-0676-media-i2c-imx219-Implement-get_selection.patch
index cb7a0af605..cb7a0af605 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0683-media-i2c-imx219-Implement-get_selection.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0676-media-i2c-imx219-Implement-get_selection.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0684-media-i2c-ov5647-Add-support-for-g_selection-to-refl.patch b/target/linux/bcm27xx/patches-5.4/950-0677-media-i2c-ov5647-Add-support-for-g_selection-to-refl.patch
index 66715a108e..66715a108e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0684-media-i2c-ov5647-Add-support-for-g_selection-to-refl.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0677-media-i2c-ov5647-Add-support-for-g_selection-to-refl.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0685-media-i2c-ov5467-Fixup-error-path-to-release-mutex.patch b/target/linux/bcm27xx/patches-5.4/950-0678-media-i2c-ov5467-Fixup-error-path-to-release-mutex.patch
index d8a0104739..d8a0104739 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0685-media-i2c-ov5467-Fixup-error-path-to-release-mutex.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0678-media-i2c-ov5467-Fixup-error-path-to-release-mutex.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0686-media-i2c-ov5647-Support-V4L2_CID_PIXEL_RATE.patch b/target/linux/bcm27xx/patches-5.4/950-0679-media-i2c-ov5647-Support-V4L2_CID_PIXEL_RATE.patch
index ce16832d35..ce16832d35 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0686-media-i2c-ov5647-Support-V4L2_CID_PIXEL_RATE.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0679-media-i2c-ov5647-Support-V4L2_CID_PIXEL_RATE.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0687-media-i2c-ov5647-Set-V4L2_SUBDEV_FL_HAS_EVENTS-flag.patch b/target/linux/bcm27xx/patches-5.4/950-0680-media-i2c-ov5647-Set-V4L2_SUBDEV_FL_HAS_EVENTS-flag.patch
index b7a3f19753..b7a3f19753 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0687-media-i2c-ov5647-Set-V4L2_SUBDEV_FL_HAS_EVENTS-flag.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0680-media-i2c-ov5647-Set-V4L2_SUBDEV_FL_HAS_EVENTS-flag.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0688-media-i2c-ov5647-Add-support-for-V4L2_CID_VBLANK.patch b/target/linux/bcm27xx/patches-5.4/950-0681-media-i2c-ov5647-Add-support-for-V4L2_CID_VBLANK.patch
index 85d63cf1a3..85d63cf1a3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0688-media-i2c-ov5647-Add-support-for-V4L2_CID_VBLANK.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0681-media-i2c-ov5647-Add-support-for-V4L2_CID_VBLANK.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0689-media-i2c-ov5647-Neither-analogue-gain-nor-exposure-.patch b/target/linux/bcm27xx/patches-5.4/950-0682-media-i2c-ov5647-Neither-analogue-gain-nor-exposure-.patch
index 039809e94e..039809e94e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0689-media-i2c-ov5647-Neither-analogue-gain-nor-exposure-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0682-media-i2c-ov5647-Neither-analogue-gain-nor-exposure-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0690-media-i2c-ov5647-Use-member-names-in-mode-tables.patch b/target/linux/bcm27xx/patches-5.4/950-0683-media-i2c-ov5647-Use-member-names-in-mode-tables.patch
index d8ef700a59..d8ef700a59 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0690-media-i2c-ov5647-Use-member-names-in-mode-tables.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0683-media-i2c-ov5647-Use-member-names-in-mode-tables.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0691-media-i2c-ov5647-Advertise-the-correct-exposure-rang.patch b/target/linux/bcm27xx/patches-5.4/950-0684-media-i2c-ov5647-Advertise-the-correct-exposure-rang.patch
index 9b874485a8..9b874485a8 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0691-media-i2c-ov5647-Advertise-the-correct-exposure-rang.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0684-media-i2c-ov5647-Advertise-the-correct-exposure-rang.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0692-media-i2c-imx219-Declare-that-the-driver-can-create-.patch b/target/linux/bcm27xx/patches-5.4/950-0685-media-i2c-imx219-Declare-that-the-driver-can-create-.patch
index fa700a81a3..fa700a81a3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0692-media-i2c-imx219-Declare-that-the-driver-can-create-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0685-media-i2c-imx219-Declare-that-the-driver-can-create-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0693-media-bcm2835-unicam-Add-support-for-VIDIOC_-S-G-_SE.patch b/target/linux/bcm27xx/patches-5.4/950-0686-media-bcm2835-unicam-Add-support-for-VIDIOC_-S-G-_SE.patch
index b30d106f6e..b30d106f6e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0693-media-bcm2835-unicam-Add-support-for-VIDIOC_-S-G-_SE.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0686-media-bcm2835-unicam-Add-support-for-VIDIOC_-S-G-_SE.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0694-media-bcm2835-unicam-Do-not-stop-streaming-in-unicam.patch b/target/linux/bcm27xx/patches-5.4/950-0687-media-bcm2835-unicam-Do-not-stop-streaming-in-unicam.patch
index 74abba4ac9..74abba4ac9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0694-media-bcm2835-unicam-Do-not-stop-streaming-in-unicam.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0687-media-bcm2835-unicam-Do-not-stop-streaming-in-unicam.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0695-media-bcm2835-unicam-Fix-reference-counting-in-unica.patch b/target/linux/bcm27xx/patches-5.4/950-0688-media-bcm2835-unicam-Fix-reference-counting-in-unica.patch
index ba979632ae..ba979632ae 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0695-media-bcm2835-unicam-Fix-reference-counting-in-unica.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0688-media-bcm2835-unicam-Fix-reference-counting-in-unica.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0696-staging-vc04_services-ISP-Add-enum_framesizes-ioctl.patch b/target/linux/bcm27xx/patches-5.4/950-0689-staging-vc04_services-ISP-Add-enum_framesizes-ioctl.patch
index 1673bde514..1673bde514 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0696-staging-vc04_services-ISP-Add-enum_framesizes-ioctl.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0689-staging-vc04_services-ISP-Add-enum_framesizes-ioctl.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0697-SQUASH-spi-Demote-SPI_CS_HIGH-warning-to-KERN_DEBUG.patch b/target/linux/bcm27xx/patches-5.4/950-0690-SQUASH-spi-Demote-SPI_CS_HIGH-warning-to-KERN_DEBUG.patch
index e4b2e7ed2a..e4b2e7ed2a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0697-SQUASH-spi-Demote-SPI_CS_HIGH-warning-to-KERN_DEBUG.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0690-SQUASH-spi-Demote-SPI_CS_HIGH-warning-to-KERN_DEBUG.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0698-bcm2835-dma-Add-proper-40-bit-DMA-support.patch b/target/linux/bcm27xx/patches-5.4/950-0691-bcm2835-dma-Add-proper-40-bit-DMA-support.patch
index 3fb47589ee..3fb47589ee 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0698-bcm2835-dma-Add-proper-40-bit-DMA-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0691-bcm2835-dma-Add-proper-40-bit-DMA-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0699-ARM-dts-bcm2711-Allow-40-bit-DMA-for-SPI.patch b/target/linux/bcm27xx/patches-5.4/950-0692-ARM-dts-bcm2711-Allow-40-bit-DMA-for-SPI.patch
index ac6543fe4f..ac6543fe4f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0699-ARM-dts-bcm2711-Allow-40-bit-DMA-for-SPI.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0692-ARM-dts-bcm2711-Allow-40-bit-DMA-for-SPI.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0700-overlays-Make-the-i2c-gpio-overlay-safe-again.patch b/target/linux/bcm27xx/patches-5.4/950-0693-overlays-Make-the-i2c-gpio-overlay-safe-again.patch
index 537ca5dc55..537ca5dc55 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0700-overlays-Make-the-i2c-gpio-overlay-safe-again.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0693-overlays-Make-the-i2c-gpio-overlay-safe-again.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0701-staging-vc04_services-isp-Remove-duplicated-initiali.patch b/target/linux/bcm27xx/patches-5.4/950-0694-staging-vc04_services-isp-Remove-duplicated-initiali.patch
index d2b0bf1f2f..d2b0bf1f2f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0701-staging-vc04_services-isp-Remove-duplicated-initiali.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0694-staging-vc04_services-isp-Remove-duplicated-initiali.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0702-staging-vc04_services-isp-Make-all-references-to-bcm.patch b/target/linux/bcm27xx/patches-5.4/950-0695-staging-vc04_services-isp-Make-all-references-to-bcm.patch
index 97ca47bcd0..97ca47bcd0 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0702-staging-vc04_services-isp-Make-all-references-to-bcm.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0695-staging-vc04_services-isp-Make-all-references-to-bcm.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0704-vc4_hdmi_phy-Fix-typo-in-phy_get_cp_current.patch b/target/linux/bcm27xx/patches-5.4/950-0696-vc4_hdmi_phy-Fix-typo-in-phy_get_cp_current.patch
index 45429d506d..45429d506d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0704-vc4_hdmi_phy-Fix-typo-in-phy_get_cp_current.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0696-vc4_hdmi_phy-Fix-typo-in-phy_get_cp_current.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0705-overlays-Make-use-of-intra-overlay-fragments.patch b/target/linux/bcm27xx/patches-5.4/950-0697-overlays-Make-use-of-intra-overlay-fragments.patch
index 628bec3f33..628bec3f33 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0705-overlays-Make-use-of-intra-overlay-fragments.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0697-overlays-Make-use-of-intra-overlay-fragments.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0706-media-i2c-tc358743-Fix-fallthrough-warning.patch b/target/linux/bcm27xx/patches-5.4/950-0698-media-i2c-tc358743-Fix-fallthrough-warning.patch
index 26c1f95bf2..26c1f95bf2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0706-media-i2c-tc358743-Fix-fallthrough-warning.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0698-media-i2c-tc358743-Fix-fallthrough-warning.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0707-media-bcm2835-unicam-Fix-uninitialized-warning.patch b/target/linux/bcm27xx/patches-5.4/950-0699-media-bcm2835-unicam-Fix-uninitialized-warning.patch
index 2186d7b802..2186d7b802 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0707-media-bcm2835-unicam-Fix-uninitialized-warning.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0699-media-bcm2835-unicam-Fix-uninitialized-warning.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0708-video-bcm2708_fb-Disable-FB-if-no-displays-found.patch b/target/linux/bcm27xx/patches-5.4/950-0700-video-bcm2708_fb-Disable-FB-if-no-displays-found.patch
index 90cb5e276e..90cb5e276e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0708-video-bcm2708_fb-Disable-FB-if-no-displays-found.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0700-video-bcm2708_fb-Disable-FB-if-no-displays-found.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0709-overlays-sc16is752-spi1-Add-xtal-parameter.patch b/target/linux/bcm27xx/patches-5.4/950-0701-overlays-sc16is752-spi1-Add-xtal-parameter.patch
index 582c32aa90..582c32aa90 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0709-overlays-sc16is752-spi1-Add-xtal-parameter.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0701-overlays-sc16is752-spi1-Add-xtal-parameter.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0710-vc4_hdmi-Fix-register-offset-when-sending-longer-CEC.patch b/target/linux/bcm27xx/patches-5.4/950-0702-vc4_hdmi-Fix-register-offset-when-sending-longer-CEC.patch
index d192565145..d192565145 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0710-vc4_hdmi-Fix-register-offset-when-sending-longer-CEC.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0702-vc4_hdmi-Fix-register-offset-when-sending-longer-CEC.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0703-overlays-gpio-keys-Avoid-open-drain-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0703-overlays-gpio-keys-Avoid-open-drain-warnings.patch
deleted file mode 100644
index 579b3b61b6..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0703-overlays-gpio-keys-Avoid-open-drain-warnings.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From ae10c15867d9a5b85eefaf11333bd30473af4b2b Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.com>
-Date: Sat, 2 May 2020 13:43:06 +0100
-Subject: [PATCH] overlays: gpio-keys: Avoid open-drain warnings
-
-The i2c-gpio driver expects to use a GPIO in open-drain mode. Failure
-to configure it in that way causes alarming warnings in the kernel log.
-The BCM283x and BCM2711 GPIO blocks don't support open-drain mode,
-but i2c-gpio works anyway. Silence the warning by declaring that
-open-drain mode has been enabled by other means.
-
-See: https://github.com/raspberrypi/firmware/issues/1381
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.com>
----
- arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts
-+++ b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts
-@@ -16,6 +16,8 @@
- &gpio 24 0 /* scl */
- >;
- i2c-gpio,delay-us = <2>; /* ~100 kHz */
-+ i2c-gpio,sda-open-drain;
-+ i2c-gpio,scl-open-drain;
- #address-cells = <1>;
- #size-cells = <0>;
- };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0711-vc4_hdmi-Fix-up-CEC-registers.patch b/target/linux/bcm27xx/patches-5.4/950-0703-vc4_hdmi-Fix-up-CEC-registers.patch
index a00aee15bd..a00aee15bd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0711-vc4_hdmi-Fix-up-CEC-registers.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0703-vc4_hdmi-Fix-up-CEC-registers.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0712-vc4_hdmi_regs-Add-Intr2-register-block.patch b/target/linux/bcm27xx/patches-5.4/950-0704-vc4_hdmi_regs-Add-Intr2-register-block.patch
index e3299acf9d..e3299acf9d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0712-vc4_hdmi_regs-Add-Intr2-register-block.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0704-vc4_hdmi_regs-Add-Intr2-register-block.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0713-vc4_hdmi_regs-Make-interrupt-mask-variant-specific.patch b/target/linux/bcm27xx/patches-5.4/950-0705-vc4_hdmi_regs-Make-interrupt-mask-variant-specific.patch
index f2a30c6443..f2a30c6443 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0713-vc4_hdmi_regs-Make-interrupt-mask-variant-specific.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0705-vc4_hdmi_regs-Make-interrupt-mask-variant-specific.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0714-vc4_hdmi-Make-irq-shared.patch b/target/linux/bcm27xx/patches-5.4/950-0706-vc4_hdmi-Make-irq-shared.patch
index 423812324b..423812324b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0714-vc4_hdmi-Make-irq-shared.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0706-vc4_hdmi-Make-irq-shared.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0715-vc4_hdmi-Adjust-CEC-ref-clock-based-on-its-input-clo.patch b/target/linux/bcm27xx/patches-5.4/950-0707-vc4_hdmi-Adjust-CEC-ref-clock-based-on-its-input-clo.patch
index f6145e4ff5..f6145e4ff5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0715-vc4_hdmi-Adjust-CEC-ref-clock-based-on-its-input-clo.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0707-vc4_hdmi-Adjust-CEC-ref-clock-based-on-its-input-clo.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0716-vc4_hdmi-Remove-cec_available-flag-as-always-support.patch b/target/linux/bcm27xx/patches-5.4/950-0708-vc4_hdmi-Remove-cec_available-flag-as-always-support.patch
index 7713eed5b1..7713eed5b1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0716-vc4_hdmi-Remove-cec_available-flag-as-always-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0708-vc4_hdmi-Remove-cec_available-flag-as-always-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0717-overlays-tc358743-Use-intra-overlay-fragments.patch b/target/linux/bcm27xx/patches-5.4/950-0709-overlays-tc358743-Use-intra-overlay-fragments.patch
index 5bfa6bc60a..5bfa6bc60a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0717-overlays-tc358743-Use-intra-overlay-fragments.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0709-overlays-tc358743-Use-intra-overlay-fragments.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0718-overlays-Move-fixed-clock-nodes-to-the-root.patch b/target/linux/bcm27xx/patches-5.4/950-0710-overlays-Move-fixed-clock-nodes-to-the-root.patch
index aa19ca11d5..aa19ca11d5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0718-overlays-Move-fixed-clock-nodes-to-the-root.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0710-overlays-Move-fixed-clock-nodes-to-the-root.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0719-raspberrypi-dts-Switch-to-discrete-ALSA-devices.patch b/target/linux/bcm27xx/patches-5.4/950-0711-raspberrypi-dts-Switch-to-discrete-ALSA-devices.patch
index c5c302f832..c5c302f832 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0719-raspberrypi-dts-Switch-to-discrete-ALSA-devices.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0711-raspberrypi-dts-Switch-to-discrete-ALSA-devices.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0720-dt-bindings-media-i2c-Add-IMX477-CMOS-sensor-binding.patch b/target/linux/bcm27xx/patches-5.4/950-0712-dt-bindings-media-i2c-Add-IMX477-CMOS-sensor-binding.patch
index eb5430bbae..eb5430bbae 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0720-dt-bindings-media-i2c-Add-IMX477-CMOS-sensor-binding.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0712-dt-bindings-media-i2c-Add-IMX477-CMOS-sensor-binding.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0721-dtoverlays-Add-IMX477-sensor-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0713-dtoverlays-Add-IMX477-sensor-overlay.patch
index 0d5ea3c188..0d5ea3c188 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0721-dtoverlays-Add-IMX477-sensor-overlay.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0713-dtoverlays-Add-IMX477-sensor-overlay.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0722-media-i2c-Add-driver-for-Sony-IMX477-sensor.patch b/target/linux/bcm27xx/patches-5.4/950-0714-media-i2c-Add-driver-for-Sony-IMX477-sensor.patch
index f3e2052bfd..f3e2052bfd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0722-media-i2c-Add-driver-for-Sony-IMX477-sensor.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0714-media-i2c-Add-driver-for-Sony-IMX477-sensor.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0723-media-i2c-imx477-Add-support-for-adaptive-frame-cont.patch b/target/linux/bcm27xx/patches-5.4/950-0715-media-i2c-imx477-Add-support-for-adaptive-frame-cont.patch
index 1da5dea326..1da5dea326 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0723-media-i2c-imx477-Add-support-for-adaptive-frame-cont.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0715-media-i2c-imx477-Add-support-for-adaptive-frame-cont.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0724-udmabuf-Remove-deleted-map-unmap-handlers.patch b/target/linux/bcm27xx/patches-5.4/950-0716-udmabuf-Remove-deleted-map-unmap-handlers.patch
index bc7b5bea91..bc7b5bea91 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0724-udmabuf-Remove-deleted-map-unmap-handlers.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0716-udmabuf-Remove-deleted-map-unmap-handlers.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0725-udmabuf-use-cache_sgt_mapping-option.patch b/target/linux/bcm27xx/patches-5.4/950-0717-udmabuf-use-cache_sgt_mapping-option.patch
index 166055556f..166055556f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0725-udmabuf-use-cache_sgt_mapping-option.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0717-udmabuf-use-cache_sgt_mapping-option.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0726-udmabuf-add-a-pointer-to-the-miscdevice-in-dma-buf-p.patch b/target/linux/bcm27xx/patches-5.4/950-0718-udmabuf-add-a-pointer-to-the-miscdevice-in-dma-buf-p.patch
index 68feae3d48..68feae3d48 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0726-udmabuf-add-a-pointer-to-the-miscdevice-in-dma-buf-p.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0718-udmabuf-add-a-pointer-to-the-miscdevice-in-dma-buf-p.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0727-udmabuf-separate-out-creating-destroying-scatter-tab.patch b/target/linux/bcm27xx/patches-5.4/950-0719-udmabuf-separate-out-creating-destroying-scatter-tab.patch
index 5a0a59ced1..5a0a59ced1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0727-udmabuf-separate-out-creating-destroying-scatter-tab.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0719-udmabuf-separate-out-creating-destroying-scatter-tab.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0728-udmabuf-implement-begin_cpu_access-end_cpu_access-ho.patch b/target/linux/bcm27xx/patches-5.4/950-0720-udmabuf-implement-begin_cpu_access-end_cpu_access-ho.patch
index 79f6a67387..79f6a67387 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0728-udmabuf-implement-begin_cpu_access-end_cpu_access-ho.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0720-udmabuf-implement-begin_cpu_access-end_cpu_access-ho.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0729-udmabuf-fix-dma-buf-cpu-access.patch b/target/linux/bcm27xx/patches-5.4/950-0721-udmabuf-fix-dma-buf-cpu-access.patch
index 14cfe8aed3..14cfe8aed3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0729-udmabuf-fix-dma-buf-cpu-access.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0721-udmabuf-fix-dma-buf-cpu-access.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0730-dma-buf-Add-dma-buf-heaps-framework.patch b/target/linux/bcm27xx/patches-5.4/950-0722-dma-buf-Add-dma-buf-heaps-framework.patch
index f60d402379..f60d402379 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0730-dma-buf-Add-dma-buf-heaps-framework.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0722-dma-buf-Add-dma-buf-heaps-framework.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0731-dma-buf-heaps-Add-heap-helpers.patch b/target/linux/bcm27xx/patches-5.4/950-0723-dma-buf-heaps-Add-heap-helpers.patch
index 10eb46ca7b..10eb46ca7b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0731-dma-buf-heaps-Add-heap-helpers.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0723-dma-buf-heaps-Add-heap-helpers.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0732-dma-buf-heaps-Add-system-heap-to-dmabuf-heaps.patch b/target/linux/bcm27xx/patches-5.4/950-0724-dma-buf-heaps-Add-system-heap-to-dmabuf-heaps.patch
index 55c2450821..55c2450821 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0732-dma-buf-heaps-Add-system-heap-to-dmabuf-heaps.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0724-dma-buf-heaps-Add-system-heap-to-dmabuf-heaps.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0733-dma-buf-heaps-Add-CMA-heap-to-dmabuf-heaps.patch b/target/linux/bcm27xx/patches-5.4/950-0725-dma-buf-heaps-Add-CMA-heap-to-dmabuf-heaps.patch
index d1828702b4..d1828702b4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0733-dma-buf-heaps-Add-CMA-heap-to-dmabuf-heaps.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0725-dma-buf-heaps-Add-CMA-heap-to-dmabuf-heaps.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0734-kselftests-Add-dma-heap-test.patch b/target/linux/bcm27xx/patches-5.4/950-0726-kselftests-Add-dma-heap-test.patch
index ff4dda9a63..ff4dda9a63 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0734-kselftests-Add-dma-heap-test.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0726-kselftests-Add-dma-heap-test.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0735-dma-buf-heaps-Use-_IOCTL_-for-userspace-IOCTL-identi.patch b/target/linux/bcm27xx/patches-5.4/950-0727-dma-buf-heaps-Use-_IOCTL_-for-userspace-IOCTL-identi.patch
index a949831525..a949831525 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0735-dma-buf-heaps-Use-_IOCTL_-for-userspace-IOCTL-identi.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0727-dma-buf-heaps-Use-_IOCTL_-for-userspace-IOCTL-identi.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0736-dma-buf-heaps-Remove-redundant-heap-identifier-from-.patch b/target/linux/bcm27xx/patches-5.4/950-0728-dma-buf-heaps-Remove-redundant-heap-identifier-from-.patch
index 288f468a78..288f468a78 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0736-dma-buf-heaps-Remove-redundant-heap-identifier-from-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0728-dma-buf-heaps-Remove-redundant-heap-identifier-from-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0737-dma-buf-fix-resource-leak-on-ENOTTY-error-return-pat.patch b/target/linux/bcm27xx/patches-5.4/950-0729-dma-buf-fix-resource-leak-on-ENOTTY-error-return-pat.patch
index 89b66956e0..89b66956e0 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0737-dma-buf-fix-resource-leak-on-ENOTTY-error-return-pat.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0729-dma-buf-fix-resource-leak-on-ENOTTY-error-return-pat.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0738-dma-heap-Make-the-symbol-dma_heap_ioctl_cmds-static.patch b/target/linux/bcm27xx/patches-5.4/950-0730-dma-heap-Make-the-symbol-dma_heap_ioctl_cmds-static.patch
index 900637ddeb..900637ddeb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0738-dma-heap-Make-the-symbol-dma_heap_ioctl_cmds-static.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0730-dma-heap-Make-the-symbol-dma_heap_ioctl_cmds-static.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0739-ARM-dts-Enable-firmware-clocks-on-all-Pis.patch b/target/linux/bcm27xx/patches-5.4/950-0731-ARM-dts-Enable-firmware-clocks-on-all-Pis.patch
index f319bdca9f..f319bdca9f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0739-ARM-dts-Enable-firmware-clocks-on-all-Pis.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0731-ARM-dts-Enable-firmware-clocks-on-all-Pis.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0740-media-bcm2835-unicam-Always-service-interrupts.patch b/target/linux/bcm27xx/patches-5.4/950-0732-media-bcm2835-unicam-Always-service-interrupts.patch
index 378824c495..378824c495 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0740-media-bcm2835-unicam-Always-service-interrupts.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0732-media-bcm2835-unicam-Always-service-interrupts.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0741-sc16is7xx-Fix-for-hardware-flow-control.patch b/target/linux/bcm27xx/patches-5.4/950-0733-sc16is7xx-Fix-for-hardware-flow-control.patch
index 3ff77bcea9..3ff77bcea9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0741-sc16is7xx-Fix-for-hardware-flow-control.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0733-sc16is7xx-Fix-for-hardware-flow-control.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0742-drm-vc4-Fix-VIC-usage-with-Broadcast-RGB.patch b/target/linux/bcm27xx/patches-5.4/950-0734-drm-vc4-Fix-VIC-usage-with-Broadcast-RGB.patch
index 611e5db743..611e5db743 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0742-drm-vc4-Fix-VIC-usage-with-Broadcast-RGB.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0734-drm-vc4-Fix-VIC-usage-with-Broadcast-RGB.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0743-staging-vc04_services-mmal-vchiq-Update-parameters-l.patch b/target/linux/bcm27xx/patches-5.4/950-0735-staging-vc04_services-mmal-vchiq-Update-parameters-l.patch
index fd878ef737..fd878ef737 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0743-staging-vc04_services-mmal-vchiq-Update-parameters-l.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0735-staging-vc04_services-mmal-vchiq-Update-parameters-l.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0744-staging-vc04_services-bcm2835-codec-Request-headers-.patch b/target/linux/bcm27xx/patches-5.4/950-0736-staging-vc04_services-bcm2835-codec-Request-headers-.patch
index 7698f822d3..7698f822d3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0744-staging-vc04_services-bcm2835-codec-Request-headers-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0736-staging-vc04_services-bcm2835-codec-Request-headers-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0745-staging-vc04_services-bcm2835-codec-Avoid-fragmentin.patch b/target/linux/bcm27xx/patches-5.4/950-0737-staging-vc04_services-bcm2835-codec-Avoid-fragmentin.patch
index da273ca65b..da273ca65b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0745-staging-vc04_services-bcm2835-codec-Avoid-fragmentin.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0737-staging-vc04_services-bcm2835-codec-Avoid-fragmentin.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0746-staging-vc04_services-bcm2835-camera-Request-headers.patch b/target/linux/bcm27xx/patches-5.4/950-0738-staging-vc04_services-bcm2835-camera-Request-headers.patch
index 5d400e2530..5d400e2530 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0746-staging-vc04_services-bcm2835-camera-Request-headers.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0738-staging-vc04_services-bcm2835-camera-Request-headers.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0747-overlays-Fix-audio-parameter-of-vc4-kms-v3d.patch b/target/linux/bcm27xx/patches-5.4/950-0739-overlays-Fix-audio-parameter-of-vc4-kms-v3d.patch
index 4e69e41710..4e69e41710 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0747-overlays-Fix-audio-parameter-of-vc4-kms-v3d.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0739-overlays-Fix-audio-parameter-of-vc4-kms-v3d.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0748-Switch-to-snd_soc_dai_set_bclk_ratio.patch b/target/linux/bcm27xx/patches-5.4/950-0740-Switch-to-snd_soc_dai_set_bclk_ratio.patch
index b104f00efc..b104f00efc 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0748-Switch-to-snd_soc_dai_set_bclk_ratio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0740-Switch-to-snd_soc_dai_set_bclk_ratio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0749-media-bcm2835-unicam-Retain-packing-information-on-G.patch b/target/linux/bcm27xx/patches-5.4/950-0741-media-bcm2835-unicam-Retain-packing-information-on-G.patch
index 1e0051be30..1e0051be30 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0749-media-bcm2835-unicam-Retain-packing-information-on-G.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0741-media-bcm2835-unicam-Retain-packing-information-on-G.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0750-zswap-Defer-zswap-initialisation.patch b/target/linux/bcm27xx/patches-5.4/950-0742-zswap-Defer-zswap-initialisation.patch
index 124a1d95cd..124a1d95cd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0750-zswap-Defer-zswap-initialisation.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0742-zswap-Defer-zswap-initialisation.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0751-drm-vc4-Adopt-the-dma-configuration-from-the-HVS-or-.patch b/target/linux/bcm27xx/patches-5.4/950-0743-drm-vc4-Adopt-the-dma-configuration-from-the-HVS-or-.patch
index 2c9449df0f..2c9449df0f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0751-drm-vc4-Adopt-the-dma-configuration-from-the-HVS-or-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0743-drm-vc4-Adopt-the-dma-configuration-from-the-HVS-or-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0752-drm-vc4-Add-FKMS-as-an-acceptable-node-for-dma-range.patch b/target/linux/bcm27xx/patches-5.4/950-0744-drm-vc4-Add-FKMS-as-an-acceptable-node-for-dma-range.patch
index 127c5aef11..127c5aef11 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0752-drm-vc4-Add-FKMS-as-an-acceptable-node-for-dma-range.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0744-drm-vc4-Add-FKMS-as-an-acceptable-node-for-dma-range.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0753-media-i2c-imx477-Return-correct-result-on-sensor-id-.patch b/target/linux/bcm27xx/patches-5.4/950-0745-media-i2c-imx477-Return-correct-result-on-sensor-id-.patch
index 4585d2d8dd..4585d2d8dd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0753-media-i2c-imx477-Return-correct-result-on-sensor-id-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0745-media-i2c-imx477-Return-correct-result-on-sensor-id-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0754-staging-vchiq_arm-Clean-up-40-bit-DMA-support.patch b/target/linux/bcm27xx/patches-5.4/950-0746-staging-vchiq_arm-Clean-up-40-bit-DMA-support.patch
index 1dac504877..1dac504877 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0754-staging-vchiq_arm-Clean-up-40-bit-DMA-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0746-staging-vchiq_arm-Clean-up-40-bit-DMA-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0755-ARM-dts-Update-for-new-VCHIQ-BCM2711-DMA-support.patch b/target/linux/bcm27xx/patches-5.4/950-0747-ARM-dts-Update-for-new-VCHIQ-BCM2711-DMA-support.patch
index 947fb73a39..947fb73a39 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0755-ARM-dts-Update-for-new-VCHIQ-BCM2711-DMA-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0747-ARM-dts-Update-for-new-VCHIQ-BCM2711-DMA-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0756-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch b/target/linux/bcm27xx/patches-5.4/950-0748-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch
index 6f14ffc02c..6f14ffc02c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0756-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0748-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0757-dt-bindings-Add-Broadcom-AVS-RO-thermal.patch b/target/linux/bcm27xx/patches-5.4/950-0749-dt-bindings-Add-Broadcom-AVS-RO-thermal.patch
index bf41ba748b..bf41ba748b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0757-dt-bindings-Add-Broadcom-AVS-RO-thermal.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0749-dt-bindings-Add-Broadcom-AVS-RO-thermal.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0758-thermal-Add-BCM2711-thermal-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0750-thermal-Add-BCM2711-thermal-driver.patch
index d7e438fd72..d7e438fd72 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0758-thermal-Add-BCM2711-thermal-driver.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0750-thermal-Add-BCM2711-thermal-driver.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0759-ARM-dts-bcm2711-Enable-thermal.patch b/target/linux/bcm27xx/patches-5.4/950-0751-ARM-dts-bcm2711-Enable-thermal.patch
index 33289324bb..33289324bb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0759-ARM-dts-bcm2711-Enable-thermal.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0751-ARM-dts-bcm2711-Enable-thermal.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0760-ARM-dts-bcm2711-rpi-Remove-downstream-thermal-sensor.patch b/target/linux/bcm27xx/patches-5.4/950-0752-ARM-dts-bcm2711-rpi-Remove-downstream-thermal-sensor.patch
index 1d885635d6..1d885635d6 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0760-ARM-dts-bcm2711-rpi-Remove-downstream-thermal-sensor.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0752-ARM-dts-bcm2711-rpi-Remove-downstream-thermal-sensor.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0753-overlays-i2c-rtc-Fix-trickle-resistor-ohms-param.patch b/target/linux/bcm27xx/patches-5.4/950-0753-overlays-i2c-rtc-Fix-trickle-resistor-ohms-param.patch
new file mode 100644
index 0000000000..a702ef7137
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0753-overlays-i2c-rtc-Fix-trickle-resistor-ohms-param.patch
@@ -0,0 +1,26 @@
+From 7871e3600c1190c6cf7968e280bd2fd1ec8bbff2 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 29 May 2020 14:41:13 +0100
+Subject: [PATCH] overlays: i2c-rtc: Fix trickle-resistor-ohms param
+
+The abx80x implementation of the trickle-resistor-ohms parameter is
+missing the ":0" indicating that the target is an integer/cell value.
+
+See: https://github.com/raspberrypi/linux/issues/3642
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts
++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts
+@@ -229,7 +229,7 @@
+ <&m41t62>, "reg:0";
+ trickle-diode-type = <&abx80x>,"abracon,tc-diode";
+ trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0",
+- <&abx80x>,"abracon,tc-resistor",
++ <&abx80x>,"abracon,tc-resistor:0",
+ <&rv3028>,"trickle-resistor-ohms:0";
+ backup-switchover-mode = <&rv3028>,"backup-switchover-mode:0";
+ wakeup-source = <&ds1339>,"wakeup-source?",
diff --git a/target/linux/bcm27xx/patches-5.4/950-0754-overlays-gpio-shutdown-Add-information-for-SysV-init.patch b/target/linux/bcm27xx/patches-5.4/950-0754-overlays-gpio-shutdown-Add-information-for-SysV-init.patch
new file mode 100644
index 0000000000..ca0fd4942b
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0754-overlays-gpio-shutdown-Add-information-for-SysV-init.patch
@@ -0,0 +1,51 @@
+From 047041db91fabcb768c3e5680645b69fa9528e86 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
+Date: Thu, 30 Apr 2020 19:40:07 +0200
+Subject: [PATCH] overlays: gpio-shutdown: Add information for SysV
+ init / inittab
+
+KeyboardSignal and kb::kbrequest can be used to call /sbin/shutdown
+---
+ arch/arm/boot/dts/overlays/README | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -847,6 +847,7 @@ Params: gpiopin GPIO for
+ 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:
+@@ -855,6 +856,29 @@ Info: Initiates a shutdown when GPIO p
+ SUBSYSTEMS=="platform", DRIVERS=="gpio-keys", \
+ ATTRS{keys}=="116", TAG+="power-switch"
+
++ Alternatively this event can be handled also on systems without
++ systemd, just by traditional SysV init daemon. KEY_POWER event
++ (keycode 116) needs to be mapped to KeyboardSignal on console
++ and then kb::kbrequest inittab action which is triggered by
++ KeyboardSignal from console can be configured to issue system
++ shutdown. Steps for this configuration are:
++
++ Add following lines to the /etc/console-setup/remap.inc file:
++
++ # Key Power as special keypress
++ keycode 116 = KeyboardSignal
++
++ Then add following lines to /etc/inittab file:
++
++ # Action on special keypress (Key Power)
++ kb::kbrequest:/sbin/shutdown -t1 -a -h -P now
++
++ And finally reload configuration by calling following commands:
++
++ # dpkg-reconfigure console-setup
++ # service console-setup reload
++ # init q
++
+ 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
diff --git a/target/linux/bcm27xx/patches-5.4/950-0755-overlays-gpio-shutdown-Add-information-for-Raspberry.patch b/target/linux/bcm27xx/patches-5.4/950-0755-overlays-gpio-shutdown-Add-information-for-Raspberry.patch
new file mode 100644
index 0000000000..5bb6ee23ab
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0755-overlays-gpio-shutdown-Add-information-for-Raspberry.patch
@@ -0,0 +1,62 @@
+From 5f9fcc99c517a517e8d74ce001fc5bc2648f0e59 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
+Date: Thu, 30 Apr 2020 19:41:10 +0200
+Subject: [PATCH] overlays: gpio-shutdown: Add information for
+ Raspberry Pi 1 Model B rev 1
+
+Raspberry Pi 1 Model B rev 1 uses GPIO1 for power-up instead of GPIO3.
+---
+ arch/arm/boot/dts/overlays/README | 10 ++++++++--
+ arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts | 6 ++++--
+ 2 files changed, 12 insertions(+), 4 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -883,9 +883,14 @@ Info: Initiates a shutdown when GPIO p
+ 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.
++ you get a shutdown and power-up button. Please note that
++ Raspberry Pi 1 Model B rev 1 uses GPIO1 instead of GPIO3.
+ Load: dtoverlay=gpio-shutdown,<param>=<val>
+ Params: gpio_pin GPIO pin to trigger on (default 3)
++ For Raspberry Pi 1 Model B rev 1 set this
++ explicitly to value 1, e.g.:
++
++ dtoverlay=gpio-shutdown,gpio_pin=1
+
+ active_low When this is 1 (active low), a falling
+ edge generates a key down event and a
+@@ -897,7 +902,8 @@ Params: gpio_pin GPIO pin
+ Default is "up".
+
+ Note that the default pin (GPIO3) has an
+- external pullup.
++ external pullup. Same applies for GPIO1
++ on Raspberry Pi 1 Model B rev 1.
+
+ debounce Specify the debounce interval in milliseconds
+ (default 100)
+--- a/arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts
++++ b/arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts
+@@ -4,7 +4,9 @@
+
+ // 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
++// also be used to wake up (start) the Rpi again after shutdown.
++// Raspberry Pi 1 Model B rev 1 can be wake up only by GPIO1 pin, so for
++// these boards change default GPIO pin to 1 via gpio_pin parameter. 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).
+@@ -71,7 +73,7 @@
+
+ // 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).
++ // on some boards). Same applies for GPIO1 on Raspberry Pi 1 Model B rev 1.
+ gpio_pull = <&pin_state>,"brcm,pull:0";
+
+ // Allow setting the active_low flag. 0 = active high, 1 = active low
diff --git a/target/linux/bcm27xx/patches-5.4/950-0756-overlays-Add-spi0-overlay-to-support-sc16is752.patch b/target/linux/bcm27xx/patches-5.4/950-0756-overlays-Add-spi0-overlay-to-support-sc16is752.patch
new file mode 100644
index 0000000000..afd760b8f3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0756-overlays-Add-spi0-overlay-to-support-sc16is752.patch
@@ -0,0 +1,87 @@
+From b2998ffa15aabea3292159ca20973f45ed9cb4b0 Mon Sep 17 00:00:00 2001
+From: bjorn <beikeland@gmail.com>
+Date: Thu, 7 May 2020 05:11:43 +0200
+Subject: [PATCH] overlays: Add spi0 overlay to support sc16is752
+
+Signed-off-by: Bjorn <beikeland@gmail.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 8 ++++
+ .../dts/overlays/sc16is752-spi0-overlay.dts | 44 +++++++++++++++++++
+ 3 files changed, 53 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/sc16is752-spi0-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -143,6 +143,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ rra-digidac1-wm8741-audio.dtbo \
+ sc16is750-i2c.dtbo \
+ sc16is752-i2c.dtbo \
++ sc16is752-spi0.dtbo \
+ sc16is752-spi1.dtbo \
+ sdhost.dtbo \
+ sdio.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -2144,6 +2144,14 @@ Params: int_pin GPIO use
+ xtal On-board crystal frequency (default 14745600)
+
+
++Name: sc16is752-spi0
++Info: Overlay for the NXP SC16IS752 Dual UART with SPI Interface
++ Enables the chip on SPI0.
++Load: dtoverlay=sc16is752-spi0,<param>=<val>
++Params: int_pin GPIO used for IRQ (default 24)
++ 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.
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/sc16is752-spi0-overlay.dts
+@@ -0,0 +1,44 @@
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2835";
++
++ fragment@0 {
++ target = <&spi0>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ 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@1 {
++ target = <&spidev0>;
++ __overlay__ {
++ status = "disabled";
++ };
++ };
++
++ __overrides__ {
++ int_pin = <&sc16is752>,"interrupts:0";
++ xtal = <&sc16is752_clk>, "clock-frequency:0";
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-0757-overlays-i2c-rtc-gpio-Fix-trickle-resistor-ohms-para.patch b/target/linux/bcm27xx/patches-5.4/950-0757-overlays-i2c-rtc-gpio-Fix-trickle-resistor-ohms-para.patch
new file mode 100644
index 0000000000..6b81afb7c1
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0757-overlays-i2c-rtc-gpio-Fix-trickle-resistor-ohms-para.patch
@@ -0,0 +1,27 @@
+From 00771f36d14f8446ad155ba6fde1f3f608e26642 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 29 May 2020 16:55:12 +0100
+Subject: [PATCH] overlays: i2c-rtc-gpio: Fix trickle-resistor-ohms
+ param
+
+The abx80x implementation of the trickle-resistor-ohms parameter is
+missing the ":0" indicating that the target is an integer/cell value.
+
+See: https://github.com/raspberrypi/linux/issues/3642
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts
++++ b/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts
+@@ -230,7 +230,7 @@
+
+ trickle-diode-type = <&abx80x>,"abracon,tc-diode";
+ trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0",
+- <&abx80x>,"abracon,tc-resistor",
++ <&abx80x>,"abracon,tc-resistor:0",
+ <&rv3028>,"trickle-resistor-ohms:0";
+ backup-switchover-mode = <&rv3028>,"backup-switchover-mode:0";
+ wakeup-source = <&ds1339>,"wakeup-source?",
diff --git a/target/linux/bcm27xx/patches-5.4/950-0758-media-bcm2835-isp-fix-bytes-per-line-calculations-fo.patch b/target/linux/bcm27xx/patches-5.4/950-0758-media-bcm2835-isp-fix-bytes-per-line-calculations-fo.patch
new file mode 100644
index 0000000000..7f4943f9ab
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0758-media-bcm2835-isp-fix-bytes-per-line-calculations-fo.patch
@@ -0,0 +1,80 @@
+From 5b07adb57e04530dc571c2a4a1aeea4b7bc57723 Mon Sep 17 00:00:00 2001
+From: David Plowman <david.plowman@raspberrypi.com>
+Date: Fri, 29 May 2020 14:36:56 +0100
+Subject: [PATCH] media: bcm2835-isp: fix bytes per line calculations
+ for some image formats
+
+The bytes per line numbers calculated by get_bytesperline was not
+matching the equivalent calculation being performed by the VideoCore
+(mostly by the calculate_pitch function there), resulting in failures
+to set the image format with some image width values. This patches up
+the RGB24 and YUYV type formats to match the VideoCore calculation.
+
+Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
+---
+ .../vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c | 6 +++++-
+ .../vc04_services/bcm2835-isp/bcm2835_isp_fmts.h | 10 +++++-----
+ 2 files changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
+@@ -676,7 +676,11 @@ struct bcm2835_isp_fmt *get_default_form
+ static inline unsigned int get_bytesperline(int width,
+ const struct bcm2835_isp_fmt *fmt)
+ {
+- return ALIGN((width * fmt->depth) >> 3, fmt->bytesperline_align);
++ /* GPU aligns 24bpp images to a multiple of 32 pixels (not bytes). */
++ if (fmt->depth == 24)
++ return ALIGN(width, 32) * 3;
++ else
++ return ALIGN((width * fmt->depth) >> 3, fmt->bytesperline_align);
+ }
+
+ static inline unsigned int get_sizeimage(int bpl, int width, int height,
+--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h
++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h
+@@ -71,7 +71,7 @@ static const struct bcm2835_isp_fmt supp
+ }, {
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .depth = 16,
+- .bytesperline_align = 32,
++ .bytesperline_align = 64,
+ .flags = 0,
+ .mmal_fmt = MMAL_ENCODING_YUYV,
+ .size_multiplier_x2 = 2,
+@@ -80,7 +80,7 @@ static const struct bcm2835_isp_fmt supp
+ }, {
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .depth = 16,
+- .bytesperline_align = 32,
++ .bytesperline_align = 64,
+ .flags = 0,
+ .mmal_fmt = MMAL_ENCODING_UYVY,
+ .size_multiplier_x2 = 2,
+@@ -89,7 +89,7 @@ static const struct bcm2835_isp_fmt supp
+ }, {
+ .fourcc = V4L2_PIX_FMT_YVYU,
+ .depth = 16,
+- .bytesperline_align = 32,
++ .bytesperline_align = 64,
+ .flags = 0,
+ .mmal_fmt = MMAL_ENCODING_YVYU,
+ .size_multiplier_x2 = 2,
+@@ -98,7 +98,7 @@ static const struct bcm2835_isp_fmt supp
+ }, {
+ .fourcc = V4L2_PIX_FMT_VYUY,
+ .depth = 16,
+- .bytesperline_align = 32,
++ .bytesperline_align = 64,
+ .flags = 0,
+ .mmal_fmt = MMAL_ENCODING_VYUY,
+ .size_multiplier_x2 = 2,
+@@ -135,7 +135,7 @@ static const struct bcm2835_isp_fmt supp
+ }, {
+ .fourcc = V4L2_PIX_FMT_ABGR32,
+ .depth = 32,
+- .bytesperline_align = 32,
++ .bytesperline_align = 64,
+ .flags = 0,
+ .mmal_fmt = MMAL_ENCODING_BGRA,
+ .size_multiplier_x2 = 2,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0759-Add-Micro-Crystal-RV-1805-to-i2c-rtc-overlays.patch b/target/linux/bcm27xx/patches-5.4/950-0759-Add-Micro-Crystal-RV-1805-to-i2c-rtc-overlays.patch
new file mode 100644
index 0000000000..6e9951bd4a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0759-Add-Micro-Crystal-RV-1805-to-i2c-rtc-overlays.patch
@@ -0,0 +1,167 @@
+From 8c16d549cd0b9e9cf890ac3ead5d58d92590140f Mon Sep 17 00:00:00 2001
+From: "Kevin P. Fleming" <kevin+linux@km6g.us>
+Date: Mon, 1 Jun 2020 07:02:00 -0400
+Subject: [PATCH] Add Micro Crystal RV-1805 to i2c-rtc overlays
+
+While the RV-1805 is supported by the rtc-abx80x driver via
+auto-detection, in order for it to be initialized properly
+it must be explcitly selected.
+
+Signed-off-by: Kevin P. Fleming <kevin+linux@km6g.us>
+---
+ arch/arm/boot/dts/overlays/README | 12 +++++---
+ .../dts/overlays/i2c-rtc-gpio-overlay.dts | 28 ++++++++++++++++---
+ .../arm/boot/dts/overlays/i2c-rtc-overlay.dts | 27 ++++++++++++++++--
+ 3 files changed, 56 insertions(+), 11 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1196,6 +1196,8 @@ Params: abx80x Select o
+
+ pcf8563 Select the PCF8563 device
+
++ rv1805 Select the Micro Crystal RV1805 device
++
+ rv3028 Select the Micro Crystal RV3028 device
+
+ addr Sets the address for the RTC. Note that the
+@@ -1203,10 +1205,10 @@ Params: abx80x Select o
+ address.
+
+ trickle-diode-type Diode type for trickle charge - "standard" or
+- "schottky" (ABx80x only)
++ "schottky" (ABx80x and RV1805 only)
+
+ trickle-resistor-ohms Resistor value for trickle charge (DS1339,
+- ABx80x, RV3028)
++ ABx80x, RV1805, RV3028)
+
+ wakeup-source Specify that the RTC can be used as a wakeup
+ source
+@@ -1243,6 +1245,8 @@ Params: abx80x Select o
+
+ pcf8563 Select the PCF8563 device
+
++ rv1805 Select the Micro Crystal RV1805 device
++
+ rv3028 Select the Micro Crystal RV3028 device
+
+ addr Sets the address for the RTC. Note that the
+@@ -1250,10 +1254,10 @@ Params: abx80x Select o
+ address.
+
+ trickle-diode-type Diode type for trickle charge - "standard" or
+- "schottky" (ABx80x only)
++ "schottky" (ABx80x and RV1805 only)
+
+ trickle-resistor-ohms Resistor value for trickle charge (DS1339,
+- ABx80x, RV3028)
++ ABx80x, RV1805, RV3028)
+
+ wakeup-source Specify that the RTC can be used as a wakeup
+ source
+--- a/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts
++++ b/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts
+@@ -204,6 +204,23 @@
+ };
+ };
+
++ fragment@13 {
++ target = <&i2c_gpio>;
++ __dormant__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ rv1805: rv1805@69 {
++ compatible = "microcrystal,rv1805";
++ reg = <0x69>;
++ abracon,tc-diode = "standard";
++ abracon,tc-resistor = <0>;
++ status = "okay";
++ };
++ };
++ };
++
+ __overrides__ {
+ abx80x = <0>,"+1";
+ ds1307 = <0>,"+2";
+@@ -217,6 +234,7 @@
+ m41t62 = <0>,"+10";
+ rv3028 = <0>,"+11";
+ pcf2129 = <0>,"+12";
++ rv1805 = <0>,"+13";
+
+ addr = <&abx80x>, "reg:0",
+ <&ds1307>, "reg:0",
+@@ -226,12 +244,14 @@
+ <&mcp7941x>, "reg:0",
+ <&pcf8523>, "reg:0",
+ <&pcf8563>, "reg:0",
+- <&m41t62>, "reg:0";
+-
+- trickle-diode-type = <&abx80x>,"abracon,tc-diode";
++ <&m41t62>, "reg:0",
++ <&rv1805>, "reg:0";
++ trickle-diode-type = <&abx80x>,"abracon,tc-diode",
++ <&rv1805>,"abracon,tc-diode";
+ trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0",
+ <&abx80x>,"abracon,tc-resistor:0",
+- <&rv3028>,"trickle-resistor-ohms:0";
++ <&rv3028>,"trickle-resistor-ohms:0",
++ <&rv1805>,"abracon,tc-resistor:0";
+ backup-switchover-mode = <&rv3028>,"backup-switchover-mode:0";
+ wakeup-source = <&ds1339>,"wakeup-source?",
+ <&ds3231>,"wakeup-source?",
+--- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts
++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts
+@@ -203,6 +203,23 @@
+ };
+ };
+
++ fragment@13 {
++ target = <&i2c_arm>;
++ __dormant__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ rv1805: rv1805@69 {
++ compatible = "microcrystal,rv1805";
++ reg = <0x69>;
++ abracon,tc-diode = "standard";
++ abracon,tc-resistor = <0>;
++ status = "okay";
++ };
++ };
++ };
++
+ __overrides__ {
+ abx80x = <0>,"+0";
+ ds1307 = <0>,"+1";
+@@ -217,6 +234,7 @@
+ rv3028 = <0>,"+10";
+ pcf2129 = <0>,"+11";
+ pcf85363 = <0>,"+12";
++ rv1805 = <0>,"+13";
+
+ addr = <&abx80x>, "reg:0",
+ <&ds1307>, "reg:0",
+@@ -226,11 +244,14 @@
+ <&mcp7941x>, "reg:0",
+ <&pcf8523>, "reg:0",
+ <&pcf8563>, "reg:0",
+- <&m41t62>, "reg:0";
+- trickle-diode-type = <&abx80x>,"abracon,tc-diode";
++ <&m41t62>, "reg:0",
++ <&rv1805>, "reg:0";
++ trickle-diode-type = <&abx80x>,"abracon,tc-diode",
++ <&rv1805>,"abracon,tc-diode";
+ trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0",
+ <&abx80x>,"abracon,tc-resistor:0",
+- <&rv3028>,"trickle-resistor-ohms:0";
++ <&rv3028>,"trickle-resistor-ohms:0",
++ <&rv1805>,"abracon,tc-resistor:0";
+ backup-switchover-mode = <&rv3028>,"backup-switchover-mode:0";
+ wakeup-source = <&ds1339>,"wakeup-source?",
+ <&ds3231>,"wakeup-source?",
diff --git a/target/linux/bcm27xx/patches-5.4/950-0760-vc4-Set-driver_name-for-card.patch b/target/linux/bcm27xx/patches-5.4/950-0760-vc4-Set-driver_name-for-card.patch
new file mode 100644
index 0000000000..0f02d99d97
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0760-vc4-Set-driver_name-for-card.patch
@@ -0,0 +1,22 @@
+From aff5900c0b389e5ad2b8f2fc67544e769f94cbf4 Mon Sep 17 00:00:00 2001
+From: Dom Cobley <popcornmix@gmail.com>
+Date: Tue, 2 Jun 2020 19:31:49 +0100
+Subject: [PATCH] vc4: Set driver_name for card
+
+Allows use of the same alsa conf file for hdmi1
+
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -1216,6 +1216,7 @@ static int vc4_hdmi_audio_init(struct vc
+ card->dai_link = dai_link;
+ card->num_links = 1;
+ card->name = vc4_hdmi->variant->id ? "vc4-hdmi1" : "vc4-hdmi";
++ card->driver_name = "vc4-hdmi";
+ card->dev = dev;
+ card->owner = THIS_MODULE;
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0761-staging-vchiq_arm-Use-g_dma_dev-for-dma_unmap_sg.patch b/target/linux/bcm27xx/patches-5.4/950-0761-staging-vchiq_arm-Use-g_dma_dev-for-dma_unmap_sg.patch
new file mode 100644
index 0000000000..4af13475f9
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0761-staging-vchiq_arm-Use-g_dma_dev-for-dma_unmap_sg.patch
@@ -0,0 +1,27 @@
+From fecd0c670aabdbe5bac8fb58be374dd02ea2e8a2 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 4 Jun 2020 17:23:36 +0100
+Subject: [PATCH] staging: vchiq_arm: Use g_dma_dev for dma_unmap_sg
+
+Commit "staging: vchiq_arm: Clean up 40-bit DMA support" failed to
+change one of the calls to dma_unmap_sg to pass in g_dma_dev (rather
+than g_dev). Correct that oversight.
+
+See: https://github.com/raspberrypi/linux/issues/3647
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ .../staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+@@ -641,7 +641,7 @@ free_pagelist(struct vchiq_pagelist_info
+ * NOTE: dma_unmap_sg must be called before the
+ * cpu can touch any of the data/pages.
+ */
+- dma_unmap_sg(g_dev, pagelistinfo->scatterlist,
++ dma_unmap_sg(g_dma_dev, pagelistinfo->scatterlist,
+ pagelistinfo->num_pages, pagelistinfo->dma_dir);
+ pagelistinfo->scatterlist_mapped = 0;
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0762-vc4-cec-Restore-cec-physical-address-on-reconnect.patch b/target/linux/bcm27xx/patches-5.4/950-0762-vc4-cec-Restore-cec-physical-address-on-reconnect.patch
new file mode 100644
index 0000000000..d42f61d2e4
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0762-vc4-cec-Restore-cec-physical-address-on-reconnect.patch
@@ -0,0 +1,56 @@
+From 7776a876ce7a6eeda164aebacc965116821d3095 Mon Sep 17 00:00:00 2001
+From: Dom Cobley <popcornmix@gmail.com>
+Date: Wed, 3 Jun 2020 12:20:19 +0100
+Subject: [PATCH] vc4: cec: Restore cec physical address on reconnect
+
+Currently we call cec_phys_addr_invalidate on a hotplug deassert.
+That may be due to a TV power cycling, or an AVR being switched
+on (and switching edid). This makes CEC unusable.
+
+Set it back up again on the hotplug assert.
+
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 25 +++++++++++++++++--------
+ 1 file changed, 17 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -113,20 +113,29 @@ static enum drm_connector_status
+ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
+ {
+ struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
++ bool connected = false;
+
+ if (vc4_hdmi->hpd_gpio) {
+ if (gpio_get_value_cansleep(vc4_hdmi->hpd_gpio) ^
+ vc4_hdmi->hpd_active_low)
+- return connector_status_connected;
+- cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
+- return connector_status_disconnected;
+- }
+-
+- if (drm_probe_ddc(vc4_hdmi->ddc))
+- return connector_status_connected;
+-
++ connected = true;
++ } else if (drm_probe_ddc(vc4_hdmi->ddc))
++ connected = true;
+ if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
++ connected = true;
++ if (connected) {
++ if (connector->status != connector_status_connected) {
++ struct edid *edid = drm_get_edid(connector, vc4_hdmi->ddc);
++
++ if (edid) {
++ cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid);
++ vc4_hdmi->encoder.hdmi_monitor = drm_detect_hdmi_monitor(edid);
++ drm_connector_update_edid_property(connector, edid);
++ kfree(edid);
++ }
++ }
+ return connector_status_connected;
++ }
+ cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
+ return connector_status_disconnected;
+ }
diff --git a/target/linux/bcm27xx/patches-5.4/950-0763-snd_bcm2835-disable-HDMI-audio-when-vc4-is-used-3640.patch b/target/linux/bcm27xx/patches-5.4/950-0763-snd_bcm2835-disable-HDMI-audio-when-vc4-is-used-3640.patch
new file mode 100644
index 0000000000..ed45410294
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0763-snd_bcm2835-disable-HDMI-audio-when-vc4-is-used-3640.patch
@@ -0,0 +1,92 @@
+From 744543757bef8621f7791e28ecb894b2627cb449 Mon Sep 17 00:00:00 2001
+From: Hristo Venev <hristo@venev.name>
+Date: Fri, 5 Jun 2020 09:22:49 +0000
+Subject: [PATCH] snd_bcm2835: disable HDMI audio when vc4 is used
+ (#3640)
+
+Things don't work too well when both the vc4 driver and the firmware
+driver are trying to control the same audio output:
+
+[ 763.569406] bcm2835_audio bcm2835_audio: vchi message timeout, msg=5
+
+Hence, when the vc4 HDMI driver is used, let it control audio. This is done
+by introducing a new device tree property to the audio node, and
+extending the vc4-kms-v3d overlays to set it appropriately.
+
+Signed-off-by: Hristo Venev <hristo@venev.name>
+---
+ arch/arm/boot/dts/overlays/README | 2 ++
+ arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 10 +++++++++-
+ arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts | 8 ++++++++
+ drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 4 +++-
+ 4 files changed, 22 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -2745,6 +2745,7 @@ Params: cma-256 CMA is 2
+ cma-size CMA size in bytes, 4MB aligned
+ cma-default Use upstream's default value
+ audio Enable or disable audio over HDMI (default "on")
++ noaudio Disable all HDMI audio (default "off")
+
+
+ Name: vc4-kms-v3d-pi4
+@@ -2761,6 +2762,7 @@ Params: cma-256 CMA is 2
+ "on")
+ audio1 Enable or disable audio over HDMI1 (default
+ "on")
++ noaudio Disable all HDMI audio (default "off")
+
+
+ Name: vga666
+--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
+@@ -108,7 +108,15 @@
+ };
+ };
+
++ fragment@14 {
++ target = <&audio>;
++ __overlay__ {
++ brcm,disable-hdmi;
++ };
++ };
++
+ __overrides__ {
+- audio = <0>,"!13";
++ audio = <0>,"!13", <0>,"=14";
++ noaudio = <0>,"=13", <0>,"!14";
+ };
+ };
+--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts
++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts
+@@ -138,8 +138,16 @@
+ };
+ };
+
++ fragment@19 {
++ target = <&audio>;
++ __overlay__ {
++ brcm,disable-hdmi;
++ };
++ };
++
+ __overrides__ {
+ audio = <0>,"!17";
+ audio1 = <0>,"!18";
++ noaudio = <0>,"=17", <0>,"=18", <0>,"!19";
+ };
+ };
+--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c
++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c
+@@ -381,7 +381,9 @@ static int snd_bcm2835_alsa_probe(struct
+ }
+
+ if (!enable_compat_alsa) {
+- set_hdmi_enables(dev);
++ if (!of_property_read_bool(dev->of_node, "brcm,disable-hdmi"))
++ set_hdmi_enables(dev);
++
+ // In this mode, always enable analog output
+ enable_headphones = true;
+ } else {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0764-overlays-i2c-gpio-Avoid-open-drain-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0764-overlays-i2c-gpio-Avoid-open-drain-warnings.patch
new file mode 100644
index 0000000000..9b6cb1d564
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0764-overlays-i2c-gpio-Avoid-open-drain-warnings.patch
@@ -0,0 +1,93 @@
+From 11f89a12530471a2b25c71416e106eaa014818c0 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 5 Jun 2020 16:07:07 +0100
+Subject: [PATCH] overlays: i2c-gpio: Avoid open-drain warnings
+
+The i2c-gpio driver expects to use a GPIO in open-drain mode. Failure
+to configure it in that way causes alarming warnings in the kernel log.
+The BCM283x and BCM2711 GPIO blocks don't support open-drain mode, but
+gpiolib can emulate it in software if configured correctly.
+
+Silence the warning by declaring the GPIOs as requiring open-drain
+mode, trusting gpiolib to manage the emulation. The previous
+incarnation of this patch took the other approach of telling the
+i2c-gpio driver that the GPIOs were configured for open-drain, but
+this had the effect of disabling the emulation. In some cases this
+appears to work, but examining the waveforms as analogue voltages
+shows contention, the success or failure depending on drive strengths.
+
+See: https://github.com/raspberrypi/firmware/issues/1381
+See: https://github.com/raspberrypi/firmware/issues/1401
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/balena-fin-overlay.dts | 5 ++++-
+ arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts | 6 ++++--
+ arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts | 6 ++++--
+ 3 files changed, 12 insertions(+), 5 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/balena-fin-overlay.dts
++++ b/arch/arm/boot/dts/overlays/balena-fin-overlay.dts
+@@ -1,6 +1,8 @@
+ /dts-v1/;
+ /plugin/;
+
++#include <dt-bindings/gpio/gpio.h>
++
+ /{
+ compatible = "brcm,bcm2835";
+
+@@ -48,7 +50,8 @@
+
+ i2c_soft: i2c@0 {
+ compatible = "i2c-gpio";
+- gpios = <&gpio 43 0 /* sda */ &gpio 42 0 /* scl */>;
++ gpios = <&gpio 43 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* sda */
++ &gpio 42 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* scl */>;
+ i2c-gpio,delay-us = <5>;
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,sda-open-drain;
+--- a/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts
++++ b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts
+@@ -2,6 +2,8 @@
+ /dts-v1/;
+ /plugin/;
+
++#include <dt-bindings/gpio/gpio.h>
++
+ / {
+ compatible = "brcm,bcm2835";
+
+@@ -12,8 +14,8 @@
+ i2c_gpio: i2c@0 {
+ reg = <0xffffffff>;
+ compatible = "i2c-gpio";
+- gpios = <&gpio 23 0 /* sda */
+- &gpio 24 0 /* scl */
++ gpios = <&gpio 23 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* sda */
++ &gpio 24 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* scl */
+ >;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+--- a/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts
++++ b/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts
+@@ -3,6 +3,8 @@
+ /dts-v1/;
+ /plugin/;
+
++#include <dt-bindings/gpio/gpio.h>
++
+ / {
+ compatible = "brcm,bcm2835";
+
+@@ -11,8 +13,8 @@
+ __overlay__ {
+ i2c_gpio: i2c-gpio-rtc@0 {
+ compatible = "i2c-gpio";
+- gpios = <&gpio 23 0 /* sda */
+- &gpio 24 0 /* scl */
++ gpios = <&gpio 23 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* sda */
++ &gpio 24 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* scl */
+ >;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0765-overlays-Update-upstream-overlays-after-vc4-kms-v3d-.patch b/target/linux/bcm27xx/patches-5.4/950-0765-overlays-Update-upstream-overlays-after-vc4-kms-v3d-.patch
new file mode 100644
index 0000000000..dd5f2ee90a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0765-overlays-Update-upstream-overlays-after-vc4-kms-v3d-.patch
@@ -0,0 +1,42 @@
+From 964d9575e0a9849f197edaa243e9f2268d5ab44e Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 5 Jun 2020 16:18:52 +0100
+Subject: [PATCH] overlays: Update upstream overlays after
+ vc4-kms-v3d change
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/upstream-overlay.dts | 6 ++++++
+ arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts | 6 ++++++
+ 2 files changed, 12 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/upstream-overlay.dts
++++ b/arch/arm/boot/dts/overlays/upstream-overlay.dts
+@@ -92,6 +92,12 @@
+ };
+ };
+ fragment@14 {
++ target = <&audio>;
++ __overlay__ {
++ brcm,disable-hdmi;
++ };
++ };
++ fragment@15 {
+ target = <&usb>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+--- a/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts
++++ b/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts
+@@ -122,6 +122,12 @@
+ };
+ };
+ fragment@19 {
++ target = <&audio>;
++ __overlay__ {
++ brcm,disable-hdmi;
++ };
++ };
++ fragment@20 {
+ target = <&usb>;
+ #address-cells = <1>;
+ #size-cells = <1>;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0766-w1_therm-adding-code-comments-and-code-reordering.patch b/target/linux/bcm27xx/patches-5.4/950-0766-w1_therm-adding-code-comments-and-code-reordering.patch
new file mode 100644
index 0000000000..5db05123da
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0766-w1_therm-adding-code-comments-and-code-reordering.patch
@@ -0,0 +1,580 @@
+From 7c49e87acd0412ff1fb2490c4ac6fcb5471afd9b Mon Sep 17 00:00:00 2001
+From: Akira Shimahara <akira215corp@gmail.com>
+Date: Mon, 11 May 2020 22:35:35 +0200
+Subject: [PATCH] w1_therm: adding code comments and code reordering
+
+commit 92b8d2724464bc1d2e735a84c0da5741dce33485 upstream.
+
+Adding code comments to split code in dedicated parts. After the global
+declarations (defines, macros and function declarations), code is organized
+as follow :
+ - Device and family dependent structures and functions
+ - Interfaces functions
+ - Helpers functions
+ - Hardware functions
+ - Sysfs interface functions
+
+Signed-off-by: Akira Shimahara <akira215corp@gmail.com>
+Link: https://lore.kernel.org/r/20200511203535.409599-1-akira215corp@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/w1/slaves/w1_therm.c | 427 +++++++++++++++++++++--------------
+ 1 file changed, 259 insertions(+), 168 deletions(-)
+
+--- a/drivers/w1/slaves/w1_therm.c
++++ b/drivers/w1/slaves/w1_therm.c
+@@ -25,7 +25,8 @@
+ #define W1_THERM_DS1825 0x3B
+ #define W1_THERM_DS28EA00 0x42
+
+-/* Allow the strong pullup to be disabled, but default to enabled.
++/*
++ * Allow the strong pullup to be disabled, but default to enabled.
+ * If it was disabled a parasite powered device might not get the require
+ * current to do a temperature conversion. If it is enabled parasite powered
+ * devices have a better chance of getting the current required.
+@@ -41,42 +42,55 @@
+ static int w1_strong_pullup = 1;
+ module_param_named(strong_pullup, w1_strong_pullup, int, 0);
+
++/* Helpers Macros */
++
++/* return the address of the refcnt in the family data */
++#define THERM_REFCNT(family_data) \
++ (&((struct w1_therm_family_data *)family_data)->refcnt)
++
++/* Structs definition */
++
++/**
++ * struct w1_therm_family_converter - bind device specific functions
++ * @broken: flag for non-registred families
++ * @reserved: not used here
++ * @f: pointer to the device binding structure
++ * @convert: pointer to the device conversion function
++ * @precision: pointer to the device precision function
++ * @eeprom: pointer to eeprom function
++ */
++struct w1_therm_family_converter {
++ u8 broken;
++ u16 reserved;
++ struct w1_family *f;
++ int (*convert)(u8 rom[9]);
++ int (*precision)(struct device *device, int val);
++ int (*eeprom)(struct device *device);
++};
++
++/**
++ * struct w1_therm_family_data - device data
++ * @rom: ROM device id (64bit Lasered ROM code + 1 CRC byte)
++ * @refcnt: ref count
++ */
+ struct w1_therm_family_data {
+ uint8_t rom[9];
+ atomic_t refcnt;
+ };
+
++/**
++ * struct therm_info - store temperature reading
++ * @rom: read device data (8 data bytes + 1 CRC byte)
++ * @crc: computed crc from rom
++ * @verdict: 1 crc checked, 0 crc not matching
++ */
+ struct therm_info {
+ u8 rom[9];
+ u8 crc;
+ u8 verdict;
+ };
+
+-/* return the address of the refcnt in the family data */
+-#define THERM_REFCNT(family_data) \
+- (&((struct w1_therm_family_data *)family_data)->refcnt)
+-
+-static int w1_therm_add_slave(struct w1_slave *sl)
+-{
+- sl->family_data = kzalloc(sizeof(struct w1_therm_family_data),
+- GFP_KERNEL);
+- if (!sl->family_data)
+- return -ENOMEM;
+- atomic_set(THERM_REFCNT(sl->family_data), 1);
+- return 0;
+-}
+-
+-static void w1_therm_remove_slave(struct w1_slave *sl)
+-{
+- int refcnt = atomic_sub_return(1, THERM_REFCNT(sl->family_data));
+-
+- while (refcnt) {
+- msleep(1000);
+- refcnt = atomic_read(THERM_REFCNT(sl->family_data));
+- }
+- kfree(sl->family_data);
+- sl->family_data = NULL;
+-}
++/* Sysfs interface declaration */
+
+ static ssize_t w1_slave_show(struct device *device,
+ struct device_attribute *attr, char *buf);
+@@ -87,9 +101,35 @@ static ssize_t w1_slave_store(struct dev
+ static ssize_t w1_seq_show(struct device *device,
+ struct device_attribute *attr, char *buf);
+
++/* Attributes declarations */
++
+ static DEVICE_ATTR_RW(w1_slave);
+ static DEVICE_ATTR_RO(w1_seq);
+
++/* Interface Functions declaration */
++
++/**
++ * w1_therm_add_slave() - Called when a new slave is discovered
++ * @sl: slave just discovered by the master.
++ *
++ * Called by the master when the slave is discovered on the bus. Used to
++ * initialize slave state before the beginning of any communication.
++ *
++ * Return: 0 - If success, negative kernel code otherwise
++ */
++static int w1_therm_add_slave(struct w1_slave *sl);
++
++/**
++ * w1_therm_remove_slave() - Called when a slave is removed
++ * @sl: slave to be removed.
++ *
++ * Called by the master when the slave is considered not to be on the bus
++ * anymore. Used to free memory.
++ */
++static void w1_therm_remove_slave(struct w1_slave *sl);
++
++/* Family attributes */
++
+ static struct attribute *w1_therm_attrs[] = {
+ &dev_attr_w1_slave.attr,
+ NULL,
+@@ -101,6 +141,8 @@ static struct attribute *w1_ds28ea00_att
+ NULL,
+ };
+
++/* Attribute groups */
++
+ ATTRIBUTE_GROUPS(w1_therm);
+ ATTRIBUTE_GROUPS(w1_ds28ea00);
+
+@@ -154,6 +196,8 @@ static const struct hwmon_chip_info w1_c
+ #define W1_CHIPINFO NULL
+ #endif
+
++/* Family operations */
++
+ static struct w1_family_ops w1_therm_fops = {
+ .add_slave = w1_therm_add_slave,
+ .remove_slave = w1_therm_remove_slave,
+@@ -168,6 +212,8 @@ static struct w1_family_ops w1_ds28ea00_
+ .chip_info = W1_CHIPINFO,
+ };
+
++/* Family binding operations struct */
++
+ static struct w1_family w1_therm_family_DS18S20 = {
+ .fid = W1_THERM_DS18S20,
+ .fops = &w1_therm_fops,
+@@ -193,138 +239,18 @@ static struct w1_family w1_therm_family_
+ .fops = &w1_therm_fops,
+ };
+
+-struct w1_therm_family_converter {
+- u8 broken;
+- u16 reserved;
+- struct w1_family *f;
+- int (*convert)(u8 rom[9]);
+- int (*precision)(struct device *device, int val);
+- int (*eeprom)(struct device *device);
+-};
++/* Device dependent func */
+
+ /* write configuration to eeprom */
+ static inline int w1_therm_eeprom(struct device *device);
+
+-/* Set precision for conversion */
+-static inline int w1_DS18B20_precision(struct device *device, int val);
+-static inline int w1_DS18S20_precision(struct device *device, int val);
+-
+-/* The return value is millidegrees Centigrade. */
+-static inline int w1_DS18B20_convert_temp(u8 rom[9]);
+-static inline int w1_DS18S20_convert_temp(u8 rom[9]);
+-
+-static struct w1_therm_family_converter w1_therm_families[] = {
+- {
+- .f = &w1_therm_family_DS18S20,
+- .convert = w1_DS18S20_convert_temp,
+- .precision = w1_DS18S20_precision,
+- .eeprom = w1_therm_eeprom
+- },
+- {
+- .f = &w1_therm_family_DS1822,
+- .convert = w1_DS18B20_convert_temp,
+- .precision = w1_DS18S20_precision,
+- .eeprom = w1_therm_eeprom
+- },
+- {
+- .f = &w1_therm_family_DS18B20,
+- .convert = w1_DS18B20_convert_temp,
+- .precision = w1_DS18B20_precision,
+- .eeprom = w1_therm_eeprom
+- },
+- {
+- .f = &w1_therm_family_DS28EA00,
+- .convert = w1_DS18B20_convert_temp,
+- .precision = w1_DS18S20_precision,
+- .eeprom = w1_therm_eeprom
+- },
+- {
+- .f = &w1_therm_family_DS1825,
+- .convert = w1_DS18B20_convert_temp,
+- .precision = w1_DS18S20_precision,
+- .eeprom = w1_therm_eeprom
+- }
+-};
+-
+-static inline int w1_therm_eeprom(struct device *device)
+-{
+- struct w1_slave *sl = dev_to_w1_slave(device);
+- struct w1_master *dev = sl->master;
+- u8 rom[9], external_power;
+- int ret, max_trying = 10;
+- u8 *family_data = sl->family_data;
+-
+- if (!sl->family_data) {
+- ret = -ENODEV;
+- goto error;
+- }
+-
+- /* prevent the slave from going away in sleep */
+- atomic_inc(THERM_REFCNT(family_data));
+-
+- ret = mutex_lock_interruptible(&dev->bus_mutex);
+- if (ret != 0)
+- goto dec_refcnt;
+-
+- memset(rom, 0, sizeof(rom));
+-
+- while (max_trying--) {
+- if (!w1_reset_select_slave(sl)) {
+- unsigned int tm = 10;
+- unsigned long sleep_rem;
+-
+- /* check if in parasite mode */
+- w1_write_8(dev, W1_READ_PSUPPLY);
+- external_power = w1_read_8(dev);
+-
+- if (w1_reset_select_slave(sl))
+- continue;
+-
+- /* 10ms strong pullup/delay after the copy command */
+- if (w1_strong_pullup == 2 ||
+- (!external_power && w1_strong_pullup))
+- w1_next_pullup(dev, tm);
+-
+- w1_write_8(dev, W1_COPY_SCRATCHPAD);
+-
+- if (external_power) {
+- mutex_unlock(&dev->bus_mutex);
+-
+- sleep_rem = msleep_interruptible(tm);
+- if (sleep_rem != 0) {
+- ret = -EINTR;
+- goto dec_refcnt;
+- }
+-
+- ret = mutex_lock_interruptible(&dev->bus_mutex);
+- if (ret != 0)
+- goto dec_refcnt;
+- } else if (!w1_strong_pullup) {
+- sleep_rem = msleep_interruptible(tm);
+- if (sleep_rem != 0) {
+- ret = -EINTR;
+- goto mt_unlock;
+- }
+- }
+-
+- break;
+- }
+- }
+-
+-mt_unlock:
+- mutex_unlock(&dev->bus_mutex);
+-dec_refcnt:
+- atomic_dec(THERM_REFCNT(family_data));
+-error:
+- return ret;
+-}
+-
+ /* DS18S20 does not feature configuration register */
+ static inline int w1_DS18S20_precision(struct device *device, int val)
+ {
+ return 0;
+ }
+
++/* Set precision for conversion */
+ static inline int w1_DS18B20_precision(struct device *device, int val)
+ {
+ struct w1_slave *sl = dev_to_w1_slave(device);
+@@ -407,6 +333,14 @@ error:
+ return ret;
+ }
+
++/**
++ * w1_DS18B20_convert_temp() - temperature computation for DS18B20
++ * @rom: data read from device RAM (8 data bytes + 1 CRC byte)
++ *
++ * Can be called for any DS18B20 compliant device.
++ *
++ * Return: value in millidegrees Celsius.
++ */
+ static inline int w1_DS18B20_convert_temp(u8 rom[9])
+ {
+ s16 t = le16_to_cpup((__le16 *)rom);
+@@ -414,6 +348,14 @@ static inline int w1_DS18B20_convert_tem
+ return t*1000/16;
+ }
+
++/**
++ * w1_DS18S20_convert_temp() - temperature computation for DS18S20
++ * @rom: data read from device RAM (8 data bytes + 1 CRC byte)
++ *
++ * Can be called for any DS18S20 compliant device.
++ *
++ * Return: value in millidegrees Celsius.
++ */
+ static inline int w1_DS18S20_convert_temp(u8 rom[9])
+ {
+ int t, h;
+@@ -434,6 +376,53 @@ static inline int w1_DS18S20_convert_tem
+ return t;
+ }
+
++/* Device capability description */
++
++static struct w1_therm_family_converter w1_therm_families[] = {
++ {
++ .f = &w1_therm_family_DS18S20,
++ .convert = w1_DS18S20_convert_temp,
++ .precision = w1_DS18S20_precision,
++ .eeprom = w1_therm_eeprom
++ },
++ {
++ .f = &w1_therm_family_DS1822,
++ .convert = w1_DS18B20_convert_temp,
++ .precision = w1_DS18S20_precision,
++ .eeprom = w1_therm_eeprom
++ },
++ {
++ .f = &w1_therm_family_DS18B20,
++ .convert = w1_DS18B20_convert_temp,
++ .precision = w1_DS18B20_precision,
++ .eeprom = w1_therm_eeprom
++ },
++ {
++ .f = &w1_therm_family_DS28EA00,
++ .convert = w1_DS18B20_convert_temp,
++ .precision = w1_DS18S20_precision,
++ .eeprom = w1_therm_eeprom
++ },
++ {
++ .f = &w1_therm_family_DS1825,
++ .convert = w1_DS18B20_convert_temp,
++ .precision = w1_DS18S20_precision,
++ .eeprom = w1_therm_eeprom
++ }
++};
++
++/* Helpers Functions */
++
++/**
++ * w1_convert_temp() - temperature conversion binding function
++ * @rom: data read from device RAM (8 data bytes + 1 CRC byte)
++ * @fid: device family id
++ *
++ * The function call the temperature computation function according to
++ * device family.
++ *
++ * Return: value in millidegrees Celsius.
++ */
+ static inline int w1_convert_temp(u8 rom[9], u8 fid)
+ {
+ int i;
+@@ -445,31 +434,32 @@ static inline int w1_convert_temp(u8 rom
+ return 0;
+ }
+
+-static ssize_t w1_slave_store(struct device *device,
+- struct device_attribute *attr, const char *buf,
+- size_t size)
++/* Interface Functions */
++
++static int w1_therm_add_slave(struct w1_slave *sl)
+ {
+- int val, ret;
+- struct w1_slave *sl = dev_to_w1_slave(device);
+- int i;
++ sl->family_data = kzalloc(sizeof(struct w1_therm_family_data),
++ GFP_KERNEL);
++ if (!sl->family_data)
++ return -ENOMEM;
++ atomic_set(THERM_REFCNT(sl->family_data), 1);
++ return 0;
++}
+
+- ret = kstrtoint(buf, 0, &val);
+- if (ret)
+- return ret;
++static void w1_therm_remove_slave(struct w1_slave *sl)
++{
++ int refcnt = atomic_sub_return(1, THERM_REFCNT(sl->family_data));
+
+- for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i) {
+- if (w1_therm_families[i].f->fid == sl->family->fid) {
+- /* zero value indicates to write current configuration to eeprom */
+- if (val == 0)
+- ret = w1_therm_families[i].eeprom(device);
+- else
+- ret = w1_therm_families[i].precision(device, val);
+- break;
+- }
++ while (refcnt) {
++ msleep(1000);
++ refcnt = atomic_read(THERM_REFCNT(sl->family_data));
+ }
+- return ret ? : size;
++ kfree(sl->family_data);
++ sl->family_data = NULL;
+ }
+
++/* Hardware Functions */
++
+ static ssize_t read_therm(struct device *device,
+ struct w1_slave *sl, struct therm_info *info)
+ {
+@@ -564,6 +554,81 @@ error:
+ return ret;
+ }
+
++static inline int w1_therm_eeprom(struct device *device)
++{
++ struct w1_slave *sl = dev_to_w1_slave(device);
++ struct w1_master *dev = sl->master;
++ u8 rom[9], external_power;
++ int ret, max_trying = 10;
++ u8 *family_data = sl->family_data;
++
++ if (!sl->family_data) {
++ ret = -ENODEV;
++ goto error;
++ }
++
++ /* prevent the slave from going away in sleep */
++ atomic_inc(THERM_REFCNT(family_data));
++
++ ret = mutex_lock_interruptible(&dev->bus_mutex);
++ if (ret != 0)
++ goto dec_refcnt;
++
++ memset(rom, 0, sizeof(rom));
++
++ while (max_trying--) {
++ if (!w1_reset_select_slave(sl)) {
++ unsigned int tm = 10;
++ unsigned long sleep_rem;
++
++ /* check if in parasite mode */
++ w1_write_8(dev, W1_READ_PSUPPLY);
++ external_power = w1_read_8(dev);
++
++ if (w1_reset_select_slave(sl))
++ continue;
++
++ /* 10ms strong pullup/delay after the copy command */
++ if (w1_strong_pullup == 2 ||
++ (!external_power && w1_strong_pullup))
++ w1_next_pullup(dev, tm);
++
++ w1_write_8(dev, W1_COPY_SCRATCHPAD);
++
++ if (external_power) {
++ mutex_unlock(&dev->bus_mutex);
++
++ sleep_rem = msleep_interruptible(tm);
++ if (sleep_rem != 0) {
++ ret = -EINTR;
++ goto dec_refcnt;
++ }
++
++ ret = mutex_lock_interruptible(&dev->bus_mutex);
++ if (ret != 0)
++ goto dec_refcnt;
++ } else if (!w1_strong_pullup) {
++ sleep_rem = msleep_interruptible(tm);
++ if (sleep_rem != 0) {
++ ret = -EINTR;
++ goto mt_unlock;
++ }
++ }
++
++ break;
++ }
++ }
++
++mt_unlock:
++ mutex_unlock(&dev->bus_mutex);
++dec_refcnt:
++ atomic_dec(THERM_REFCNT(family_data));
++error:
++ return ret;
++}
++
++/* Sysfs Interface definition */
++
+ static ssize_t w1_slave_show(struct device *device,
+ struct device_attribute *attr, char *buf)
+ {
+@@ -597,6 +662,32 @@ static ssize_t w1_slave_show(struct devi
+ return ret;
+ }
+
++static ssize_t w1_slave_store(struct device *device,
++ struct device_attribute *attr, const char *buf,
++ size_t size)
++{
++ int val, ret;
++ struct w1_slave *sl = dev_to_w1_slave(device);
++ int i;
++
++ ret = kstrtoint(buf, 0, &val);
++ if (ret)
++ return ret;
++
++ for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i) {
++ if (w1_therm_families[i].f->fid == sl->family->fid) {
++ /* zero value indicates to write current configuration to eeprom */
++ if (val == 0)
++ ret = w1_therm_families[i].eeprom(device);
++ else
++ ret = w1_therm_families[i].precision(device,
++ val);
++ break;
++ }
++ }
++ return ret ? : size;
++}
++
+ #if IS_REACHABLE(CONFIG_HWMON)
+ static int w1_read_temp(struct device *device, u32 attr, int channel,
+ long *val)
+@@ -666,7 +757,7 @@ static ssize_t w1_seq_show(struct device
+ if (ack != W1_42_SUCCESS_CONFIRM_BYTE)
+ goto error;
+
+- /* In case the bus fails to send 0xFF, limit*/
++ /* In case the bus fails to send 0xFF, limit */
+ for (i = 0; i <= 64; i++) {
+ if (w1_reset_bus(sl->master))
+ goto error;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0767-w1_therm-fix-reset_select_slave-during-discovery.patch b/target/linux/bcm27xx/patches-5.4/950-0767-w1_therm-fix-reset_select_slave-during-discovery.patch
new file mode 100644
index 0000000000..9881f81de4
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0767-w1_therm-fix-reset_select_slave-during-discovery.patch
@@ -0,0 +1,149 @@
+From dfc9fd0060f9103ca1f9335d529401ee8a105737 Mon Sep 17 00:00:00 2001
+From: Akira Shimahara <akira215corp@gmail.com>
+Date: Mon, 11 May 2020 22:36:10 +0200
+Subject: [PATCH] w1_therm: fix reset_select_slave during discovery
+
+commit c8ad65f6fbfdcb9b620674ef456020eef2bfeb36 upstream.
+
+Fix reset_select_slave issue during devices discovery by the master on
+bus. The w1_reset_select_slave() from w1_io.c, which was previously used,
+assume that if the slave count is 1 there is only one slave attached on
+the bus. This is not always true. For example when discovering devices,
+when the first device is discover by the bus master, its slave count is
+1, but some other slaves may be on the bus.
+
+In that case instead of adressing command to the attached slave the
+master throw a SKIP ROM command so that all slaves attached on the bus
+will answer simultenaously causing data collision.
+
+A dedicated reset_select_slave() function is implemented here,
+it always perform an adressing to each slave using the MATCH ROM
+command.
+
+Signed-off-by: Akira Shimahara <akira215corp@gmail.com>
+Link: https://lore.kernel.org/r/20200511203610.409975-1-akira215corp@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/w1/slaves/w1_therm.c | 48 ++++++++++++++++++++++++++++++------
+ 1 file changed, 41 insertions(+), 7 deletions(-)
+
+--- a/drivers/w1/slaves/w1_therm.c
++++ b/drivers/w1/slaves/w1_therm.c
+@@ -16,6 +16,7 @@
+ #include <linux/slab.h>
+ #include <linux/delay.h>
+ #include <linux/hwmon.h>
++#include <linux/string.h>
+
+ #include <linux/w1.h>
+
+@@ -90,6 +91,24 @@ struct therm_info {
+ u8 verdict;
+ };
+
++/* Hardware Functions declaration */
++
++/**
++ * reset_select_slave() - reset and select a slave
++ * @sl: the slave to select
++ *
++ * Resets the bus and select the slave by sending a ROM MATCH cmd
++ * w1_reset_select_slave() from w1_io.c could not be used here because
++ * it sent a SKIP ROM command if only one device is on the line.
++ * At the beginning of the such process, sl->master->slave_count is 1 even if
++ * more devices are on the line, causing collision on the line.
++ *
++ * Context: The w1 master lock must be held.
++ *
++ * Return: 0 if success, negative kernel error code otherwise.
++ */
++static int reset_select_slave(struct w1_slave *sl);
++
+ /* Sysfs interface declaration */
+
+ static ssize_t w1_slave_show(struct device *device,
+@@ -301,7 +320,7 @@ static inline int w1_DS18B20_precision(s
+ while (max_trying--) {
+ crc = 0;
+
+- if (!w1_reset_select_slave(sl)) {
++ if (!reset_select_slave(sl)) {
+ int count = 0;
+
+ /* read values to only alter precision bits */
+@@ -314,7 +333,7 @@ static inline int w1_DS18B20_precision(s
+ if (rom[8] == crc) {
+ rom[4] = (rom[4] & ~mask) | (precision_bits & mask);
+
+- if (!w1_reset_select_slave(sl)) {
++ if (!reset_select_slave(sl)) {
+ w1_write_8(dev, W1_WRITE_SCRATCHPAD);
+ w1_write_8(dev, rom[2]);
+ w1_write_8(dev, rom[3]);
+@@ -460,6 +479,21 @@ static void w1_therm_remove_slave(struct
+
+ /* Hardware Functions */
+
++/* Safe version of reset_select_slave - avoid using the one in w_io.c */
++static int reset_select_slave(struct w1_slave *sl)
++{
++ u8 match[9] = { W1_MATCH_ROM, };
++ u64 rn = le64_to_cpu(*((u64 *)&sl->reg_num));
++
++ if (w1_reset_bus(sl->master))
++ return -ENODEV;
++
++ memcpy(&match[1], &rn, 8);
++ w1_write_block(sl->master, match, 9);
++
++ return 0;
++}
++
+ static ssize_t read_therm(struct device *device,
+ struct w1_slave *sl, struct therm_info *info)
+ {
+@@ -487,7 +521,7 @@ static ssize_t read_therm(struct device
+ info->verdict = 0;
+ info->crc = 0;
+
+- if (!w1_reset_select_slave(sl)) {
++ if (!reset_select_slave(sl)) {
+ int count = 0;
+ unsigned int tm = 750;
+ unsigned long sleep_rem;
+@@ -495,7 +529,7 @@ static ssize_t read_therm(struct device
+ w1_write_8(dev, W1_READ_PSUPPLY);
+ external_power = w1_read_8(dev);
+
+- if (w1_reset_select_slave(sl))
++ if (reset_select_slave(sl))
+ continue;
+
+ /* 750ms strong pullup (or delay) after the convert */
+@@ -525,7 +559,7 @@ static ssize_t read_therm(struct device
+ }
+ }
+
+- if (!w1_reset_select_slave(sl)) {
++ if (!reset_select_slave(sl)) {
+
+ w1_write_8(dev, W1_READ_SCRATCHPAD);
+ count = w1_read_block(dev, info->rom, 9);
+@@ -577,7 +611,7 @@ static inline int w1_therm_eeprom(struct
+ memset(rom, 0, sizeof(rom));
+
+ while (max_trying--) {
+- if (!w1_reset_select_slave(sl)) {
++ if (!reset_select_slave(sl)) {
+ unsigned int tm = 10;
+ unsigned long sleep_rem;
+
+@@ -585,7 +619,7 @@ static inline int w1_therm_eeprom(struct
+ w1_write_8(dev, W1_READ_PSUPPLY);
+ external_power = w1_read_8(dev);
+
+- if (w1_reset_select_slave(sl))
++ if (reset_select_slave(sl))
+ continue;
+
+ /* 10ms strong pullup/delay after the copy command */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0768-w1_therm-adding-ext_power-sysfs-entry.patch b/target/linux/bcm27xx/patches-5.4/950-0768-w1_therm-adding-ext_power-sysfs-entry.patch
new file mode 100644
index 0000000000..b2e8195b64
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0768-w1_therm-adding-ext_power-sysfs-entry.patch
@@ -0,0 +1,293 @@
+From 5737e27d3c5e2f743421e68f926c05e8581ae21f Mon Sep 17 00:00:00 2001
+From: Akira Shimahara <akira215corp@gmail.com>
+Date: Mon, 11 May 2020 22:36:50 +0200
+Subject: [PATCH] w1_therm: adding ext_power sysfs entry
+
+commit b7bb6ca17a90f47c2fe2848531b5bbaf27a65ba7 upstream.
+
+Adding ext_power sysfs entry (RO). Return the power status of the device:
+ - 0: device parasite powered
+ - 1: device externally powered
+ - xx: xx is kernel error
+
+The power status of each device is check when the device is
+discover by the bus master, in 'w1_therm_add_slave(struct w1_slave *)'.
+The status is stored in the device structure w1_therm_family_data so
+that the driver always knows the power state of each device, which could
+be used later to determine the required strong pull up to apply on the
+line.
+
+The power status is re evaluate each time the sysfs ext_power read by
+a user.
+
+The hardware function 'read_powermode(struct w1_slave *sl)' act just as
+per device specifications, sending W1_READ_PSUPPLY command on the bus,
+and issue a read time slot, reading only one bit.
+
+A helper function 'bool bus_mutex_lock(struct mutex *lock)' is introduced.
+It try to aquire the bus mutex several times (W1_THERM_MAX_TRY), waiting
+W1_THERM_RETRY_DELAY between two attempt.
+
+Updating Documentation/ABI/testing/sysfs-driver-w1_therm accordingly.
+
+Signed-off-by: Akira Shimahara <akira215corp@gmail.com>
+Link: https://lore.kernel.org/r/20200511203650.410439-1-akira215corp@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ .../ABI/testing/sysfs-driver-w1_therm | 29 ++++
+ drivers/w1/slaves/w1_therm.c | 137 ++++++++++++++++++
+ 2 files changed, 166 insertions(+)
+ create mode 100644 Documentation/ABI/testing/sysfs-driver-w1_therm
+
+--- /dev/null
++++ b/Documentation/ABI/testing/sysfs-driver-w1_therm
+@@ -0,0 +1,29 @@
++What: /sys/bus/w1/devices/.../ext_power
++Date: May 2020
++Contact: Akira Shimahara <akira215corp@gmail.com>
++Description:
++ (RO) return the power status by asking the device
++ * '0': device parasite powered
++ * '1': device externally powered
++ * '-xx': xx is kernel error when reading power status
++Users: any user space application which wants to communicate with
++ w1_term device
++
++
++What: /sys/bus/w1/devices/.../w1_slave
++Date: May 2020
++Contact: Akira Shimahara <akira215corp@gmail.com>
++Description:
++ (RW) return the temperature in 1/1000 degC.
++ *read*: return 2 lines with the hexa output data sent on the
++ bus, return the CRC check and temperature in 1/1000 degC
++ *write* :
++ * '0' : save the 2 or 3 bytes to the device EEPROM
++ (i.e. TH, TL and config register)
++ * '9..12' : set the device resolution in RAM
++ (if supported)
++ * Anything else: do nothing
++ refer to Documentation/w1/slaves/w1_therm.rst for detailed
++ information.
++Users: any user space application which wants to communicate with
++ w1_term device
+\ No newline at end of file
+--- a/drivers/w1/slaves/w1_therm.c
++++ b/drivers/w1/slaves/w1_therm.c
+@@ -43,8 +43,21 @@
+ static int w1_strong_pullup = 1;
+ module_param_named(strong_pullup, w1_strong_pullup, int, 0);
+
++/* Nb of try for an operation */
++#define W1_THERM_MAX_TRY 5
++
++/* ms delay to retry bus mutex */
++#define W1_THERM_RETRY_DELAY 20
++
+ /* Helpers Macros */
+
++/*
++ * return the power mode of the sl slave : 1-ext, 0-parasite, <0 unknown
++ * always test family data existence before using this macro
++ */
++#define SLAVE_POWERMODE(sl) \
++ (((struct w1_therm_family_data *)(sl->family_data))->external_powered)
++
+ /* return the address of the refcnt in the family data */
+ #define THERM_REFCNT(family_data) \
+ (&((struct w1_therm_family_data *)family_data)->refcnt)
+@@ -73,10 +86,14 @@ struct w1_therm_family_converter {
+ * struct w1_therm_family_data - device data
+ * @rom: ROM device id (64bit Lasered ROM code + 1 CRC byte)
+ * @refcnt: ref count
++ * @external_powered: 1 device powered externally,
++ * 0 device parasite powered,
++ * -x error or undefined
+ */
+ struct w1_therm_family_data {
+ uint8_t rom[9];
+ atomic_t refcnt;
++ int external_powered;
+ };
+
+ /**
+@@ -109,6 +126,20 @@ struct therm_info {
+ */
+ static int reset_select_slave(struct w1_slave *sl);
+
++/**
++ * read_powermode() - Query the power mode of the slave
++ * @sl: slave to retrieve the power mode
++ *
++ * Ask the device to get its power mode (external or parasite)
++ * and store the power status in the &struct w1_therm_family_data.
++ *
++ * Return:
++ * * 0 parasite powered device
++ * * 1 externally powered device
++ * * <0 kernel error code
++ */
++static int read_powermode(struct w1_slave *sl);
++
+ /* Sysfs interface declaration */
+
+ static ssize_t w1_slave_show(struct device *device,
+@@ -120,10 +151,14 @@ static ssize_t w1_slave_store(struct dev
+ static ssize_t w1_seq_show(struct device *device,
+ struct device_attribute *attr, char *buf);
+
++static ssize_t ext_power_show(struct device *device,
++ struct device_attribute *attr, char *buf);
++
+ /* Attributes declarations */
+
+ static DEVICE_ATTR_RW(w1_slave);
+ static DEVICE_ATTR_RO(w1_seq);
++static DEVICE_ATTR_RO(ext_power);
+
+ /* Interface Functions declaration */
+
+@@ -151,12 +186,14 @@ static void w1_therm_remove_slave(struct
+
+ static struct attribute *w1_therm_attrs[] = {
+ &dev_attr_w1_slave.attr,
++ &dev_attr_ext_power.attr,
+ NULL,
+ };
+
+ static struct attribute *w1_ds28ea00_attrs[] = {
+ &dev_attr_w1_slave.attr,
+ &dev_attr_w1_seq.attr,
++ &dev_attr_ext_power.attr,
+ NULL,
+ };
+
+@@ -433,6 +470,34 @@ static struct w1_therm_family_converter
+ /* Helpers Functions */
+
+ /**
++ * bus_mutex_lock() - Acquire the mutex
++ * @lock: w1 bus mutex to acquire
++ *
++ * It try to acquire the mutex W1_THERM_MAX_TRY times and wait
++ * W1_THERM_RETRY_DELAY between 2 attempts.
++ *
++ * Return: true is mutex is acquired and lock, false otherwise
++ */
++static inline bool bus_mutex_lock(struct mutex *lock)
++{
++ int max_trying = W1_THERM_MAX_TRY;
++
++ /* try to acquire the mutex, if not, sleep retry_delay before retry) */
++ while (mutex_lock_interruptible(lock) != 0 && max_trying > 0) {
++ unsigned long sleep_rem;
++
++ sleep_rem = msleep_interruptible(W1_THERM_RETRY_DELAY);
++ if (!sleep_rem)
++ max_trying--;
++ }
++
++ if (!max_trying)
++ return false; /* Didn't acquire the bus mutex */
++
++ return true;
++}
++
++/**
+ * w1_convert_temp() - temperature conversion binding function
+ * @rom: data read from device RAM (8 data bytes + 1 CRC byte)
+ * @fid: device family id
+@@ -461,7 +526,19 @@ static int w1_therm_add_slave(struct w1_
+ GFP_KERNEL);
+ if (!sl->family_data)
+ return -ENOMEM;
++
+ atomic_set(THERM_REFCNT(sl->family_data), 1);
++
++ /* Getting the power mode of the device {external, parasite} */
++ SLAVE_POWERMODE(sl) = read_powermode(sl);
++
++ if (SLAVE_POWERMODE(sl) < 0) {
++ /* no error returned as device has been added */
++ dev_warn(&sl->dev,
++ "%s: Device has been added, but power_mode may be corrupted. err=%d\n",
++ __func__, SLAVE_POWERMODE(sl));
++ }
++
+ return 0;
+ }
+
+@@ -661,6 +738,44 @@ error:
+ return ret;
+ }
+
++static int read_powermode(struct w1_slave *sl)
++{
++ struct w1_master *dev_master = sl->master;
++ int max_trying = W1_THERM_MAX_TRY;
++ int ret = -ENODEV;
++
++ if (!sl->family_data)
++ goto error;
++
++ /* prevent the slave from going away in sleep */
++ atomic_inc(THERM_REFCNT(sl->family_data));
++
++ if (!bus_mutex_lock(&dev_master->bus_mutex)) {
++ ret = -EAGAIN; /* Didn't acquire the mutex */
++ goto dec_refcnt;
++ }
++
++ while ((max_trying--) && (ret < 0)) {
++ /* safe version to select slave */
++ if (!reset_select_slave(sl)) {
++ w1_write_8(dev_master, W1_READ_PSUPPLY);
++ /*
++ * Emit a read time slot and read only one bit,
++ * 1 is externally powered,
++ * 0 is parasite powered
++ */
++ ret = w1_touch_bit(dev_master, 1);
++ /* ret should be either 1 either 0 */
++ }
++ }
++ mutex_unlock(&dev_master->bus_mutex);
++
++dec_refcnt:
++ atomic_dec(THERM_REFCNT(sl->family_data));
++error:
++ return ret;
++}
++
+ /* Sysfs Interface definition */
+
+ static ssize_t w1_slave_show(struct device *device,
+@@ -722,6 +837,28 @@ static ssize_t w1_slave_store(struct dev
+ return ret ? : size;
+ }
+
++static ssize_t ext_power_show(struct device *device,
++ struct device_attribute *attr, char *buf)
++{
++ struct w1_slave *sl = dev_to_w1_slave(device);
++
++ if (!sl->family_data) {
++ dev_info(device,
++ "%s: Device not supported by the driver\n", __func__);
++ return 0; /* No device family */
++ }
++
++ /* Getting the power mode of the device {external, parasite} */
++ SLAVE_POWERMODE(sl) = read_powermode(sl);
++
++ if (SLAVE_POWERMODE(sl) < 0) {
++ dev_dbg(device,
++ "%s: Power_mode may be corrupted. err=%d\n",
++ __func__, SLAVE_POWERMODE(sl));
++ }
++ return sprintf(buf, "%d\n", SLAVE_POWERMODE(sl));
++}
++
+ #if IS_REACHABLE(CONFIG_HWMON)
+ static int w1_read_temp(struct device *device, u32 attr, int channel,
+ long *val)
diff --git a/target/linux/bcm27xx/patches-5.4/950-0769-w1_therm-adding-resolution-sysfs-entry.patch b/target/linux/bcm27xx/patches-5.4/950-0769-w1_therm-adding-resolution-sysfs-entry.patch
new file mode 100644
index 0000000000..17b047a0c7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0769-w1_therm-adding-resolution-sysfs-entry.patch
@@ -0,0 +1,713 @@
+From feffc2efed02adda00c6c5480292db012663e6e8 Mon Sep 17 00:00:00 2001
+From: Akira Shimahara <akira215corp@gmail.com>
+Date: Mon, 11 May 2020 22:37:08 +0200
+Subject: [PATCH] w1_therm: adding resolution sysfs entry
+
+commit 308bdb94de0c1abe7eac5193f58638b8aeaddf4b upstream.
+
+Adding resolution sysfs entry (RW) to get or set the device resolution
+Write values are managed as follow:
+ * '9..12': resolution to set in bit
+ * Anything else: do nothing
+Read values are :
+ * '9..12': device resolution in bit
+ * '-xx': xx is kernel error when reading the resolution
+
+Only supported devices will show the sysfs entry. A new family has been
+created for DS18S20 devices as they do not implement resolution feature.
+
+The resolution of each device is check when the device is
+discover by the bus master, in 'w1_therm_add_slave(struct w1_slave *)'.
+The status is stored in the device structure w1_therm_family_data so
+that the driver always knows the resolution of each device, which could
+be used later to determine the required conversion duration (resolution
+dependent).
+
+The resolution is re evaluate each time a user read or write the sysfs
+entry.
+
+To avoid looping through the w1_therm_families at run time, the pointer
+'specific_functions' is set up to the correct 'w1_therm_family_converter'
+when the slave is added (which mean when it is discovered by the master).
+This initialization is done by a helper function
+'device_family(struct w1_slave *sl)', and a dedicated macro
+'SLAVE_SPECIFIC_FUNC(sl)' allow the access to the specific function of the
+slave device.
+
+'read_scratchpad' and 'write_scratchpad' are the hardware functions to
+access the device RAM, as per protocol specification.
+
+It cancel the former 'precision' functions, which was only set and never
+read (so not stored in the device struct).
+
+Updating Documentation/ABI/testing/sysfs-driver-w1_therm accordingly.
+
+Signed-off-by: Akira Shimahara <akira215corp@gmail.com>
+Link: https://lore.kernel.org/r/20200511203708.410649-1-akira215corp@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ .../ABI/testing/sysfs-driver-w1_therm | 17 +
+ drivers/w1/slaves/w1_therm.c | 442 ++++++++++++++----
+ 2 files changed, 361 insertions(+), 98 deletions(-)
+
+--- a/Documentation/ABI/testing/sysfs-driver-w1_therm
++++ b/Documentation/ABI/testing/sysfs-driver-w1_therm
+@@ -10,6 +10,23 @@ Users: any user space application which
+ w1_term device
+
+
++What: /sys/bus/w1/devices/.../resolution
++Date: May 2020
++Contact: Akira Shimahara <akira215corp@gmail.com>
++Description:
++ (RW) get or set the device resolution (on supported devices,
++ if not, this entry is not present). Note that the resolution
++ will be changed only in device RAM, so it will be cleared when
++ power is lost. Trigger a 'save' to EEPROM command to keep
++ values after power-on. Read or write are :
++ * '9..12': device resolution in bit
++ or resolution to set in bit
++ * '-xx': xx is kernel error when reading the resolution
++ * Anything else: do nothing
++Users: any user space application which wants to communicate with
++ w1_term device
++
++
+ What: /sys/bus/w1/devices/.../w1_slave
+ Date: May 2020
+ Contact: Akira Shimahara <akira215corp@gmail.com>
+--- a/drivers/w1/slaves/w1_therm.c
++++ b/drivers/w1/slaves/w1_therm.c
+@@ -52,12 +52,26 @@ module_param_named(strong_pullup, w1_str
+ /* Helpers Macros */
+
+ /*
++ * return a pointer on the slave w1_therm_family_converter struct:
++ * always test family data existence before using this macro
++ */
++#define SLAVE_SPECIFIC_FUNC(sl) \
++ (((struct w1_therm_family_data *)(sl->family_data))->specific_functions)
++
++/*
+ * return the power mode of the sl slave : 1-ext, 0-parasite, <0 unknown
+ * always test family data existence before using this macro
+ */
+ #define SLAVE_POWERMODE(sl) \
+ (((struct w1_therm_family_data *)(sl->family_data))->external_powered)
+
++/*
++ * return the resolution in bit of the sl slave : <0 unknown
++ * always test family data existence before using this macro
++ */
++#define SLAVE_RESOLUTION(sl) \
++ (((struct w1_therm_family_data *)(sl->family_data))->resolution)
++
+ /* return the address of the refcnt in the family data */
+ #define THERM_REFCNT(family_data) \
+ (&((struct w1_therm_family_data *)family_data)->refcnt)
+@@ -70,7 +84,8 @@ module_param_named(strong_pullup, w1_str
+ * @reserved: not used here
+ * @f: pointer to the device binding structure
+ * @convert: pointer to the device conversion function
+- * @precision: pointer to the device precision function
++ * @set_resolution: pointer to the device set_resolution function
++ * @get_resolution: pointer to the device get_resolution function
+ * @eeprom: pointer to eeprom function
+ */
+ struct w1_therm_family_converter {
+@@ -78,7 +93,8 @@ struct w1_therm_family_converter {
+ u16 reserved;
+ struct w1_family *f;
+ int (*convert)(u8 rom[9]);
+- int (*precision)(struct device *device, int val);
++ int (*set_resolution)(struct w1_slave *sl, int val);
++ int (*get_resolution)(struct w1_slave *sl);
+ int (*eeprom)(struct device *device);
+ };
+
+@@ -89,11 +105,15 @@ struct w1_therm_family_converter {
+ * @external_powered: 1 device powered externally,
+ * 0 device parasite powered,
+ * -x error or undefined
++ * @resolution: current device resolution
++ * @specific_functions: pointer to struct of device specific function
+ */
+ struct w1_therm_family_data {
+ uint8_t rom[9];
+ atomic_t refcnt;
+ int external_powered;
++ int resolution;
++ struct w1_therm_family_converter *specific_functions;
+ };
+
+ /**
+@@ -127,6 +147,25 @@ struct therm_info {
+ static int reset_select_slave(struct w1_slave *sl);
+
+ /**
++ * read_scratchpad() - read the data in device RAM
++ * @sl: pointer to the slave to read
++ * @info: pointer to a structure to store the read results
++ *
++ * Return: 0 if success, -kernel error code otherwise
++ */
++static int read_scratchpad(struct w1_slave *sl, struct therm_info *info);
++
++/**
++ * write_scratchpad() - write nb_bytes in the device RAM
++ * @sl: pointer to the slave to write in
++ * @data: pointer to an array of 3 bytes, as 3 bytes MUST be written
++ * @nb_bytes: number of bytes to be written (2 for DS18S20, 3 otherwise)
++ *
++ * Return: 0 if success, -kernel error code otherwise
++ */
++static int write_scratchpad(struct w1_slave *sl, const u8 *data, u8 nb_bytes);
++
++/**
+ * read_powermode() - Query the power mode of the slave
+ * @sl: slave to retrieve the power mode
+ *
+@@ -154,11 +193,18 @@ static ssize_t w1_seq_show(struct device
+ static ssize_t ext_power_show(struct device *device,
+ struct device_attribute *attr, char *buf);
+
++static ssize_t resolution_show(struct device *device,
++ struct device_attribute *attr, char *buf);
++
++static ssize_t resolution_store(struct device *device,
++ struct device_attribute *attr, const char *buf, size_t size);
++
+ /* Attributes declarations */
+
+ static DEVICE_ATTR_RW(w1_slave);
+ static DEVICE_ATTR_RO(w1_seq);
+ static DEVICE_ATTR_RO(ext_power);
++static DEVICE_ATTR_RW(resolution);
+
+ /* Interface Functions declaration */
+
+@@ -187,6 +233,13 @@ static void w1_therm_remove_slave(struct
+ static struct attribute *w1_therm_attrs[] = {
+ &dev_attr_w1_slave.attr,
+ &dev_attr_ext_power.attr,
++ &dev_attr_resolution.attr,
++ NULL,
++};
++
++static struct attribute *w1_ds18s20_attrs[] = {
++ &dev_attr_w1_slave.attr,
++ &dev_attr_ext_power.attr,
+ NULL,
+ };
+
+@@ -194,12 +247,14 @@ static struct attribute *w1_ds28ea00_att
+ &dev_attr_w1_slave.attr,
+ &dev_attr_w1_seq.attr,
+ &dev_attr_ext_power.attr,
++ &dev_attr_resolution.attr,
+ NULL,
+ };
+
+ /* Attribute groups */
+
+ ATTRIBUTE_GROUPS(w1_therm);
++ATTRIBUTE_GROUPS(w1_ds18s20);
+ ATTRIBUTE_GROUPS(w1_ds28ea00);
+
+ #if IS_REACHABLE(CONFIG_HWMON)
+@@ -261,6 +316,13 @@ static struct w1_family_ops w1_therm_fop
+ .chip_info = W1_CHIPINFO,
+ };
+
++static struct w1_family_ops w1_ds18s20_fops = {
++ .add_slave = w1_therm_add_slave,
++ .remove_slave = w1_therm_remove_slave,
++ .groups = w1_ds18s20_groups,
++ .chip_info = W1_CHIPINFO,
++};
++
+ static struct w1_family_ops w1_ds28ea00_fops = {
+ .add_slave = w1_therm_add_slave,
+ .remove_slave = w1_therm_remove_slave,
+@@ -272,7 +334,7 @@ static struct w1_family_ops w1_ds28ea00_
+
+ static struct w1_family w1_therm_family_DS18S20 = {
+ .fid = W1_THERM_DS18S20,
+- .fops = &w1_therm_fops,
++ .fops = &w1_ds18s20_fops,
+ };
+
+ static struct w1_family w1_therm_family_DS18B20 = {
+@@ -300,92 +362,67 @@ static struct w1_family w1_therm_family_
+ /* write configuration to eeprom */
+ static inline int w1_therm_eeprom(struct device *device);
+
+-/* DS18S20 does not feature configuration register */
+-static inline int w1_DS18S20_precision(struct device *device, int val)
++static inline int w1_DS18B20_write_data(struct w1_slave *sl,
++ const u8 *data)
+ {
+- return 0;
++ return write_scratchpad(sl, data, 3);
+ }
+
+-/* Set precision for conversion */
+-static inline int w1_DS18B20_precision(struct device *device, int val)
++static inline int w1_DS18S20_write_data(struct w1_slave *sl,
++ const u8 *data)
+ {
+- struct w1_slave *sl = dev_to_w1_slave(device);
+- struct w1_master *dev = sl->master;
+- u8 rom[9], crc;
+- int ret, max_trying = 10;
+- u8 *family_data = sl->family_data;
+- uint8_t precision_bits;
+- uint8_t mask = 0x60;
+-
+- if (val > 12 || val < 9) {
+- pr_warn("Unsupported precision\n");
+- ret = -EINVAL;
+- goto error;
+- }
+-
+- if (!sl->family_data) {
+- ret = -ENODEV;
+- goto error;
+- }
+-
+- /* prevent the slave from going away in sleep */
+- atomic_inc(THERM_REFCNT(family_data));
++ /* No config register */
++ return write_scratchpad(sl, data, 2);
++}
+
+- ret = mutex_lock_interruptible(&dev->bus_mutex);
+- if (ret != 0)
+- goto dec_refcnt;
++static inline int w1_DS18B20_set_resolution(struct w1_slave *sl, int val)
++{
++ int ret = -ENODEV;
++ u8 new_config_register[3]; /* array of data to be written */
++ struct therm_info info;
+
+- memset(rom, 0, sizeof(rom));
++ /* resolution of DS18B20 is in the range [9..12] bits */
++ if (val < 9 || val > 12)
++ return -EINVAL;
++
++ val -= 9; /* soustract 9 the lowest resolution in bit */
++ val = (val << 5); /* shift to position bit 5 & bit 6 */
++
++ /*
++ * Read the scratchpad to change only the required bits
++ * (bit5 & bit 6 from byte 4)
++ */
++ ret = read_scratchpad(sl, &info);
++ if (!ret) {
++ new_config_register[0] = info.rom[2];
++ new_config_register[1] = info.rom[3];
++ /* config register is byte 4 & mask 0b10011111*/
++ new_config_register[2] = (info.rom[4] & 0x9F) |
++ (u8) val;
++ } else
++ return ret;
+
+- /* translate precision to bitmask (see datasheet page 9) */
+- switch (val) {
+- case 9:
+- precision_bits = 0x00;
+- break;
+- case 10:
+- precision_bits = 0x20;
+- break;
+- case 11:
+- precision_bits = 0x40;
+- break;
+- case 12:
+- default:
+- precision_bits = 0x60;
+- break;
+- }
++ /* Write data in the device RAM */
++ ret = w1_DS18B20_write_data(sl, new_config_register);
+
+- while (max_trying--) {
+- crc = 0;
++ return ret;
++}
+
+- if (!reset_select_slave(sl)) {
+- int count = 0;
++static inline int w1_DS18B20_get_resolution(struct w1_slave *sl)
++{
++ int ret = -ENODEV;
++ u8 config_register;
++ struct therm_info info;
+
+- /* read values to only alter precision bits */
+- w1_write_8(dev, W1_READ_SCRATCHPAD);
+- count = w1_read_block(dev, rom, 9);
+- if (count != 9)
+- dev_warn(device, "w1_read_block() returned %u instead of 9.\n", count);
+-
+- crc = w1_calc_crc8(rom, 8);
+- if (rom[8] == crc) {
+- rom[4] = (rom[4] & ~mask) | (precision_bits & mask);
+-
+- if (!reset_select_slave(sl)) {
+- w1_write_8(dev, W1_WRITE_SCRATCHPAD);
+- w1_write_8(dev, rom[2]);
+- w1_write_8(dev, rom[3]);
+- w1_write_8(dev, rom[4]);
++ ret = read_scratchpad(sl, &info);
+
+- break;
+- }
+- }
+- }
++ if (!ret) {
++ config_register = info.rom[4]; /* config register is byte 4 */
++ config_register &= 0x60; /* 0b01100000 keep only bit 5 & 6 */
++ config_register = (config_register >> 5); /* shift */
++ config_register += 9; /* add 9 the lowest resolution in bit */
++ ret = (int) config_register;
+ }
+-
+- mutex_unlock(&dev->bus_mutex);
+-dec_refcnt:
+- atomic_dec(THERM_REFCNT(family_data));
+-error:
+ return ret;
+ }
+
+@@ -438,31 +475,36 @@ static struct w1_therm_family_converter
+ {
+ .f = &w1_therm_family_DS18S20,
+ .convert = w1_DS18S20_convert_temp,
+- .precision = w1_DS18S20_precision,
++ .set_resolution = NULL, /* no config register */
++ .get_resolution = NULL, /* no config register */
+ .eeprom = w1_therm_eeprom
+ },
+ {
+ .f = &w1_therm_family_DS1822,
+ .convert = w1_DS18B20_convert_temp,
+- .precision = w1_DS18S20_precision,
++ .set_resolution = w1_DS18B20_set_resolution,
++ .get_resolution = w1_DS18B20_get_resolution,
+ .eeprom = w1_therm_eeprom
+ },
+ {
+ .f = &w1_therm_family_DS18B20,
+ .convert = w1_DS18B20_convert_temp,
+- .precision = w1_DS18B20_precision,
++ .set_resolution = w1_DS18B20_set_resolution,
++ .get_resolution = w1_DS18B20_get_resolution,
+ .eeprom = w1_therm_eeprom
+ },
+ {
+ .f = &w1_therm_family_DS28EA00,
+ .convert = w1_DS18B20_convert_temp,
+- .precision = w1_DS18S20_precision,
++ .set_resolution = w1_DS18B20_set_resolution,
++ .get_resolution = w1_DS18B20_get_resolution,
+ .eeprom = w1_therm_eeprom
+ },
+ {
+ .f = &w1_therm_family_DS1825,
+ .convert = w1_DS18B20_convert_temp,
+- .precision = w1_DS18S20_precision,
++ .set_resolution = w1_DS18B20_set_resolution,
++ .get_resolution = w1_DS18B20_get_resolution,
+ .eeprom = w1_therm_eeprom
+ }
+ };
+@@ -470,6 +512,26 @@ static struct w1_therm_family_converter
+ /* Helpers Functions */
+
+ /**
++ * device_family() - Retrieve a pointer on &struct w1_therm_family_converter
++ * @sl: slave to retrieve the device specific structure
++ *
++ * Return: pointer to the slaves's family converter, NULL if not known
++ */
++static struct w1_therm_family_converter *device_family(struct w1_slave *sl)
++{
++ struct w1_therm_family_converter *ret = NULL;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i) {
++ if (w1_therm_families[i].f->fid == sl->family->fid) {
++ ret = &w1_therm_families[i];
++ break;
++ }
++ }
++ return ret;
++}
++
++/**
+ * bus_mutex_lock() - Acquire the mutex
+ * @lock: w1 bus mutex to acquire
+ *
+@@ -522,6 +584,9 @@ static inline int w1_convert_temp(u8 rom
+
+ static int w1_therm_add_slave(struct w1_slave *sl)
+ {
++ struct w1_therm_family_converter *sl_family_conv;
++
++ /* Allocate memory */
+ sl->family_data = kzalloc(sizeof(struct w1_therm_family_data),
+ GFP_KERNEL);
+ if (!sl->family_data)
+@@ -529,6 +594,15 @@ static int w1_therm_add_slave(struct w1_
+
+ atomic_set(THERM_REFCNT(sl->family_data), 1);
+
++ /* Get a pointer to the device specific function struct */
++ sl_family_conv = device_family(sl);
++ if (!sl_family_conv) {
++ kfree(sl->family_data);
++ return -ENODEV;
++ }
++ /* save this pointer to the device structure */
++ SLAVE_SPECIFIC_FUNC(sl) = sl_family_conv;
++
+ /* Getting the power mode of the device {external, parasite} */
+ SLAVE_POWERMODE(sl) = read_powermode(sl);
+
+@@ -539,6 +613,18 @@ static int w1_therm_add_slave(struct w1_
+ __func__, SLAVE_POWERMODE(sl));
+ }
+
++ /* Getting the resolution of the device */
++ if (SLAVE_SPECIFIC_FUNC(sl)->get_resolution) {
++ SLAVE_RESOLUTION(sl) =
++ SLAVE_SPECIFIC_FUNC(sl)->get_resolution(sl);
++ if (SLAVE_RESOLUTION(sl) < 0) {
++ /* no error returned as device has been added */
++ dev_warn(&sl->dev,
++ "%s:Device has been added, but resolution may be corrupted. err=%d\n",
++ __func__, SLAVE_RESOLUTION(sl));
++ }
++ }
++
+ return 0;
+ }
+
+@@ -665,6 +751,93 @@ error:
+ return ret;
+ }
+
++static int read_scratchpad(struct w1_slave *sl, struct therm_info *info)
++{
++ struct w1_master *dev_master = sl->master;
++ int max_trying = W1_THERM_MAX_TRY;
++ int ret = -ENODEV;
++
++ info->verdict = 0;
++
++ if (!sl->family_data)
++ goto error;
++
++ memset(info->rom, 0, sizeof(info->rom));
++
++ /* prevent the slave from going away in sleep */
++ atomic_inc(THERM_REFCNT(sl->family_data));
++
++ if (!bus_mutex_lock(&dev_master->bus_mutex)) {
++ ret = -EAGAIN; /* Didn't acquire the mutex */
++ goto dec_refcnt;
++ }
++
++ while (max_trying-- && ret) { /* ret should be 0 */
++ /* safe version to select slave */
++ if (!reset_select_slave(sl)) {
++ u8 nb_bytes_read;
++
++ w1_write_8(dev_master, W1_READ_SCRATCHPAD);
++
++ nb_bytes_read = w1_read_block(dev_master, info->rom, 9);
++ if (nb_bytes_read != 9) {
++ dev_warn(&sl->dev,
++ "w1_read_block(): returned %u instead of 9.\n",
++ nb_bytes_read);
++ ret = -EIO;
++ }
++
++ info->crc = w1_calc_crc8(info->rom, 8);
++
++ if (info->rom[8] == info->crc) {
++ info->verdict = 1;
++ ret = 0;
++ } else
++ ret = -EIO; /* CRC not checked */
++ }
++
++ }
++ mutex_unlock(&dev_master->bus_mutex);
++
++dec_refcnt:
++ atomic_dec(THERM_REFCNT(sl->family_data));
++error:
++ return ret;
++}
++
++static int write_scratchpad(struct w1_slave *sl, const u8 *data, u8 nb_bytes)
++{
++ struct w1_master *dev_master = sl->master;
++ int max_trying = W1_THERM_MAX_TRY;
++ int ret = -ENODEV;
++
++ if (!sl->family_data)
++ goto error;
++
++ /* prevent the slave from going away in sleep */
++ atomic_inc(THERM_REFCNT(sl->family_data));
++
++ if (!bus_mutex_lock(&dev_master->bus_mutex)) {
++ ret = -EAGAIN; /* Didn't acquire the mutex */
++ goto dec_refcnt;
++ }
++
++ while (max_trying-- && ret) { /* ret should be 0 */
++ /* safe version to select slave */
++ if (!reset_select_slave(sl)) {
++ w1_write_8(dev_master, W1_WRITE_SCRATCHPAD);
++ w1_write_block(dev_master, data, nb_bytes);
++ ret = 0;
++ }
++ }
++ mutex_unlock(&dev_master->bus_mutex);
++
++dec_refcnt:
++ atomic_dec(THERM_REFCNT(sl->family_data));
++error:
++ return ret;
++}
++
+ static inline int w1_therm_eeprom(struct device *device)
+ {
+ struct w1_slave *sl = dev_to_w1_slave(device);
+@@ -815,26 +988,38 @@ static ssize_t w1_slave_store(struct dev
+ struct device_attribute *attr, const char *buf,
+ size_t size)
+ {
+- int val, ret;
++ int val, ret = 0;
+ struct w1_slave *sl = dev_to_w1_slave(device);
+- int i;
+
+- ret = kstrtoint(buf, 0, &val);
+- if (ret)
+- return ret;
++ ret = kstrtoint(buf, 10, &val); /* converting user entry to int */
+
+- for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i) {
+- if (w1_therm_families[i].f->fid == sl->family->fid) {
+- /* zero value indicates to write current configuration to eeprom */
+- if (val == 0)
+- ret = w1_therm_families[i].eeprom(device);
+- else
+- ret = w1_therm_families[i].precision(device,
+- val);
+- break;
+- }
++ if (ret) { /* conversion error */
++ dev_info(device,
++ "%s: conversion error. err= %d\n", __func__, ret);
++ return size; /* return size to avoid call back again */
++ }
++
++ if ((!sl->family_data) || (!SLAVE_SPECIFIC_FUNC(sl))) {
++ dev_info(device,
++ "%s: Device not supported by the driver\n", __func__);
++ return size; /* No device family */
++ }
++
++ if (val == 0) /* val=0 : trigger a EEPROM save */
++ ret = SLAVE_SPECIFIC_FUNC(sl)->eeprom(device);
++ else {
++ if (SLAVE_SPECIFIC_FUNC(sl)->set_resolution)
++ ret = SLAVE_SPECIFIC_FUNC(sl)->set_resolution(sl, val);
+ }
+- return ret ? : size;
++
++ if (ret) {
++ dev_info(device,
++ "%s: writing error %d\n", __func__, ret);
++ /* return size to avoid call back again */
++ } else
++ SLAVE_RESOLUTION(sl) = val;
++
++ return size; /* always return size to avoid infinite calling */
+ }
+
+ static ssize_t ext_power_show(struct device *device,
+@@ -859,6 +1044,67 @@ static ssize_t ext_power_show(struct dev
+ return sprintf(buf, "%d\n", SLAVE_POWERMODE(sl));
+ }
+
++static ssize_t resolution_show(struct device *device,
++ struct device_attribute *attr, char *buf)
++{
++ struct w1_slave *sl = dev_to_w1_slave(device);
++
++ if ((!sl->family_data) || (!SLAVE_SPECIFIC_FUNC(sl))) {
++ dev_info(device,
++ "%s: Device not supported by the driver\n", __func__);
++ return 0; /* No device family */
++ }
++
++ /* get the correct function depending on the device */
++ SLAVE_RESOLUTION(sl) = SLAVE_SPECIFIC_FUNC(sl)->get_resolution(sl);
++ if (SLAVE_RESOLUTION(sl) < 0) {
++ dev_dbg(device,
++ "%s: Resolution may be corrupted. err=%d\n",
++ __func__, SLAVE_RESOLUTION(sl));
++ }
++
++ return sprintf(buf, "%d\n", SLAVE_RESOLUTION(sl));
++}
++
++static ssize_t resolution_store(struct device *device,
++ struct device_attribute *attr, const char *buf, size_t size)
++{
++ struct w1_slave *sl = dev_to_w1_slave(device);
++ int val;
++ int ret = 0;
++
++ ret = kstrtoint(buf, 10, &val); /* converting user entry to int */
++
++ if (ret) { /* conversion error */
++ dev_info(device,
++ "%s: conversion error. err= %d\n", __func__, ret);
++ return size; /* return size to avoid call back again */
++ }
++
++ if ((!sl->family_data) || (!SLAVE_SPECIFIC_FUNC(sl))) {
++ dev_info(device,
++ "%s: Device not supported by the driver\n", __func__);
++ return size; /* No device family */
++ }
++
++ /*
++ * Don't deal with the val enterd by user,
++ * only device knows what is correct or not
++ */
++
++ /* get the correct function depending on the device */
++ ret = SLAVE_SPECIFIC_FUNC(sl)->set_resolution(sl, val);
++
++ if (ret) {
++ dev_info(device,
++ "%s: writing error %d\n", __func__, ret);
++ /* return size to avoid call back again */
++ } else
++ SLAVE_RESOLUTION(sl) = val;
++
++ return size;
++}
++
+ #if IS_REACHABLE(CONFIG_HWMON)
+ static int w1_read_temp(struct device *device, u32 attr, int channel,
+ long *val)
diff --git a/target/linux/bcm27xx/patches-5.4/950-0770-w1_therm-adding-eeprom-sysfs-entry.patch b/target/linux/bcm27xx/patches-5.4/950-0770-w1_therm-adding-eeprom-sysfs-entry.patch
new file mode 100644
index 0000000000..58467a00c3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0770-w1_therm-adding-eeprom-sysfs-entry.patch
@@ -0,0 +1,372 @@
+From 855a8d82506c7c2428e13beebe8dbf7739ea6176 Mon Sep 17 00:00:00 2001
+From: Akira Shimahara <akira215corp@gmail.com>
+Date: Mon, 11 May 2020 22:37:25 +0200
+Subject: [PATCH] w1_therm: adding eeprom sysfs entry
+
+commit 45d457a4cf24455eefd076a01a3d86414fc2ff1e upstream.
+
+The driver implement 2 hardware functions to access device RAM:
+ * copy_scratchpad
+ * recall_scratchpad
+They act according to device specifications.
+
+As EEPROM operations are not device dependent (all w1_therm can perform
+EEPROM read/write operation following the same protocol), it is removed
+from device families structures.
+
+Updating Documentation/ABI/testing/sysfs-driver-w1_therm accordingly.
+
+Signed-off-by: Akira Shimahara <akira215corp@gmail.com>
+Link: https://lore.kernel.org/r/20200511203725.410844-1-akira215corp@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ .../ABI/testing/sysfs-driver-w1_therm | 14 ++
+ drivers/w1/slaves/w1_therm.c | 175 ++++++++++++------
+ 2 files changed, 132 insertions(+), 57 deletions(-)
+
+--- a/Documentation/ABI/testing/sysfs-driver-w1_therm
++++ b/Documentation/ABI/testing/sysfs-driver-w1_therm
+@@ -1,3 +1,17 @@
++What: /sys/bus/w1/devices/.../eeprom
++Date: May 2020
++Contact: Akira Shimahara <akira215corp@gmail.com>
++Description:
++ (WO) writing that file will either trigger a save of the
++ device data to its embedded EEPROM, either restore data
++ embedded in device EEPROM. Be aware that devices support
++ limited EEPROM writing cycles (typical 50k)
++ * 'save': save device RAM to EEPROM
++ * 'restore': restore EEPROM data in device RAM
++Users: any user space application which wants to communicate with
++ w1_term device
++
++
+ What: /sys/bus/w1/devices/.../ext_power
+ Date: May 2020
+ Contact: Akira Shimahara <akira215corp@gmail.com>
+--- a/drivers/w1/slaves/w1_therm.c
++++ b/drivers/w1/slaves/w1_therm.c
+@@ -43,12 +43,21 @@
+ static int w1_strong_pullup = 1;
+ module_param_named(strong_pullup, w1_strong_pullup, int, 0);
+
++/* This command should be in public header w1.h but is not */
++#define W1_RECALL_EEPROM 0xB8
++
+ /* Nb of try for an operation */
+ #define W1_THERM_MAX_TRY 5
+
+ /* ms delay to retry bus mutex */
+ #define W1_THERM_RETRY_DELAY 20
+
++/* delay in ms to write in EEPROM */
++#define W1_THERM_EEPROM_WRITE_DELAY 10
++
++#define EEPROM_CMD_WRITE "save" /* cmd for write eeprom sysfs */
++#define EEPROM_CMD_READ "restore" /* cmd for read eeprom sysfs */
++
+ /* Helpers Macros */
+
+ /*
+@@ -86,7 +95,6 @@ module_param_named(strong_pullup, w1_str
+ * @convert: pointer to the device conversion function
+ * @set_resolution: pointer to the device set_resolution function
+ * @get_resolution: pointer to the device get_resolution function
+- * @eeprom: pointer to eeprom function
+ */
+ struct w1_therm_family_converter {
+ u8 broken;
+@@ -95,7 +103,6 @@ struct w1_therm_family_converter {
+ int (*convert)(u8 rom[9]);
+ int (*set_resolution)(struct w1_slave *sl, int val);
+ int (*get_resolution)(struct w1_slave *sl);
+- int (*eeprom)(struct device *device);
+ };
+
+ /**
+@@ -166,6 +173,22 @@ static int read_scratchpad(struct w1_sla
+ static int write_scratchpad(struct w1_slave *sl, const u8 *data, u8 nb_bytes);
+
+ /**
++ * copy_scratchpad() - Copy the content of scratchpad in device EEPROM
++ * @sl: slave involved
++ *
++ * Return: 0 if success, -kernel error code otherwise
++ */
++static int copy_scratchpad(struct w1_slave *sl);
++
++/**
++ * recall_eeprom() - Restore EEPROM data to device RAM
++ * @sl: slave involved
++ *
++ * Return: 0 if success, -kernel error code otherwise
++ */
++static int recall_eeprom(struct w1_slave *sl);
++
++/**
+ * read_powermode() - Query the power mode of the slave
+ * @sl: slave to retrieve the power mode
+ *
+@@ -199,12 +222,16 @@ static ssize_t resolution_show(struct de
+ static ssize_t resolution_store(struct device *device,
+ struct device_attribute *attr, const char *buf, size_t size);
+
++static ssize_t eeprom_store(struct device *device,
++ struct device_attribute *attr, const char *buf, size_t size);
++
+ /* Attributes declarations */
+
+ static DEVICE_ATTR_RW(w1_slave);
+ static DEVICE_ATTR_RO(w1_seq);
+ static DEVICE_ATTR_RO(ext_power);
+ static DEVICE_ATTR_RW(resolution);
++static DEVICE_ATTR_WO(eeprom);
+
+ /* Interface Functions declaration */
+
+@@ -234,12 +261,14 @@ static struct attribute *w1_therm_attrs[
+ &dev_attr_w1_slave.attr,
+ &dev_attr_ext_power.attr,
+ &dev_attr_resolution.attr,
++ &dev_attr_eeprom.attr,
+ NULL,
+ };
+
+ static struct attribute *w1_ds18s20_attrs[] = {
+ &dev_attr_w1_slave.attr,
+ &dev_attr_ext_power.attr,
++ &dev_attr_eeprom.attr,
+ NULL,
+ };
+
+@@ -248,6 +277,7 @@ static struct attribute *w1_ds28ea00_att
+ &dev_attr_w1_seq.attr,
+ &dev_attr_ext_power.attr,
+ &dev_attr_resolution.attr,
++ &dev_attr_eeprom.attr,
+ NULL,
+ };
+
+@@ -359,9 +389,6 @@ static struct w1_family w1_therm_family_
+
+ /* Device dependent func */
+
+-/* write configuration to eeprom */
+-static inline int w1_therm_eeprom(struct device *device);
+-
+ static inline int w1_DS18B20_write_data(struct w1_slave *sl,
+ const u8 *data)
+ {
+@@ -477,35 +504,30 @@ static struct w1_therm_family_converter
+ .convert = w1_DS18S20_convert_temp,
+ .set_resolution = NULL, /* no config register */
+ .get_resolution = NULL, /* no config register */
+- .eeprom = w1_therm_eeprom
+ },
+ {
+ .f = &w1_therm_family_DS1822,
+ .convert = w1_DS18B20_convert_temp,
+ .set_resolution = w1_DS18B20_set_resolution,
+ .get_resolution = w1_DS18B20_get_resolution,
+- .eeprom = w1_therm_eeprom
+ },
+ {
+ .f = &w1_therm_family_DS18B20,
+ .convert = w1_DS18B20_convert_temp,
+ .set_resolution = w1_DS18B20_set_resolution,
+ .get_resolution = w1_DS18B20_get_resolution,
+- .eeprom = w1_therm_eeprom
+ },
+ {
+ .f = &w1_therm_family_DS28EA00,
+ .convert = w1_DS18B20_convert_temp,
+ .set_resolution = w1_DS18B20_set_resolution,
+ .get_resolution = w1_DS18B20_get_resolution,
+- .eeprom = w1_therm_eeprom
+ },
+ {
+ .f = &w1_therm_family_DS1825,
+ .convert = w1_DS18B20_convert_temp,
+ .set_resolution = w1_DS18B20_set_resolution,
+ .get_resolution = w1_DS18B20_get_resolution,
+- .eeprom = w1_therm_eeprom
+ }
+ };
+
+@@ -838,75 +860,94 @@ error:
+ return ret;
+ }
+
+-static inline int w1_therm_eeprom(struct device *device)
++static int copy_scratchpad(struct w1_slave *sl)
+ {
+- struct w1_slave *sl = dev_to_w1_slave(device);
+- struct w1_master *dev = sl->master;
+- u8 rom[9], external_power;
+- int ret, max_trying = 10;
+- u8 *family_data = sl->family_data;
++ struct w1_master *dev_master = sl->master;
++ int max_trying = W1_THERM_MAX_TRY;
++ int t_write, ret = -ENODEV;
++ bool strong_pullup;
+
+- if (!sl->family_data) {
+- ret = -ENODEV;
++ if (!sl->family_data)
+ goto error;
+- }
++
++ t_write = W1_THERM_EEPROM_WRITE_DELAY;
++ strong_pullup = (w1_strong_pullup == 2 ||
++ (!SLAVE_POWERMODE(sl) &&
++ w1_strong_pullup));
+
+ /* prevent the slave from going away in sleep */
+- atomic_inc(THERM_REFCNT(family_data));
++ atomic_inc(THERM_REFCNT(sl->family_data));
+
+- ret = mutex_lock_interruptible(&dev->bus_mutex);
+- if (ret != 0)
++ if (!bus_mutex_lock(&dev_master->bus_mutex)) {
++ ret = -EAGAIN; /* Didn't acquire the mutex */
+ goto dec_refcnt;
++ }
+
+- memset(rom, 0, sizeof(rom));
+-
+- while (max_trying--) {
++ while (max_trying-- && ret) { /* ret should be 0 */
++ /* safe version to select slave */
+ if (!reset_select_slave(sl)) {
+- unsigned int tm = 10;
+ unsigned long sleep_rem;
+
+- /* check if in parasite mode */
+- w1_write_8(dev, W1_READ_PSUPPLY);
+- external_power = w1_read_8(dev);
+-
+- if (reset_select_slave(sl))
+- continue;
+-
+- /* 10ms strong pullup/delay after the copy command */
+- if (w1_strong_pullup == 2 ||
+- (!external_power && w1_strong_pullup))
+- w1_next_pullup(dev, tm);
+-
+- w1_write_8(dev, W1_COPY_SCRATCHPAD);
+-
+- if (external_power) {
+- mutex_unlock(&dev->bus_mutex);
++ /* 10ms strong pullup (or delay) after the convert */
++ if (strong_pullup)
++ w1_next_pullup(dev_master, t_write);
+
+- sleep_rem = msleep_interruptible(tm);
+- if (sleep_rem != 0) {
+- ret = -EINTR;
+- goto dec_refcnt;
+- }
++ w1_write_8(dev_master, W1_COPY_SCRATCHPAD);
+
+- ret = mutex_lock_interruptible(&dev->bus_mutex);
+- if (ret != 0)
+- goto dec_refcnt;
+- } else if (!w1_strong_pullup) {
+- sleep_rem = msleep_interruptible(tm);
++ if (strong_pullup) {
++ sleep_rem = msleep_interruptible(t_write);
+ if (sleep_rem != 0) {
+ ret = -EINTR;
+ goto mt_unlock;
+ }
+ }
+-
+- break;
++ ret = 0;
+ }
++
+ }
+
+ mt_unlock:
+- mutex_unlock(&dev->bus_mutex);
++ mutex_unlock(&dev_master->bus_mutex);
+ dec_refcnt:
+- atomic_dec(THERM_REFCNT(family_data));
++ atomic_dec(THERM_REFCNT(sl->family_data));
++error:
++ return ret;
++}
++
++static int recall_eeprom(struct w1_slave *sl)
++{
++ struct w1_master *dev_master = sl->master;
++ int max_trying = W1_THERM_MAX_TRY;
++ int ret = -ENODEV;
++
++ if (!sl->family_data)
++ goto error;
++
++ /* prevent the slave from going away in sleep */
++ atomic_inc(THERM_REFCNT(sl->family_data));
++
++ if (!bus_mutex_lock(&dev_master->bus_mutex)) {
++ ret = -EAGAIN; /* Didn't acquire the mutex */
++ goto dec_refcnt;
++ }
++
++ while (max_trying-- && ret) { /* ret should be 0 */
++ /* safe version to select slave */
++ if (!reset_select_slave(sl)) {
++
++ w1_write_8(dev_master, W1_RECALL_EEPROM);
++
++ ret = 1; /* Slave will pull line to 0 */
++ while (ret)
++ ret = 1 - w1_touch_bit(dev_master, 1);
++ }
++
++ }
++
++ mutex_unlock(&dev_master->bus_mutex);
++
++dec_refcnt:
++ atomic_dec(THERM_REFCNT(sl->family_data));
+ error:
+ return ret;
+ }
+@@ -1006,7 +1047,7 @@ static ssize_t w1_slave_store(struct dev
+ }
+
+ if (val == 0) /* val=0 : trigger a EEPROM save */
+- ret = SLAVE_SPECIFIC_FUNC(sl)->eeprom(device);
++ ret = copy_scratchpad(sl);
+ else {
+ if (SLAVE_SPECIFIC_FUNC(sl)->set_resolution)
+ ret = SLAVE_SPECIFIC_FUNC(sl)->set_resolution(sl, val);
+@@ -1104,6 +1145,26 @@ static ssize_t resolution_store(struct d
+
+ return size;
+ }
++
++static ssize_t eeprom_store(struct device *device,
++ struct device_attribute *attr, const char *buf, size_t size)
++{
++ struct w1_slave *sl = dev_to_w1_slave(device);
++ int ret = -EINVAL; /* Invalid argument */
++
++ if (size == sizeof(EEPROM_CMD_WRITE)) {
++ if (!strncmp(buf, EEPROM_CMD_WRITE, sizeof(EEPROM_CMD_WRITE)-1))
++ ret = copy_scratchpad(sl);
++ } else if (size == sizeof(EEPROM_CMD_READ)) {
++ if (!strncmp(buf, EEPROM_CMD_READ, sizeof(EEPROM_CMD_READ)-1))
++ ret = recall_eeprom(sl);
++ }
++
++ if (ret)
++ dev_info(device, "%s: error in process %d\n", __func__, ret);
++
++ return size;
++}
+
+ #if IS_REACHABLE(CONFIG_HWMON)
+ static int w1_read_temp(struct device *device, u32 attr, int channel,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0771-w1_therm-optimizing-temperature-read-timings.patch b/target/linux/bcm27xx/patches-5.4/950-0771-w1_therm-optimizing-temperature-read-timings.patch
new file mode 100644
index 0000000000..142560c6da
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0771-w1_therm-optimizing-temperature-read-timings.patch
@@ -0,0 +1,528 @@
+From 23769ad113407ceb21a4285a8194c7d788149269 Mon Sep 17 00:00:00 2001
+From: Akira Shimahara <akira215corp@gmail.com>
+Date: Mon, 11 May 2020 22:37:42 +0200
+Subject: [PATCH] w1_therm: optimizing temperature read timings
+
+commit 67b392f7b8edfa6f427fecd98722acab34c1c99f upstream.
+
+Optimizing temperature reading by reducing waiting conversion time
+according to device resolution settings, as per device specification.
+This is device dependent as not all the devices supports resolution
+setting, so it has been added in device family structures.
+
+The process to read the temperature on the device has been adapted in a
+new function 'convert_t()', which replace the former 'read_therm()', is
+introduce to deal with this timing. Strong pull up is also applied during
+the required time, according to device power status needs and
+'strong_pullup' module parameter.
+
+'temperature_from_RAM()' function is introduced to get the correct
+temperature computation (device dependent) from device RAM data.
+
+An new sysfs entry has been added to ouptut only temperature. The old
+entry w1_slave has been kept for compatibility, without changing its
+output format.
+
+Updating Documentation/ABI/testing/sysfs-driver-w1_therm accordingly.
+
+Signed-off-by: Akira Shimahara <akira215corp@gmail.com>
+Link: https://lore.kernel.org/r/20200511203742.411039-1-akira215corp@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ .../ABI/testing/sysfs-driver-w1_therm | 12 +
+ drivers/w1/slaves/w1_therm.c | 286 +++++++++++-------
+ 2 files changed, 197 insertions(+), 101 deletions(-)
+
+--- a/Documentation/ABI/testing/sysfs-driver-w1_therm
++++ b/Documentation/ABI/testing/sysfs-driver-w1_therm
+@@ -41,6 +41,18 @@ Users: any user space application which
+ w1_term device
+
+
++What: /sys/bus/w1/devices/.../temperature
++Date: May 2020
++Contact: Akira Shimahara <akira215corp@gmail.com>
++Description:
++ (RO) return the temperature in 1/1000 degC.
++ Note that the conversion duration depend on the resolution (if
++ device support this feature). It takes 94ms in 9bits
++ resolution, 750ms for 12bits.
++Users: any user space application which wants to communicate with
++ w1_term device
++
++
+ What: /sys/bus/w1/devices/.../w1_slave
+ Date: May 2020
+ Contact: Akira Shimahara <akira215corp@gmail.com>
+--- a/drivers/w1/slaves/w1_therm.c
++++ b/drivers/w1/slaves/w1_therm.c
+@@ -93,6 +93,7 @@ module_param_named(strong_pullup, w1_str
+ * @reserved: not used here
+ * @f: pointer to the device binding structure
+ * @convert: pointer to the device conversion function
++ * @get_conversion_time: pointer to the device conversion time function
+ * @set_resolution: pointer to the device set_resolution function
+ * @get_resolution: pointer to the device get_resolution function
+ */
+@@ -101,6 +102,7 @@ struct w1_therm_family_converter {
+ u16 reserved;
+ struct w1_family *f;
+ int (*convert)(u8 rom[9]);
++ int (*get_conversion_time)(struct w1_slave *sl);
+ int (*set_resolution)(struct w1_slave *sl, int val);
+ int (*get_resolution)(struct w1_slave *sl);
+ };
+@@ -154,6 +156,15 @@ struct therm_info {
+ static int reset_select_slave(struct w1_slave *sl);
+
+ /**
++ * convert_t() - Query the device for temperature conversion and read
++ * @sl: pointer to the slave to read
++ * @info: pointer to a structure to store the read results
++ *
++ * Return: 0 if success, -kernel error code otherwise
++ */
++static int convert_t(struct w1_slave *sl, struct therm_info *info);
++
++/**
+ * read_scratchpad() - read the data in device RAM
+ * @sl: pointer to the slave to read
+ * @info: pointer to a structure to store the read results
+@@ -213,6 +224,9 @@ static ssize_t w1_slave_store(struct dev
+ static ssize_t w1_seq_show(struct device *device,
+ struct device_attribute *attr, char *buf);
+
++static ssize_t temperature_show(struct device *device,
++ struct device_attribute *attr, char *buf);
++
+ static ssize_t ext_power_show(struct device *device,
+ struct device_attribute *attr, char *buf);
+
+@@ -229,6 +243,7 @@ static ssize_t eeprom_store(struct devic
+
+ static DEVICE_ATTR_RW(w1_slave);
+ static DEVICE_ATTR_RO(w1_seq);
++static DEVICE_ATTR_RO(temperature);
+ static DEVICE_ATTR_RO(ext_power);
+ static DEVICE_ATTR_RW(resolution);
+ static DEVICE_ATTR_WO(eeprom);
+@@ -259,6 +274,7 @@ static void w1_therm_remove_slave(struct
+
+ static struct attribute *w1_therm_attrs[] = {
+ &dev_attr_w1_slave.attr,
++ &dev_attr_temperature.attr,
+ &dev_attr_ext_power.attr,
+ &dev_attr_resolution.attr,
+ &dev_attr_eeprom.attr,
+@@ -267,6 +283,7 @@ static struct attribute *w1_therm_attrs[
+
+ static struct attribute *w1_ds18s20_attrs[] = {
+ &dev_attr_w1_slave.attr,
++ &dev_attr_temperature.attr,
+ &dev_attr_ext_power.attr,
+ &dev_attr_eeprom.attr,
+ NULL,
+@@ -275,6 +292,7 @@ static struct attribute *w1_ds18s20_attr
+ static struct attribute *w1_ds28ea00_attrs[] = {
+ &dev_attr_w1_slave.attr,
+ &dev_attr_w1_seq.attr,
++ &dev_attr_temperature.attr,
+ &dev_attr_ext_power.attr,
+ &dev_attr_resolution.attr,
+ &dev_attr_eeprom.attr,
+@@ -389,6 +407,37 @@ static struct w1_family w1_therm_family_
+
+ /* Device dependent func */
+
++static inline int w1_DS18B20_convert_time(struct w1_slave *sl)
++{
++ int ret;
++
++ if (!sl->family_data)
++ return -ENODEV; /* device unknown */
++
++ /* return time in ms for conversion operation */
++ switch (SLAVE_RESOLUTION(sl)) {
++ case 9:
++ ret = 95;
++ break;
++ case 10:
++ ret = 190;
++ break;
++ case 11:
++ ret = 375;
++ break;
++ case 12:
++ default:
++ ret = 750;
++ }
++ return ret;
++}
++
++static inline int w1_DS18S20_convert_time(struct w1_slave *sl)
++{
++ (void)(sl);
++ return 750; /* always 750ms for DS18S20 */
++}
++
+ static inline int w1_DS18B20_write_data(struct w1_slave *sl,
+ const u8 *data)
+ {
+@@ -480,8 +529,10 @@ static inline int w1_DS18S20_convert_tem
+ {
+ int t, h;
+
+- if (!rom[7])
++ if (!rom[7]) {
++ pr_debug("%s: Invalid argument for conversion\n", __func__);
+ return 0;
++ }
+
+ if (rom[1] == 0)
+ t = ((s32)rom[0] >> 1)*1000;
+@@ -500,34 +551,39 @@ static inline int w1_DS18S20_convert_tem
+
+ static struct w1_therm_family_converter w1_therm_families[] = {
+ {
+- .f = &w1_therm_family_DS18S20,
+- .convert = w1_DS18S20_convert_temp,
+- .set_resolution = NULL, /* no config register */
+- .get_resolution = NULL, /* no config register */
++ .f = &w1_therm_family_DS18S20,
++ .convert = w1_DS18S20_convert_temp,
++ .get_conversion_time = w1_DS18S20_convert_time,
++ .set_resolution = NULL, /* no config register */
++ .get_resolution = NULL, /* no config register */
+ },
+ {
+- .f = &w1_therm_family_DS1822,
+- .convert = w1_DS18B20_convert_temp,
+- .set_resolution = w1_DS18B20_set_resolution,
+- .get_resolution = w1_DS18B20_get_resolution,
++ .f = &w1_therm_family_DS1822,
++ .convert = w1_DS18B20_convert_temp,
++ .get_conversion_time = w1_DS18B20_convert_time,
++ .set_resolution = w1_DS18B20_set_resolution,
++ .get_resolution = w1_DS18B20_get_resolution,
+ },
+ {
+- .f = &w1_therm_family_DS18B20,
+- .convert = w1_DS18B20_convert_temp,
+- .set_resolution = w1_DS18B20_set_resolution,
+- .get_resolution = w1_DS18B20_get_resolution,
++ .f = &w1_therm_family_DS18B20,
++ .convert = w1_DS18B20_convert_temp,
++ .get_conversion_time = w1_DS18B20_convert_time,
++ .set_resolution = w1_DS18B20_set_resolution,
++ .get_resolution = w1_DS18B20_get_resolution,
+ },
+ {
+- .f = &w1_therm_family_DS28EA00,
+- .convert = w1_DS18B20_convert_temp,
+- .set_resolution = w1_DS18B20_set_resolution,
+- .get_resolution = w1_DS18B20_get_resolution,
++ .f = &w1_therm_family_DS28EA00,
++ .convert = w1_DS18B20_convert_temp,
++ .get_conversion_time = w1_DS18B20_convert_time,
++ .set_resolution = w1_DS18B20_set_resolution,
++ .get_resolution = w1_DS18B20_get_resolution,
+ },
+ {
+- .f = &w1_therm_family_DS1825,
+- .convert = w1_DS18B20_convert_temp,
+- .set_resolution = w1_DS18B20_set_resolution,
+- .get_resolution = w1_DS18B20_get_resolution,
++ .f = &w1_therm_family_DS1825,
++ .convert = w1_DS18B20_convert_temp,
++ .get_conversion_time = w1_DS18B20_convert_time,
++ .set_resolution = w1_DS18B20_set_resolution,
++ .get_resolution = w1_DS18B20_get_resolution,
+ }
+ };
+
+@@ -582,24 +638,44 @@ static inline bool bus_mutex_lock(struct
+ }
+
+ /**
+- * w1_convert_temp() - temperature conversion binding function
+- * @rom: data read from device RAM (8 data bytes + 1 CRC byte)
+- * @fid: device family id
++ * conversion_time() - get the Tconv for the slave
++ * @sl: device to get the conversion time
+ *
+- * The function call the temperature computation function according to
+- * device family.
++ * On device supporting resolution settings, conversion time depend
++ * on the resolution setting. This helper function get the slave timing,
++ * depending on its current setting.
+ *
+- * Return: value in millidegrees Celsius.
++ * Return: conversion time in ms, negative values are kernel error code
+ */
+-static inline int w1_convert_temp(u8 rom[9], u8 fid)
++static inline int conversion_time(struct w1_slave *sl)
+ {
+- int i;
++ if (SLAVE_SPECIFIC_FUNC(sl))
++ return SLAVE_SPECIFIC_FUNC(sl)->get_conversion_time(sl);
+
+- for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i)
+- if (w1_therm_families[i].f->fid == fid)
+- return w1_therm_families[i].convert(rom);
++ dev_info(&sl->dev,
++ "%s: Device not supported by the driver\n", __func__);
+
+- return 0;
++ return -ENODEV; /* No device family */
++}
++
++/**
++ * temperature_from_RAM() - Convert the read info to temperature
++ * @sl: device that sent the RAM data
++ * @rom: read value on the slave device RAM
++ *
++ * Device dependent, the function bind the correct computation method.
++ *
++ * Return: temperature in 1/1000degC, 0 on error.
++ */
++static inline int temperature_from_RAM(struct w1_slave *sl, u8 rom[9])
++{
++ if (SLAVE_SPECIFIC_FUNC(sl))
++ return SLAVE_SPECIFIC_FUNC(sl)->convert(rom);
++
++ dev_info(&sl->dev,
++ "%s: Device not supported by the driver\n", __func__);
++
++ return 0; /* No device family */
+ }
+
+ /* Interface Functions */
+@@ -679,96 +755,74 @@ static int reset_select_slave(struct w1_
+ return 0;
+ }
+
+-static ssize_t read_therm(struct device *device,
+- struct w1_slave *sl, struct therm_info *info)
++static int convert_t(struct w1_slave *sl, struct therm_info *info)
+ {
+- struct w1_master *dev = sl->master;
+- u8 external_power;
+- int ret, max_trying = 10;
+- u8 *family_data = sl->family_data;
++ struct w1_master *dev_master = sl->master;
++ int max_trying = W1_THERM_MAX_TRY;
++ int t_conv;
++ int ret = -ENODEV;
++ bool strong_pullup;
+
+- if (!family_data) {
+- ret = -ENODEV;
++ if (!sl->family_data)
+ goto error;
+- }
+
+- /* prevent the slave from going away in sleep */
+- atomic_inc(THERM_REFCNT(family_data));
++ strong_pullup = (w1_strong_pullup == 2 ||
++ (!SLAVE_POWERMODE(sl) &&
++ w1_strong_pullup));
+
+- ret = mutex_lock_interruptible(&dev->bus_mutex);
+- if (ret != 0)
+- goto dec_refcnt;
++ /* get conversion duration device and id dependent */
++ t_conv = conversion_time(sl);
+
+ memset(info->rom, 0, sizeof(info->rom));
+
+- while (max_trying--) {
++ /* prevent the slave from going away in sleep */
++ atomic_inc(THERM_REFCNT(sl->family_data));
++
++ if (!bus_mutex_lock(&dev_master->bus_mutex)) {
++ ret = -EAGAIN; /* Didn't acquire the mutex */
++ goto dec_refcnt;
++ }
++
++ while (max_trying-- && ret) { /* ret should be 0 */
+
+ info->verdict = 0;
+ info->crc = 0;
+-
++ /* safe version to select slave */
+ if (!reset_select_slave(sl)) {
+- int count = 0;
+- unsigned int tm = 750;
+ unsigned long sleep_rem;
+
+- w1_write_8(dev, W1_READ_PSUPPLY);
+- external_power = w1_read_8(dev);
+-
+- if (reset_select_slave(sl))
+- continue;
+-
+ /* 750ms strong pullup (or delay) after the convert */
+- if (w1_strong_pullup == 2 ||
+- (!external_power && w1_strong_pullup))
+- w1_next_pullup(dev, tm);
+-
+- w1_write_8(dev, W1_CONVERT_TEMP);
++ if (strong_pullup)
++ w1_next_pullup(dev_master, t_conv);
+
+- if (external_power) {
+- mutex_unlock(&dev->bus_mutex);
++ w1_write_8(dev_master, W1_CONVERT_TEMP);
+
+- sleep_rem = msleep_interruptible(tm);
++ if (strong_pullup) { /*some device need pullup */
++ sleep_rem = msleep_interruptible(t_conv);
+ if (sleep_rem != 0) {
+ ret = -EINTR;
+- goto dec_refcnt;
++ goto mt_unlock;
+ }
++ mutex_unlock(&dev_master->bus_mutex);
++ } else { /*no device need pullup */
++ mutex_unlock(&dev_master->bus_mutex);
+
+- ret = mutex_lock_interruptible(&dev->bus_mutex);
+- if (ret != 0)
+- goto dec_refcnt;
+- } else if (!w1_strong_pullup) {
+- sleep_rem = msleep_interruptible(tm);
++ sleep_rem = msleep_interruptible(t_conv);
+ if (sleep_rem != 0) {
+ ret = -EINTR;
+- goto mt_unlock;
++ goto dec_refcnt;
+ }
+ }
+-
+- if (!reset_select_slave(sl)) {
+-
+- w1_write_8(dev, W1_READ_SCRATCHPAD);
+- count = w1_read_block(dev, info->rom, 9);
+- if (count != 9) {
+- dev_warn(device, "w1_read_block() "
+- "returned %u instead of 9.\n",
+- count);
+- }
+-
+- info->crc = w1_calc_crc8(info->rom, 8);
+-
+- if (info->rom[8] == info->crc)
+- info->verdict = 1;
+- }
++ ret = read_scratchpad(sl, info);
++ goto dec_refcnt;
+ }
+
+- if (info->verdict)
+- break;
+ }
+
+ mt_unlock:
+- mutex_unlock(&dev->bus_mutex);
++ mutex_unlock(&dev_master->bus_mutex);
+ dec_refcnt:
+- atomic_dec(THERM_REFCNT(family_data));
++ atomic_dec(THERM_REFCNT(sl->family_data));
+ error:
+ return ret;
+ }
+@@ -1000,27 +1054,33 @@ static ssize_t w1_slave_show(struct devi
+ u8 *family_data = sl->family_data;
+ int ret, i;
+ ssize_t c = PAGE_SIZE;
+- u8 fid = sl->family->fid;
+
+- ret = read_therm(device, sl, &info);
+- if (ret)
+- return ret;
++ ret = convert_t(sl, &info);
++
++ if (ret < 0) {
++ dev_dbg(device,
++ "%s: Temperature data may be corrupted. err=%d\n",
++ __func__, ret);
++ return 0;
++ }
+
+ for (i = 0; i < 9; ++i)
+ c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", info.rom[i]);
+ c -= snprintf(buf + PAGE_SIZE - c, c, ": crc=%02x %s\n",
+ info.crc, (info.verdict) ? "YES" : "NO");
++
+ if (info.verdict)
+ memcpy(family_data, info.rom, sizeof(info.rom));
+ else
+- dev_warn(device, "Read failed CRC check\n");
++ dev_warn(device, "%s:Read failed CRC check\n", __func__);
+
+ for (i = 0; i < 9; ++i)
+ c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ",
+ ((u8 *)family_data)[i]);
+
+ c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n",
+- w1_convert_temp(info.rom, fid));
++ temperature_from_RAM(sl, info.rom));
++
+ ret = PAGE_SIZE - c;
+ return ret;
+ }
+@@ -1063,6 +1123,31 @@ static ssize_t w1_slave_store(struct dev
+ return size; /* always return size to avoid infinite calling */
+ }
+
++static ssize_t temperature_show(struct device *device,
++ struct device_attribute *attr, char *buf)
++{
++ struct w1_slave *sl = dev_to_w1_slave(device);
++ struct therm_info info;
++ int ret = 0;
++
++ if ((!sl->family_data) || (!SLAVE_SPECIFIC_FUNC(sl))) {
++ dev_info(device,
++ "%s: Device not supported by the driver\n", __func__);
++ return 0; /* No device family */
++ }
++
++ ret = convert_t(sl, &info);
++
++ if (ret < 0) {
++ dev_dbg(device,
++ "%s: Temperature data may be corrupted. err=%d\n",
++ __func__, ret);
++ return 0;
++ }
++
++ return sprintf(buf, "%d\n", temperature_from_RAM(sl, info.rom));
++}
++
+ static ssize_t ext_power_show(struct device *device,
+ struct device_attribute *attr, char *buf)
+ {
+@@ -1172,12 +1257,11 @@ static int w1_read_temp(struct device *d
+ {
+ struct w1_slave *sl = dev_get_drvdata(device);
+ struct therm_info info;
+- u8 fid = sl->family->fid;
+ int ret;
+
+ switch (attr) {
+ case hwmon_temp_input:
+- ret = read_therm(device, sl, &info);
++ ret = convert_t(sl, &info);
+ if (ret)
+ return ret;
+
+@@ -1186,7 +1270,7 @@ static int w1_read_temp(struct device *d
+ return ret;
+ }
+
+- *val = w1_convert_temp(info.rom, fid);
++ *val = temperature_from_RAM(sl, info.rom);
+ ret = 0;
+ break;
+ default:
diff --git a/target/linux/bcm27xx/patches-5.4/950-0772-w1_therm-adding-alarm-sysfs-entry.patch b/target/linux/bcm27xx/patches-5.4/950-0772-w1_therm-adding-alarm-sysfs-entry.patch
new file mode 100644
index 0000000000..f4b8d5d1d6
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0772-w1_therm-adding-alarm-sysfs-entry.patch
@@ -0,0 +1,319 @@
+From 8c3d9356c3c3b9c9188f1e192c7e2541e313c7ab Mon Sep 17 00:00:00 2001
+From: Akira Shimahara <akira215corp@gmail.com>
+Date: Mon, 11 May 2020 22:38:01 +0200
+Subject: [PATCH] w1_therm: adding alarm sysfs entry
+
+commit e2c94d6f572079511945e64537eb1218643f2e68 upstream.
+
+Adding device alarms settings by a dedicated sysfs entry alarms (RW):
+read or write TH and TL in the device RAM. Checking devices in alarm
+state could be performed using the master search command.
+
+As alarms temperature level are store in a 8 bit register on the device
+and are signed values, a safe cast shall be performed using the min and
+max temperature that device are able to measure. This is done by
+int_to_short inline function.
+
+A 'write_data' field is added in the device structure, to bind the
+correct writing function, as some devices may have 2 or 3 bytes RAM.
+
+Updating Documentation/ABI/testing/sysfs-driver-w1_therm accordingly.
+
+Signed-off-by: Akira Shimahara <akira215corp@gmail.com>
+Link: https://lore.kernel.org/r/20200511203801.411253-1-akira215corp@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ .../ABI/testing/sysfs-driver-w1_therm | 16 ++
+ drivers/w1/slaves/w1_therm.c | 161 ++++++++++++++++++
+ 2 files changed, 177 insertions(+)
+
+--- a/Documentation/ABI/testing/sysfs-driver-w1_therm
++++ b/Documentation/ABI/testing/sysfs-driver-w1_therm
+@@ -1,3 +1,19 @@
++What: /sys/bus/w1/devices/.../alarms
++Date: May 2020
++Contact: Akira Shimahara <akira215corp@gmail.com>
++Description:
++ (RW) read or write TH and TL (Temperature High an Low) alarms.
++ Values shall be space separated and in the device range
++ (typical -55 degC to 125 degC), if not values will be trimmed
++ to device min/max capabilities. Values are integer as they are
++ stored in a 8bit register in the device. Lowest value is
++ automatically put to TL. Once set, alarms could be search at
++ master level, refer to Documentation/w1/w1_generic.rst for
++ detailed information
++Users: any user space application which wants to communicate with
++ w1_term device
++
++
+ What: /sys/bus/w1/devices/.../eeprom
+ Date: May 2020
+ Contact: Akira Shimahara <akira215corp@gmail.com>
+--- a/drivers/w1/slaves/w1_therm.c
++++ b/drivers/w1/slaves/w1_therm.c
+@@ -58,6 +58,9 @@ module_param_named(strong_pullup, w1_str
+ #define EEPROM_CMD_WRITE "save" /* cmd for write eeprom sysfs */
+ #define EEPROM_CMD_READ "restore" /* cmd for read eeprom sysfs */
+
++#define MIN_TEMP -55 /* min temperature that can be mesured */
++#define MAX_TEMP 125 /* max temperature that can be mesured */
++
+ /* Helpers Macros */
+
+ /*
+@@ -96,6 +99,7 @@ module_param_named(strong_pullup, w1_str
+ * @get_conversion_time: pointer to the device conversion time function
+ * @set_resolution: pointer to the device set_resolution function
+ * @get_resolution: pointer to the device get_resolution function
++ * @write_data: pointer to the device writing function (2 or 3 bytes)
+ */
+ struct w1_therm_family_converter {
+ u8 broken;
+@@ -105,6 +109,7 @@ struct w1_therm_family_converter {
+ int (*get_conversion_time)(struct w1_slave *sl);
+ int (*set_resolution)(struct w1_slave *sl, int val);
+ int (*get_resolution)(struct w1_slave *sl);
++ int (*write_data)(struct w1_slave *sl, const u8 *data);
+ };
+
+ /**
+@@ -239,6 +244,12 @@ static ssize_t resolution_store(struct d
+ static ssize_t eeprom_store(struct device *device,
+ struct device_attribute *attr, const char *buf, size_t size);
+
++static ssize_t alarms_store(struct device *device,
++ struct device_attribute *attr, const char *buf, size_t size);
++
++static ssize_t alarms_show(struct device *device,
++ struct device_attribute *attr, char *buf);
++
+ /* Attributes declarations */
+
+ static DEVICE_ATTR_RW(w1_slave);
+@@ -247,6 +258,7 @@ static DEVICE_ATTR_RO(temperature);
+ static DEVICE_ATTR_RO(ext_power);
+ static DEVICE_ATTR_RW(resolution);
+ static DEVICE_ATTR_WO(eeprom);
++static DEVICE_ATTR_RW(alarms);
+
+ /* Interface Functions declaration */
+
+@@ -278,6 +290,7 @@ static struct attribute *w1_therm_attrs[
+ &dev_attr_ext_power.attr,
+ &dev_attr_resolution.attr,
+ &dev_attr_eeprom.attr,
++ &dev_attr_alarms.attr,
+ NULL,
+ };
+
+@@ -286,6 +299,7 @@ static struct attribute *w1_ds18s20_attr
+ &dev_attr_temperature.attr,
+ &dev_attr_ext_power.attr,
+ &dev_attr_eeprom.attr,
++ &dev_attr_alarms.attr,
+ NULL,
+ };
+
+@@ -296,6 +310,7 @@ static struct attribute *w1_ds28ea00_att
+ &dev_attr_ext_power.attr,
+ &dev_attr_resolution.attr,
+ &dev_attr_eeprom.attr,
++ &dev_attr_alarms.attr,
+ NULL,
+ };
+
+@@ -556,6 +571,7 @@ static struct w1_therm_family_converter
+ .get_conversion_time = w1_DS18S20_convert_time,
+ .set_resolution = NULL, /* no config register */
+ .get_resolution = NULL, /* no config register */
++ .write_data = w1_DS18S20_write_data,
+ },
+ {
+ .f = &w1_therm_family_DS1822,
+@@ -563,6 +579,7 @@ static struct w1_therm_family_converter
+ .get_conversion_time = w1_DS18B20_convert_time,
+ .set_resolution = w1_DS18B20_set_resolution,
+ .get_resolution = w1_DS18B20_get_resolution,
++ .write_data = w1_DS18B20_write_data,
+ },
+ {
+ .f = &w1_therm_family_DS18B20,
+@@ -570,6 +587,7 @@ static struct w1_therm_family_converter
+ .get_conversion_time = w1_DS18B20_convert_time,
+ .set_resolution = w1_DS18B20_set_resolution,
+ .get_resolution = w1_DS18B20_get_resolution,
++ .write_data = w1_DS18B20_write_data,
+ },
+ {
+ .f = &w1_therm_family_DS28EA00,
+@@ -577,6 +595,7 @@ static struct w1_therm_family_converter
+ .get_conversion_time = w1_DS18B20_convert_time,
+ .set_resolution = w1_DS18B20_set_resolution,
+ .get_resolution = w1_DS18B20_get_resolution,
++ .write_data = w1_DS18B20_write_data,
+ },
+ {
+ .f = &w1_therm_family_DS1825,
+@@ -584,6 +603,7 @@ static struct w1_therm_family_converter
+ .get_conversion_time = w1_DS18B20_convert_time,
+ .set_resolution = w1_DS18B20_set_resolution,
+ .get_resolution = w1_DS18B20_get_resolution,
++ .write_data = w1_DS18B20_write_data,
+ }
+ };
+
+@@ -678,6 +698,26 @@ static inline int temperature_from_RAM(s
+ return 0; /* No device family */
+ }
+
++/**
++ * int_to_short() - Safe casting of int to short
++ *
++ * @i: integer to be converted to short
++ *
++ * Device register use 1 byte to store signed integer.
++ * This helper function convert the int in a signed short,
++ * using the min/max values that device can measure as limits.
++ * min/max values are defined by macro.
++ *
++ * Return: a short in the range of min/max value
++ */
++static inline s8 int_to_short(int i)
++{
++ /* Prepare to cast to short by eliminating out of range values */
++ i = i > MAX_TEMP ? MAX_TEMP : i;
++ i = i < MIN_TEMP ? MIN_TEMP : i;
++ return (s8) i;
++}
++
+ /* Interface Functions */
+
+ static int w1_therm_add_slave(struct w1_slave *sl)
+@@ -1250,6 +1290,127 @@ static ssize_t eeprom_store(struct devic
+
+ return size;
+ }
++
++static ssize_t alarms_show(struct device *device,
++ struct device_attribute *attr, char *buf)
++{
++ struct w1_slave *sl = dev_to_w1_slave(device);
++ int ret = -ENODEV;
++ s8 th = 0, tl = 0;
++ struct therm_info scratchpad;
++
++ ret = read_scratchpad(sl, &scratchpad);
++
++ if (!ret) {
++ th = scratchpad.rom[2]; /* TH is byte 2 */
++ tl = scratchpad.rom[3]; /* TL is byte 3 */
++ } else {
++ dev_info(device,
++ "%s: error reading alarms register %d\n",
++ __func__, ret);
++ }
++
++ return sprintf(buf, "%hd %hd\n", tl, th);
++}
++
++static ssize_t alarms_store(struct device *device,
++ struct device_attribute *attr, const char *buf, size_t size)
++{
++ struct w1_slave *sl = dev_to_w1_slave(device);
++ struct therm_info info;
++ u8 new_config_register[3]; /* array of data to be written */
++ int temp, ret = -EINVAL;
++ char *token = NULL;
++ s8 tl, th, tt; /* 1 byte per value + temp ring order */
++ char *p_args = kmalloc(size, GFP_KERNEL);
++
++ /* Safe string copys as buf is const */
++ if (!p_args) {
++ dev_warn(device,
++ "%s: error unable to allocate memory %d\n",
++ __func__, -ENOMEM);
++ return size;
++ }
++ strcpy(p_args, buf);
++
++ /* Split string using space char */
++ token = strsep(&p_args, " ");
++
++ if (!token) {
++ dev_info(device,
++ "%s: error parsing args %d\n", __func__, -EINVAL);
++ goto free_m;
++ }
++
++ /* Convert 1st entry to int */
++ ret = kstrtoint (token, 10, &temp);
++ if (ret) {
++ dev_info(device,
++ "%s: error parsing args %d\n", __func__, ret);
++ goto free_m;
++ }
++
++ tl = int_to_short(temp);
++
++ /* Split string using space char */
++ token = strsep(&p_args, " ");
++ if (!token) {
++ dev_info(device,
++ "%s: error parsing args %d\n", __func__, -EINVAL);
++ goto free_m;
++ }
++ /* Convert 2nd entry to int */
++ ret = kstrtoint (token, 10, &temp);
++ if (ret) {
++ dev_info(device,
++ "%s: error parsing args %d\n", __func__, ret);
++ goto free_m;
++ }
++
++ /* Prepare to cast to short by eliminating out of range values */
++ th = int_to_short(temp);
++
++ /* Reorder if required th and tl */
++ if (tl > th) {
++ tt = tl; tl = th; th = tt;
++ }
++
++ /*
++ * Read the scratchpad to change only the required bits
++ * (th : byte 2 - tl: byte 3)
++ */
++ ret = read_scratchpad(sl, &info);
++ if (!ret) {
++ new_config_register[0] = th; /* Byte 2 */
++ new_config_register[1] = tl; /* Byte 3 */
++ new_config_register[2] = info.rom[4];/* Byte 4 */
++ } else {
++ dev_info(device,
++ "%s: error reading from the slave device %d\n",
++ __func__, ret);
++ goto free_m;
++ }
++
++ /* Write data in the device RAM */
++ if (!SLAVE_SPECIFIC_FUNC(sl)) {
++ dev_info(device,
++ "%s: Device not supported by the driver %d\n",
++ __func__, -ENODEV);
++ goto free_m;
++ }
++
++ ret = SLAVE_SPECIFIC_FUNC(sl)->write_data(sl, new_config_register);
++ if (ret)
++ dev_info(device,
++ "%s: error writing to the slave device %d\n",
++ __func__, ret);
++
++free_m:
++ /* free allocated memory */
++ kfree(p_args);
++
++ return size;
++}
+
+ #if IS_REACHABLE(CONFIG_HWMON)
+ static int w1_read_temp(struct device *device, u32 attr, int channel,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0773-w1_therm-adding-bulk-read-support-to-trigger-multipl.patch b/target/linux/bcm27xx/patches-5.4/950-0773-w1_therm-adding-bulk-read-support-to-trigger-multipl.patch
new file mode 100644
index 0000000000..ad641e1e98
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0773-w1_therm-adding-bulk-read-support-to-trigger-multipl.patch
@@ -0,0 +1,587 @@
+From e6585a1d299375740f95f30027b8b3f4b34e7548 Mon Sep 17 00:00:00 2001
+From: Akira Shimahara <akira215corp@gmail.com>
+Date: Mon, 11 May 2020 22:38:20 +0200
+Subject: [PATCH] w1_therm: adding bulk read support to trigger
+ multiple conversion on bus
+
+commit 57c76221d5af648c8355a55c09b050c5d8d38189 upstream.
+
+Adding bulk read support:
+Sending a 'trigger' command in the dedicated sysfs entry of bus master
+device send a conversion command for all the slaves on the bus. The sysfs
+entry is added as soon as at least one device supporting this feature
+is detected on the bus.
+
+The behavior of the sysfs reading temperature on the device is as follow:
+ * If no bulk read pending, trigger a conversion on the device, wait for
+ the conversion to be done, read the temperature in device RAM
+ * If a bulk read has been trigger, access directly the device RAM
+This behavior is the same on the 2 sysfs entries ('temperature' and
+'w1_slave').
+
+Reading the therm_bulk_read sysfs give the status of bulk operations:
+ * '-1': conversion in progress on at least 1 sensor
+ * '1': conversion complete but at least one sensor has not been read yet
+ * '0': no bulk operation. Reading temperature on ecah device will trigger
+a conversion
+
+As not all devices support bulk read feature, it has been added in device
+family structure.
+
+The attribute is set at master level as soon as a supporting device is
+discover. It is removed when the last supported device leave the bus.
+The count of supported device is kept with the static counter
+bulk_read_device_counter.
+
+A strong pull up is apply on the line if at least one device required it.
+The duration of the pull up is the max time required by a device on the
+line, which depends on the resolution settings of each device. The strong
+pull up could be adjust with the a module parameter.
+
+Updating documentation in Documentation/ABI/testing/sysfs-driver-w1_therm
+and Documentation/w1/slaves/w1_therm.rst accordingly.
+
+Signed-off-by: Akira Shimahara <akira215corp@gmail.com>
+Link: https://lore.kernel.org/r/20200511203820.411483-1-akira215corp@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ .../ABI/testing/sysfs-driver-w1_therm | 36 ++-
+ Documentation/w1/slaves/w1_therm.rst | 50 +++-
+ drivers/w1/slaves/w1_therm.c | 251 +++++++++++++++++-
+ 3 files changed, 322 insertions(+), 15 deletions(-)
+
+--- a/Documentation/ABI/testing/sysfs-driver-w1_therm
++++ b/Documentation/ABI/testing/sysfs-driver-w1_therm
+@@ -62,9 +62,16 @@ Date: May 2020
+ Contact: Akira Shimahara <akira215corp@gmail.com>
+ Description:
+ (RO) return the temperature in 1/1000 degC.
+- Note that the conversion duration depend on the resolution (if
+- device support this feature). It takes 94ms in 9bits
+- resolution, 750ms for 12bits.
++ * If a bulk read has been triggered, it will directly
++ return the temperature computed when the bulk read
++ occurred, if available. If not yet available, nothing
++ is returned (a debug kernel message is sent), you
++ should retry later on.
++ * If no bulk read has been triggered, it will trigger
++ a conversion and send the result. Note that the
++ conversion duration depend on the resolution (if
++ device support this feature). It takes 94ms in 9bits
++ resolution, 750ms for 12bits.
+ Users: any user space application which wants to communicate with
+ w1_term device
+
+@@ -85,4 +92,25 @@ Description:
+ refer to Documentation/w1/slaves/w1_therm.rst for detailed
+ information.
+ Users: any user space application which wants to communicate with
+- w1_term device
+\ No newline at end of file
++ w1_term device
++
++
++What: /sys/bus/w1/devices/w1_bus_masterXX/therm_bulk_read
++Date: May 2020
++Contact: Akira Shimahara <akira215corp@gmail.com>
++Description:
++ (RW) trigger a bulk read conversion. read the status
++ *read*:
++ * '-1': conversion in progress on at least 1 sensor
++ * '1' : conversion complete but at least one sensor
++ value has not been read yet
++ * '0' : no bulk operation. Reading temperature will
++ trigger a conversion on each device
++ *write*: 'trigger': trigger a bulk read on all supporting
++ devices on the bus
++ Note that if a bulk read is sent but one sensor is not read
++ immediately, the next access to temperature on this device
++ will return the temperature measured at the time of issue
++ of the bulk read command (not the current temperature).
++Users: any user space application which wants to communicate with
++ w1_term device
+--- a/Documentation/w1/slaves/w1_therm.rst
++++ b/Documentation/w1/slaves/w1_therm.rst
+@@ -26,20 +26,31 @@ W1_THERM_DS1825 0x3B
+ W1_THERM_DS28EA00 0x42
+ ==================== ====
+
+-Support is provided through the sysfs w1_slave file. Each open and
++Support is provided through the sysfs w1_slave file. Each open and
+ read sequence will initiate a temperature conversion then provide two
+-lines of ASCII output. The first line contains the nine hex bytes
++lines of ASCII output. The first line contains the nine hex bytes
+ read along with a calculated crc value and YES or NO if it matched.
+-If the crc matched the returned values are retained. The second line
++If the crc matched the returned values are retained. The second line
+ displays the retained values along with a temperature in millidegrees
+ Centigrade after t=.
+
+-Parasite powered devices are limited to one slave performing a
+-temperature conversion at a time. If none of the devices are parasite
+-powered it would be possible to convert all the devices at the same
+-time and then go back to read individual sensors. That isn't
+-currently supported. The driver also doesn't support reduced
+-precision (which would also reduce the conversion time) when reading values.
++Alternatively, temperature can be read using temperature sysfs, it
++return only temperature in millidegrees Centigrade.
++
++A bulk read of all devices on the bus could be done writing 'trigger'
++in the therm_bulk_read sysfs entry at w1_bus_master level. This will
++sent the convert command on all devices on the bus, and if parasite
++powered devices are detected on the bus (and strong pullup is enable
++in the module), it will drive the line high during the longer conversion
++time required by parasited powered device on the line. Reading
++therm_bulk_read will return 0 if no bulk conversion pending,
++-1 if at least one sensor still in conversion, 1 if conversion is complete
++but at least one sensor value has not been read yet. Result temperature is
++then accessed by reading the temperature sysfs entry of each device, which
++may return empty if conversion is still in progress. Note that if a bulk
++read is sent but one sensor is not read immediately, the next access to
++temperature on this device will return the temperature measured at the
++time of issue of the bulk read command (not the current temperature).
+
+ Writing a value between 9 and 12 to the sysfs w1_slave file will change the
+ precision of the sensor for the next readings. This value is in (volatile)
+@@ -49,6 +60,27 @@ To store the current precision configura
+ has to be written to the sysfs w1_slave file. Since the EEPROM has a limited
+ amount of writes (>50k), this command should be used wisely.
+
++Alternatively, resolution can be set or read (value from 9 to 12) using the
++dedicated resolution sysfs entry on each device. This sysfs entry is not
++present for devices not supporting this feature. Driver will adjust the
++correct conversion time for each device regarding to its resolution setting.
++In particular, strong pullup will be applied if required during the conversion
++duration.
++
++The write-only sysfs entry eeprom is an alternative for EEPROM operations:
++ * 'save': will save device RAM to EEPROM
++ * 'restore': will restore EEPROM data in device RAM.
++
++ext_power syfs entry allow tho check the power status of each device.
++ * '0': device parasite powered
++ * '1': device externally powered
++
++sysfs alarms allow read or write TH and TL (Temperature High an Low) alarms.
++Values shall be space separated and in the device range (typical -55 degC
++to 125 degC). Values are integer as they are store in a 8bit register in
++the device. Lowest value is automatically put to TL.Once set, alarms could
++be search at master level.
++
+ The module parameter strong_pullup can be set to 0 to disable the
+ strong pullup, 1 to enable autodetection or 2 to force strong pullup.
+ In case of autodetection, the driver will use the "READ POWER SUPPLY"
+--- a/drivers/w1/slaves/w1_therm.c
++++ b/drivers/w1/slaves/w1_therm.c
+@@ -43,6 +43,9 @@
+ static int w1_strong_pullup = 1;
+ module_param_named(strong_pullup, w1_strong_pullup, int, 0);
+
++/* Counter for devices supporting bulk reading */
++static u16 bulk_read_device_counter; /* =0 as per C standard */
++
+ /* This command should be in public header w1.h but is not */
+ #define W1_RECALL_EEPROM 0xB8
+
+@@ -57,6 +60,7 @@ module_param_named(strong_pullup, w1_str
+
+ #define EEPROM_CMD_WRITE "save" /* cmd for write eeprom sysfs */
+ #define EEPROM_CMD_READ "restore" /* cmd for read eeprom sysfs */
++#define BULK_TRIGGER_CMD "trigger" /* cmd to trigger a bulk read */
+
+ #define MIN_TEMP -55 /* min temperature that can be mesured */
+ #define MAX_TEMP 125 /* max temperature that can be mesured */
+@@ -84,6 +88,15 @@ module_param_named(strong_pullup, w1_str
+ #define SLAVE_RESOLUTION(sl) \
+ (((struct w1_therm_family_data *)(sl->family_data))->resolution)
+
++/*
++ * return whether or not a converT command has been issued to the slave
++ * * 0: no bulk read is pending
++ * * -1: conversion is in progress
++ * * 1: conversion done, result to be read
++ */
++#define SLAVE_CONVERT_TRIGGERED(sl) \
++ (((struct w1_therm_family_data *)(sl->family_data))->convert_triggered)
++
+ /* return the address of the refcnt in the family data */
+ #define THERM_REFCNT(family_data) \
+ (&((struct w1_therm_family_data *)family_data)->refcnt)
+@@ -100,6 +113,7 @@ module_param_named(strong_pullup, w1_str
+ * @set_resolution: pointer to the device set_resolution function
+ * @get_resolution: pointer to the device get_resolution function
+ * @write_data: pointer to the device writing function (2 or 3 bytes)
++ * @bulk_read: true if device family support bulk read, false otherwise
+ */
+ struct w1_therm_family_converter {
+ u8 broken;
+@@ -110,6 +124,7 @@ struct w1_therm_family_converter {
+ int (*set_resolution)(struct w1_slave *sl, int val);
+ int (*get_resolution)(struct w1_slave *sl);
+ int (*write_data)(struct w1_slave *sl, const u8 *data);
++ bool bulk_read;
+ };
+
+ /**
+@@ -120,6 +135,7 @@ struct w1_therm_family_converter {
+ * 0 device parasite powered,
+ * -x error or undefined
+ * @resolution: current device resolution
++ * @convert_triggered: conversion state of the device
+ * @specific_functions: pointer to struct of device specific function
+ */
+ struct w1_therm_family_data {
+@@ -127,6 +143,7 @@ struct w1_therm_family_data {
+ atomic_t refcnt;
+ int external_powered;
+ int resolution;
++ int convert_triggered;
+ struct w1_therm_family_converter *specific_functions;
+ };
+
+@@ -218,6 +235,18 @@ static int recall_eeprom(struct w1_slave
+ */
+ static int read_powermode(struct w1_slave *sl);
+
++/**
++ * trigger_bulk_read() - function to trigger a bulk read on the bus
++ * @dev_master: the device master of the bus
++ *
++ * Send a SKIP ROM follow by a CONVERT T commmand on the bus.
++ * It also set the status flag in each slave &struct w1_therm_family_data
++ * to signal that a conversion is in progress.
++ *
++ * Return: 0 if success, -kernel error code otherwise
++ */
++static int trigger_bulk_read(struct w1_master *dev_master);
++
+ /* Sysfs interface declaration */
+
+ static ssize_t w1_slave_show(struct device *device,
+@@ -250,6 +279,12 @@ static ssize_t alarms_store(struct devic
+ static ssize_t alarms_show(struct device *device,
+ struct device_attribute *attr, char *buf);
+
++static ssize_t therm_bulk_read_store(struct device *device,
++ struct device_attribute *attr, const char *buf, size_t size);
++
++static ssize_t therm_bulk_read_show(struct device *device,
++ struct device_attribute *attr, char *buf);
++
+ /* Attributes declarations */
+
+ static DEVICE_ATTR_RW(w1_slave);
+@@ -260,6 +295,8 @@ static DEVICE_ATTR_RW(resolution);
+ static DEVICE_ATTR_WO(eeprom);
+ static DEVICE_ATTR_RW(alarms);
+
++static DEVICE_ATTR_RW(therm_bulk_read); /* attribut at master level */
++
+ /* Interface Functions declaration */
+
+ /**
+@@ -572,6 +609,7 @@ static struct w1_therm_family_converter
+ .set_resolution = NULL, /* no config register */
+ .get_resolution = NULL, /* no config register */
+ .write_data = w1_DS18S20_write_data,
++ .bulk_read = true
+ },
+ {
+ .f = &w1_therm_family_DS1822,
+@@ -580,6 +618,7 @@ static struct w1_therm_family_converter
+ .set_resolution = w1_DS18B20_set_resolution,
+ .get_resolution = w1_DS18B20_get_resolution,
+ .write_data = w1_DS18B20_write_data,
++ .bulk_read = true
+ },
+ {
+ .f = &w1_therm_family_DS18B20,
+@@ -588,6 +627,7 @@ static struct w1_therm_family_converter
+ .set_resolution = w1_DS18B20_set_resolution,
+ .get_resolution = w1_DS18B20_get_resolution,
+ .write_data = w1_DS18B20_write_data,
++ .bulk_read = true
+ },
+ {
+ .f = &w1_therm_family_DS28EA00,
+@@ -596,6 +636,7 @@ static struct w1_therm_family_converter
+ .set_resolution = w1_DS18B20_set_resolution,
+ .get_resolution = w1_DS18B20_get_resolution,
+ .write_data = w1_DS18B20_write_data,
++ .bulk_read = false
+ },
+ {
+ .f = &w1_therm_family_DS1825,
+@@ -604,6 +645,7 @@ static struct w1_therm_family_converter
+ .set_resolution = w1_DS18B20_set_resolution,
+ .get_resolution = w1_DS18B20_get_resolution,
+ .write_data = w1_DS18B20_write_data,
++ .bulk_read = true
+ }
+ };
+
+@@ -658,6 +700,23 @@ static inline bool bus_mutex_lock(struct
+ }
+
+ /**
++ * support_bulk_read() - check if slave support bulk read
++ * @sl: device to check the ability
++ *
++ * Return: true if bulk read is supported, false if not or error
++ */
++static inline bool bulk_read_support(struct w1_slave *sl)
++{
++ if (SLAVE_SPECIFIC_FUNC(sl))
++ return SLAVE_SPECIFIC_FUNC(sl)->bulk_read;
++
++ dev_info(&sl->dev,
++ "%s: Device not supported by the driver\n", __func__);
++
++ return false; /* No device family */
++}
++
++/**
+ * conversion_time() - get the Tconv for the slave
+ * @sl: device to get the conversion time
+ *
+@@ -741,6 +800,24 @@ static int w1_therm_add_slave(struct w1_
+ /* save this pointer to the device structure */
+ SLAVE_SPECIFIC_FUNC(sl) = sl_family_conv;
+
++ if (bulk_read_support(sl)) {
++ /*
++ * add the sys entry to trigger bulk_read
++ * at master level only the 1st time
++ */
++ if (!bulk_read_device_counter) {
++ int err = device_create_file(&sl->master->dev,
++ &dev_attr_therm_bulk_read);
++
++ if (err)
++ dev_warn(&sl->dev,
++ "%s: Device has been added, but bulk read is unavailable. err=%d\n",
++ __func__, err);
++ }
++ /* Increment the counter */
++ bulk_read_device_counter++;
++ }
++
+ /* Getting the power mode of the device {external, parasite} */
+ SLAVE_POWERMODE(sl) = read_powermode(sl);
+
+@@ -763,6 +840,9 @@ static int w1_therm_add_slave(struct w1_
+ }
+ }
+
++ /* Finally initialize convert_triggered flag */
++ SLAVE_CONVERT_TRIGGERED(sl) = 0;
++
+ return 0;
+ }
+
+@@ -770,6 +850,14 @@ static void w1_therm_remove_slave(struct
+ {
+ int refcnt = atomic_sub_return(1, THERM_REFCNT(sl->family_data));
+
++ if (bulk_read_support(sl)) {
++ bulk_read_device_counter--;
++ /* Delete the entry if no more device support the feature */
++ if (!bulk_read_device_counter)
++ device_remove_file(&sl->master->dev,
++ &dev_attr_therm_bulk_read);
++ }
++
+ while (refcnt) {
+ msleep(1000);
+ refcnt = atomic_read(THERM_REFCNT(sl->family_data));
+@@ -1084,6 +1172,96 @@ error:
+ return ret;
+ }
+
++static int trigger_bulk_read(struct w1_master *dev_master)
++{
++ struct w1_slave *sl = NULL; /* used to iterate through slaves */
++ int max_trying = W1_THERM_MAX_TRY;
++ int t_conv = 0;
++ int ret = -ENODEV;
++ bool strong_pullup = false;
++
++ /*
++ * Check whether there are parasite powered device on the bus,
++ * and compute duration of conversion for these devices
++ * so we can apply a strong pullup if required
++ */
++ list_for_each_entry(sl, &dev_master->slist, w1_slave_entry) {
++ if (!sl->family_data)
++ goto error;
++ if (bulk_read_support(sl)) {
++ int t_cur = conversion_time(sl);
++
++ t_conv = t_cur > t_conv ? t_cur : t_conv;
++ strong_pullup = strong_pullup ||
++ (w1_strong_pullup == 2 ||
++ (!SLAVE_POWERMODE(sl) &&
++ w1_strong_pullup));
++ }
++ }
++
++ /*
++ * t_conv is the max conversion time required on the bus
++ * If its 0, no device support the bulk read feature
++ */
++ if (!t_conv)
++ goto error;
++
++ if (!bus_mutex_lock(&dev_master->bus_mutex)) {
++ ret = -EAGAIN; /* Didn't acquire the mutex */
++ goto error;
++ }
++
++ while ((max_trying--) && (ret < 0)) { /* ret should be either 0 */
++
++ if (!w1_reset_bus(dev_master)) { /* Just reset the bus */
++ unsigned long sleep_rem;
++
++ w1_write_8(dev_master, W1_SKIP_ROM);
++
++ if (strong_pullup) /* Apply pullup if required */
++ w1_next_pullup(dev_master, t_conv);
++
++ w1_write_8(dev_master, W1_CONVERT_TEMP);
++
++ /* set a flag to instruct that converT pending */
++ list_for_each_entry(sl,
++ &dev_master->slist, w1_slave_entry) {
++ if (bulk_read_support(sl))
++ SLAVE_CONVERT_TRIGGERED(sl) = -1;
++ }
++
++ if (strong_pullup) { /* some device need pullup */
++ sleep_rem = msleep_interruptible(t_conv);
++ if (sleep_rem != 0) {
++ ret = -EINTR;
++ goto mt_unlock;
++ }
++ mutex_unlock(&dev_master->bus_mutex);
++ } else {
++ mutex_unlock(&dev_master->bus_mutex);
++ sleep_rem = msleep_interruptible(t_conv);
++ if (sleep_rem != 0) {
++ ret = -EINTR;
++ goto set_flag;
++ }
++ }
++ ret = 0;
++ goto set_flag;
++ }
++ }
++
++mt_unlock:
++ mutex_unlock(&dev_master->bus_mutex);
++set_flag:
++ /* set a flag to register convsersion is done */
++ list_for_each_entry(sl, &dev_master->slist, w1_slave_entry) {
++ if (bulk_read_support(sl))
++ SLAVE_CONVERT_TRIGGERED(sl) = 1;
++ }
++error:
++ return ret;
++}
++
+ /* Sysfs Interface definition */
+
+ static ssize_t w1_slave_show(struct device *device,
+@@ -1095,7 +1273,20 @@ static ssize_t w1_slave_show(struct devi
+ int ret, i;
+ ssize_t c = PAGE_SIZE;
+
+- ret = convert_t(sl, &info);
++ if (bulk_read_support(sl)) {
++ if (SLAVE_CONVERT_TRIGGERED(sl) < 0) {
++ dev_dbg(device,
++ "%s: Conversion in progress, retry later\n",
++ __func__);
++ return 0;
++ } else if (SLAVE_CONVERT_TRIGGERED(sl) > 0) {
++ /* A bulk read has been issued, read the device RAM */
++ ret = read_scratchpad(sl, &info);
++ SLAVE_CONVERT_TRIGGERED(sl) = 0;
++ } else
++ ret = convert_t(sl, &info);
++ } else
++ ret = convert_t(sl, &info);
+
+ if (ret < 0) {
+ dev_dbg(device,
+@@ -1176,7 +1367,20 @@ static ssize_t temperature_show(struct d
+ return 0; /* No device family */
+ }
+
+- ret = convert_t(sl, &info);
++ if (bulk_read_support(sl)) {
++ if (SLAVE_CONVERT_TRIGGERED(sl) < 0) {
++ dev_dbg(device,
++ "%s: Conversion in progress, retry later\n",
++ __func__);
++ return 0;
++ } else if (SLAVE_CONVERT_TRIGGERED(sl) > 0) {
++ /* A bulk read has been issued, read the device RAM */
++ ret = read_scratchpad(sl, &info);
++ SLAVE_CONVERT_TRIGGERED(sl) = 0;
++ } else
++ ret = convert_t(sl, &info);
++ } else
++ ret = convert_t(sl, &info);
+
+ if (ret < 0) {
+ dev_dbg(device,
+@@ -1412,6 +1616,49 @@ free_m:
+ return size;
+ }
+
++static ssize_t therm_bulk_read_store(struct device *device,
++ struct device_attribute *attr, const char *buf, size_t size)
++{
++ struct w1_master *dev_master = dev_to_w1_master(device);
++ int ret = -EINVAL; /* Invalid argument */
++
++ if (size == sizeof(BULK_TRIGGER_CMD))
++ if (!strncmp(buf, BULK_TRIGGER_CMD,
++ sizeof(BULK_TRIGGER_CMD)-1))
++ ret = trigger_bulk_read(dev_master);
++
++ if (ret)
++ dev_info(device,
++ "%s: unable to trigger a bulk read on the bus. err=%d\n",
++ __func__, ret);
++
++ return size;
++}
++
++static ssize_t therm_bulk_read_show(struct device *device,
++ struct device_attribute *attr, char *buf)
++{
++ struct w1_master *dev_master = dev_to_w1_master(device);
++ struct w1_slave *sl = NULL;
++ int ret = 0;
++
++ list_for_each_entry(sl, &dev_master->slist, w1_slave_entry) {
++ if (sl->family_data) {
++ if (bulk_read_support(sl)) {
++ if (SLAVE_CONVERT_TRIGGERED(sl) == -1) {
++ ret = -1;
++ goto show_result;
++ }
++ if (SLAVE_CONVERT_TRIGGERED(sl) == 1)
++ /* continue to check other slaves */
++ ret = 1;
++ }
++ }
++ }
++show_result:
++ return sprintf(buf, "%d\n", ret);
++}
++
+ #if IS_REACHABLE(CONFIG_HWMON)
+ static int w1_read_temp(struct device *device, u32 attr, int channel,
+ long *val)
diff --git a/target/linux/bcm27xx/patches-5.4/950-0774-w1_therm-Free-the-correct-variable.patch b/target/linux/bcm27xx/patches-5.4/950-0774-w1_therm-Free-the-correct-variable.patch
new file mode 100644
index 0000000000..fede4120ba
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0774-w1_therm-Free-the-correct-variable.patch
@@ -0,0 +1,41 @@
+From 039babe99fda6eb04a77ca29cacf98efd1a5f406 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 20 May 2020 15:00:19 +0300
+Subject: [PATCH] w1_therm: Free the correct variable
+
+commit e420637b81f78d0fbacf539bdb1b341eba602aea upstream.
+
+The problem is that we change "p_args" to point to the middle of the
+string so when we free it at the end of the function it's not freeing
+the same pointer that we originally allocated.
+
+Fixes: e2c94d6f5720 ("w1_therm: adding alarm sysfs entry")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Link: https://lore.kernel.org/r/20200520120019.GA172354@mwanda
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/w1/slaves/w1_therm.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/w1/slaves/w1_therm.c
++++ b/drivers/w1/slaves/w1_therm.c
+@@ -1526,8 +1526,9 @@ static ssize_t alarms_store(struct devic
+ int temp, ret = -EINVAL;
+ char *token = NULL;
+ s8 tl, th, tt; /* 1 byte per value + temp ring order */
+- char *p_args = kmalloc(size, GFP_KERNEL);
++ char *p_args, *orig;
+
++ p_args = orig = kmalloc(size, GFP_KERNEL);
+ /* Safe string copys as buf is const */
+ if (!p_args) {
+ dev_warn(device,
+@@ -1611,7 +1612,7 @@ static ssize_t alarms_store(struct devic
+
+ free_m:
+ /* free allocated memory */
+- kfree(p_args);
++ kfree(orig);
+
+ return size;
+ }
diff --git a/target/linux/bcm27xx/patches-5.4/950-0775-w1_therm-remove-redundant-assignments-to-variable-re.patch b/target/linux/bcm27xx/patches-5.4/950-0775-w1_therm-remove-redundant-assignments-to-variable-re.patch
new file mode 100644
index 0000000000..73bc9d5402
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0775-w1_therm-remove-redundant-assignments-to-variable-re.patch
@@ -0,0 +1,58 @@
+From 7566655c9e659e890f44784a6403de98ad77ae5b Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Tue, 19 May 2020 16:45:53 +0100
+Subject: [PATCH] w1_therm: remove redundant assignments to variable
+ ret
+
+commit f37d13d52c0560bd2bac40b22466af538e61a5ce upstream.
+
+The variable ret is being initialized with a value that is never read
+and it is being updated later with a new value. The initialization
+is redundant and can be removed.
+
+Addresses-Coverity: ("Unused value")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Link: https://lore.kernel.org/r/20200519154553.873413-1-colin.king@canonical.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/w1/slaves/w1_therm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/w1/slaves/w1_therm.c
++++ b/drivers/w1/slaves/w1_therm.c
+@@ -505,7 +505,7 @@ static inline int w1_DS18S20_write_data(
+
+ static inline int w1_DS18B20_set_resolution(struct w1_slave *sl, int val)
+ {
+- int ret = -ENODEV;
++ int ret;
+ u8 new_config_register[3]; /* array of data to be written */
+ struct therm_info info;
+
+@@ -538,7 +538,7 @@ static inline int w1_DS18B20_set_resolut
+
+ static inline int w1_DS18B20_get_resolution(struct w1_slave *sl)
+ {
+- int ret = -ENODEV;
++ int ret;
+ u8 config_register;
+ struct therm_info info;
+
+@@ -1499,7 +1499,7 @@ static ssize_t alarms_show(struct device
+ struct device_attribute *attr, char *buf)
+ {
+ struct w1_slave *sl = dev_to_w1_slave(device);
+- int ret = -ENODEV;
++ int ret;
+ s8 th = 0, tl = 0;
+ struct therm_info scratchpad;
+
+@@ -1523,7 +1523,7 @@ static ssize_t alarms_store(struct devic
+ struct w1_slave *sl = dev_to_w1_slave(device);
+ struct therm_info info;
+ u8 new_config_register[3]; /* array of data to be written */
+- int temp, ret = -EINVAL;
++ int temp, ret;
+ char *token = NULL;
+ s8 tl, th, tt; /* 1 byte per value + temp ring order */
+ char *p_args, *orig;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0776-PCI-brcmstb-Assert-fundamental-reset-on-initializati.patch b/target/linux/bcm27xx/patches-5.4/950-0776-PCI-brcmstb-Assert-fundamental-reset-on-initializati.patch
new file mode 100644
index 0000000000..2692bed050
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0776-PCI-brcmstb-Assert-fundamental-reset-on-initializati.patch
@@ -0,0 +1,33 @@
+From d9317f90391167ebc275696d9df3c21ce754d609 Mon Sep 17 00:00:00 2001
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Thu, 7 May 2020 19:20:20 +0200
+Subject: [PATCH] PCI: brcmstb: Assert fundamental reset on
+ initialization
+
+commit 22e21e51ce755399fd42055a3f668ee4af370881 upstream.
+
+While preparing the driver for upstream this detail was missed.
+
+If not asserted during the initialization process, devices connected on
+the bus will not be made aware of the internal reset happening. This,
+potentially resulting in unexpected behavior.
+
+Link: https://lore.kernel.org/r/20200507172020.18000-1-nsaenzjulienne@suse.de
+Fixes: c0452137034b ("PCI: brcmstb: Add Broadcom STB PCIe host controller driver")
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+---
+ drivers/pci/controller/pcie-brcmstb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/pci/controller/pcie-brcmstb.c
++++ b/drivers/pci/controller/pcie-brcmstb.c
+@@ -697,6 +697,7 @@ static int brcm_pcie_setup(struct brcm_p
+
+ /* Reset the bridge */
+ brcm_pcie_bridge_sw_init_set(pcie, 1);
++ brcm_pcie_perst_set(pcie, 1);
+
+ usleep_range(100, 200);
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0777-clk-rpi-Adjust-DT-binding-to-match-upstream.patch b/target/linux/bcm27xx/patches-5.4/950-0777-clk-rpi-Adjust-DT-binding-to-match-upstream.patch
new file mode 100644
index 0000000000..35278708e9
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0777-clk-rpi-Adjust-DT-binding-to-match-upstream.patch
@@ -0,0 +1,189 @@
+From d8daf6289869513ed548bcb0da410d7de3e5d57a Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 10 Jun 2020 16:28:56 +0200
+Subject: [PATCH] clk: rpi: Adjust DT binding to match upstream
+
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+---
+ arch/arm/boot/dts/bcm270x.dtsi | 6 ------
+ arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 5 +++++
+ arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 5 +++++
+ arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 5 +++++
+ arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 5 +++++
+ arch/arm/boot/dts/bcm2711.dtsi | 6 ------
+ arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts | 5 +++++
+ arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 5 +++++
+ arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 5 +++++
+ arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi | 5 +++++
+ drivers/clk/bcm/clk-raspberrypi.c | 12 +++++++++++-
+ 11 files changed, 51 insertions(+), 13 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm270x.dtsi
++++ b/arch/arm/boot/dts/bcm270x.dtsi
+@@ -7,12 +7,6 @@
+ /delete-property/ stdout-path;
+ };
+
+- firmware_clocks: firmware-clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- raspberrypi,firmware = <&firmware>;
+- #clock-cells = <1>;
+- };
+-
+ soc: soc {
+
+ watchdog: watchdog@7e100000 {
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts
+@@ -85,6 +85,11 @@
+ };
+
+ &firmware {
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <1>;
++ };
++
+ expgpio: expgpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
+@@ -96,6 +96,11 @@
+ };
+
+ &firmware {
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <1>;
++ };
++
+ expgpio: expgpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts
+@@ -58,6 +58,11 @@
+ };
+
+ &firmware {
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <1>;
++ };
++
+ expgpio: expgpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+@@ -54,6 +54,11 @@
+ };
+
+ &firmware {
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <1>;
++ };
++
+ expgpio: gpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/arch/arm/boot/dts/bcm2711.dtsi
++++ b/arch/arm/boot/dts/bcm2711.dtsi
+@@ -24,12 +24,6 @@
+ clock-output-names = "108MHz-clock";
+ };
+
+- firmware_clocks: firmware-clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- raspberrypi,firmware = <&firmware>;
+- #clock-cells = <1>;
+- };
+-
+ soc {
+ /*
+ * Defined ranges:
+--- a/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
++++ b/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
+@@ -31,6 +31,11 @@
+ };
+
+ &firmware {
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <1>;
++ };
++
+ expgpio: gpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
++++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
+@@ -37,6 +37,11 @@
+ };
+
+ &firmware {
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <1>;
++ };
++
+ expgpio: gpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
++++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
+@@ -32,6 +32,11 @@
+ };
+
+ &firmware {
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <1>;
++ };
++
+ expgpio: gpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
++++ b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
+@@ -35,6 +35,11 @@
+ };
+
+ &firmware {
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <1>;
++ };
++
+ expgpio: gpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/drivers/clk/bcm/clk-raspberrypi.c
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -383,13 +383,23 @@ static int raspberrypi_clk_probe(struct
+ struct raspberrypi_clk *rpi;
+ int ret;
+
+- firmware_node = of_parse_phandle(dev->of_node, "raspberrypi,firmware", 0);
++ /*
++ * We can be probed either through the an old-fashioned
++ * platform device registration or through a DT node that is a
++ * child of the firmware node. Handle both cases.
++ */
++ if (dev->of_node)
++ firmware_node = of_get_parent(dev->of_node);
++ else
++ firmware_node = of_find_compatible_node(NULL, NULL,
++ "raspberrypi,bcm2835-firmware");
+ if (!firmware_node) {
+ dev_err(dev, "Missing firmware node\n");
+ return -ENOENT;
+ }
+
+ firmware = rpi_firmware_get(firmware_node);
++ of_node_put(firmware_node);
+ if (!firmware)
+ return -EPROBE_DEFER;
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0778-clk-bcm-rpi-Add-an-enum-for-the-firmware-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0778-clk-bcm-rpi-Add-an-enum-for-the-firmware-clocks.patch
new file mode 100644
index 0000000000..c69b5685d4
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0778-clk-bcm-rpi-Add-an-enum-for-the-firmware-clocks.patch
@@ -0,0 +1,80 @@
+From d9b492679a107e535cfd39ee00bd2ce6f12089e0 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Tue, 26 May 2020 14:23:04 +0200
+Subject: [PATCH] clk: bcm: rpi: Add an enum for the firmware clocks
+
+While the firmware allows us to discover the available clocks, we need to
+discriminate those clocks to only register the ones meaningful to Linux.
+The firmware also doesn't provide a clock name, so having a list of the ID
+will help us to give clocks a proper name later on.
+
+Acked-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+---
+ drivers/clk/bcm/clk-raspberrypi.c | 30 ++++++++++++++++++++++++------
+ 1 file changed, 24 insertions(+), 6 deletions(-)
+
+--- a/drivers/clk/bcm/clk-raspberrypi.c
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -18,7 +18,23 @@
+
+ #include <soc/bcm2835/raspberrypi-firmware.h>
+
+-#define RPI_FIRMWARE_ARM_CLK_ID 0x00000003
++enum rpi_firmware_clk_id {
++ RPI_FIRMWARE_EMMC_CLK_ID = 1,
++ RPI_FIRMWARE_UART_CLK_ID,
++ RPI_FIRMWARE_ARM_CLK_ID,
++ RPI_FIRMWARE_CORE_CLK_ID,
++ RPI_FIRMWARE_V3D_CLK_ID,
++ RPI_FIRMWARE_H264_CLK_ID,
++ RPI_FIRMWARE_ISP_CLK_ID,
++ RPI_FIRMWARE_SDRAM_CLK_ID,
++ RPI_FIRMWARE_PIXEL_CLK_ID,
++ RPI_FIRMWARE_PWM_CLK_ID,
++ RPI_FIRMWARE_HEVC_CLK_ID,
++ RPI_FIRMWARE_EMMC2_CLK_ID,
++ RPI_FIRMWARE_M2MC_CLK_ID,
++ RPI_FIRMWARE_PIXEL_BVB_CLK_ID,
++ RPI_FIRMWARE_NUM_CLK_ID,
++};
+
+ #define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0)
+ #define RPI_FIRMWARE_STATE_WAIT_BIT BIT(1)
+@@ -31,8 +47,6 @@
+
+ #define A2W_PLL_FRAC_BITS 20
+
+-#define NUM_FW_CLKS 16
+-
+ struct raspberrypi_clk {
+ struct device *dev;
+ struct rpi_firmware *firmware;
+@@ -350,12 +364,15 @@ static int raspberrypi_discover_clocks(s
+ struct rpi_firmware_get_clocks_response *clks;
+ int ret;
+
+- clks = devm_kcalloc(rpi->dev, sizeof(*clks), NUM_FW_CLKS, GFP_KERNEL);
++ clks = devm_kcalloc(rpi->dev,
++ sizeof(*clks), RPI_FIRMWARE_NUM_CLK_ID,
++ GFP_KERNEL);
+ if (!clks)
+ return -ENOMEM;
+
+ ret = rpi_firmware_property(rpi->firmware, RPI_FIRMWARE_GET_CLOCKS,
+- clks, sizeof(*clks) * NUM_FW_CLKS);
++ clks,
++ sizeof(*clks) * RPI_FIRMWARE_NUM_CLK_ID);
+ if (ret)
+ return ret;
+
+@@ -411,7 +428,8 @@ static int raspberrypi_clk_probe(struct
+ rpi->firmware = firmware;
+ platform_set_drvdata(pdev, rpi);
+
+- clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, NUM_FW_CLKS),
++ clk_data = devm_kzalloc(dev, struct_size(clk_data, hws,
++ RPI_FIRMWARE_NUM_CLK_ID),
+ GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0779-clk-bcm-rpi-Use-CCF-boundaries-instead-of-rolling-ou.patch b/target/linux/bcm27xx/patches-5.4/950-0779-clk-bcm-rpi-Use-CCF-boundaries-instead-of-rolling-ou.patch
new file mode 100644
index 0000000000..22f1aa6742
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0779-clk-bcm-rpi-Use-CCF-boundaries-instead-of-rolling-ou.patch
@@ -0,0 +1,134 @@
+From cd72d75cfb216a7ef15ec8649e57b03b4fc48b62 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 27 May 2020 11:13:52 +0200
+Subject: [PATCH] clk: bcm: rpi: Use CCF boundaries instead of
+ rolling our own
+
+The raspberrypi firmware clock driver has a min_rate / max_rate clamping by
+storing the info it needs in a private structure.
+
+However, the CCF already provides such a facility, so we can switch to it
+to remove the boilerplate.
+
+Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+---
+ drivers/clk/bcm/clk-raspberrypi.c | 49 ++++++++++++++++++++-----------
+ 1 file changed, 32 insertions(+), 17 deletions(-)
+
+--- a/drivers/clk/bcm/clk-raspberrypi.c
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -57,9 +57,6 @@ struct raspberrypi_clk_data {
+ struct clk_hw hw;
+ unsigned id;
+
+- unsigned long min_rate;
+- unsigned long max_rate;
+-
+ struct raspberrypi_clk *rpi;
+ };
+
+@@ -177,13 +174,11 @@ static int raspberrypi_fw_pll_set_rate(s
+ static int raspberrypi_pll_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+ {
+- struct raspberrypi_clk_data *data =
+- container_of(hw, struct raspberrypi_clk_data, hw);
+ u64 div, final_rate;
+ u32 ndiv, fdiv;
+
+ /* We can't use req->rate directly as it would overflow */
+- final_rate = clamp(req->rate, data->min_rate, data->max_rate);
++ final_rate = clamp(req->rate, req->min_rate, req->max_rate);
+
+ div = (u64)final_rate << A2W_PLL_FRAC_BITS;
+ do_div(div, req->best_parent_rate);
+@@ -254,16 +249,15 @@ static struct clk_hw *raspberrypi_regist
+ dev_info(rpi->dev, "CPU frequency range: min %u, max %u\n",
+ min_rate, max_rate);
+
+- data->min_rate = min_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
+- data->max_rate = max_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
+-
+ data->hw.init = &init;
+
+ ret = devm_clk_hw_register(rpi->dev, &data->hw);
+- if (ret)
+- return ERR_PTR(ret);
++ if (!ret)
++ clk_hw_set_rate_range(&data->hw,
++ min_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE,
++ max_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE);
+
+- return &data->hw;
++ return ret;
+ }
+
+ static struct clk_fixed_factor raspberrypi_clk_pllb_arm = {
+@@ -299,22 +293,22 @@ static struct clk_hw *raspberrypi_regist
+ return &raspberrypi_clk_pllb_arm.hw;
+ }
+
+-static long raspberrypi_fw_dumb_round_rate(struct clk_hw *hw,
+- unsigned long rate,
+- unsigned long *parent_rate)
++static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw,
++ struct clk_rate_request *req)
+ {
+ /*
+ * The firmware will do the rounding but that isn't part of
+ * the interface with the firmware, so we just do our best
+ * here.
+ */
+- return rate;
++ req->rate = clamp(req->rate, req->min_rate, req->max_rate);
++ return 0;
+ }
+
+ static const struct clk_ops raspberrypi_firmware_clk_ops = {
+ .is_prepared = raspberrypi_fw_is_prepared,
+ .recalc_rate = raspberrypi_fw_get_rate,
+- .round_rate = raspberrypi_fw_dumb_round_rate,
++ .determine_rate = raspberrypi_fw_dumb_determine_rate,
+ .set_rate = raspberrypi_fw_set_rate,
+ };
+
+@@ -324,6 +318,7 @@ static struct clk_hw *raspberrypi_clk_re
+ {
+ struct raspberrypi_clk_data *data;
+ struct clk_init_data init = {};
++ u32 min_rate, max_rate;
+ int ret;
+
+ if (id == RPI_FIRMWARE_ARM_CLK_ID) {
+@@ -351,10 +346,30 @@ static struct clk_hw *raspberrypi_clk_re
+
+ data->hw.init = &init;
+
++ ret = raspberrypi_clock_property(rpi->firmware, data,
++ RPI_FIRMWARE_GET_MIN_CLOCK_RATE,
++ &min_rate);
++ if (ret) {
++ dev_err(rpi->dev, "Failed to get %s min freq: %d\n",
++ init.name, ret);
++ return ERR_PTR(ret);
++ }
++
++ ret = raspberrypi_clock_property(rpi->firmware, data,
++ RPI_FIRMWARE_GET_MAX_CLOCK_RATE,
++ &max_rate);
++ if (ret) {
++ dev_err(rpi->dev, "Failed to get %s max freq: %d\n",
++ init.name, ret);
++ return ERR_PTR(ret);
++ }
++
+ ret = devm_clk_hw_register(rpi->dev, &data->hw);
+ if (ret)
+ return ERR_PTR(ret);
+
++ clk_hw_set_rate_range(&data->hw, min_rate, max_rate);
++
+ return &data->hw;
+ }
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0780-clk-bcm-rpi-Give-firmware-clocks-a-name.patch b/target/linux/bcm27xx/patches-5.4/950-0780-clk-bcm-rpi-Give-firmware-clocks-a-name.patch
new file mode 100644
index 0000000000..745e8588ac
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0780-clk-bcm-rpi-Give-firmware-clocks-a-name.patch
@@ -0,0 +1,52 @@
+From 5f69f49a942cd31e5f8b511e166fb55e3a0df267 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Tue, 26 May 2020 14:30:31 +0200
+Subject: [PATCH] clk: bcm: rpi: Give firmware clocks a name
+
+We've registered the firmware clocks using their ID as name, but it's much
+more convenient to register them using their proper name. Since the
+firmware doesn't provide it, we have to duplicate it.
+
+Acked-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+---
+ drivers/clk/bcm/clk-raspberrypi.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+--- a/drivers/clk/bcm/clk-raspberrypi.c
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -36,6 +36,23 @@ enum rpi_firmware_clk_id {
+ RPI_FIRMWARE_NUM_CLK_ID,
+ };
+
++static char *rpi_firmware_clk_names[] = {
++ [RPI_FIRMWARE_EMMC_CLK_ID] = "emmc",
++ [RPI_FIRMWARE_UART_CLK_ID] = "uart",
++ [RPI_FIRMWARE_ARM_CLK_ID] = "arm",
++ [RPI_FIRMWARE_CORE_CLK_ID] = "core",
++ [RPI_FIRMWARE_V3D_CLK_ID] = "v3d",
++ [RPI_FIRMWARE_H264_CLK_ID] = "h264",
++ [RPI_FIRMWARE_ISP_CLK_ID] = "isp",
++ [RPI_FIRMWARE_SDRAM_CLK_ID] = "sdram",
++ [RPI_FIRMWARE_PIXEL_CLK_ID] = "pixel",
++ [RPI_FIRMWARE_PWM_CLK_ID] = "pwm",
++ [RPI_FIRMWARE_HEVC_CLK_ID] = "hevc",
++ [RPI_FIRMWARE_EMMC2_CLK_ID] = "emmc2",
++ [RPI_FIRMWARE_M2MC_CLK_ID] = "m2mc",
++ [RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = "pixel-bvb",
++};
++
+ #define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0)
+ #define RPI_FIRMWARE_STATE_WAIT_BIT BIT(1)
+
+@@ -340,7 +357,9 @@ static struct clk_hw *raspberrypi_clk_re
+ data->rpi = rpi;
+ data->id = id;
+
+- init.name = devm_kasprintf(rpi->dev, GFP_KERNEL, "fw-clk-%u", id);
++ init.name = devm_kasprintf(rpi->dev, GFP_KERNEL,
++ "fw-clk-%s",
++ rpi_firmware_clk_names[id]);
+ init.ops = &raspberrypi_firmware_clk_ops;
+ init.flags = CLK_GET_RATE_NOCACHE;
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0781-clk-bcm-rpi-Remove-the-quirks-for-the-CPU-clock.patch b/target/linux/bcm27xx/patches-5.4/950-0781-clk-bcm-rpi-Remove-the-quirks-for-the-CPU-clock.patch
new file mode 100644
index 0000000000..0e9bb9c601
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0781-clk-bcm-rpi-Remove-the-quirks-for-the-CPU-clock.patch
@@ -0,0 +1,207 @@
+From 30ae66617ee6f340343c8e75c244e370721ed2eb Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Tue, 26 May 2020 15:27:35 +0200
+Subject: [PATCH] clk: bcm: rpi: Remove the quirks for the CPU clock
+
+The CPU clock has had so far a bunch of quirks to expose the clock tree
+properly, but since we reverted to exposing them through the MMIO driver,
+we can remove that code from the firmware driver.
+
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+---
+ drivers/clk/bcm/clk-raspberrypi.c | 163 ++----------------------------
+ 1 file changed, 9 insertions(+), 154 deletions(-)
+
+--- a/drivers/clk/bcm/clk-raspberrypi.c
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -151,13 +151,6 @@ static unsigned long raspberrypi_fw_get_
+ return val;
+ }
+
+-static unsigned long raspberrypi_fw_pll_get_rate(struct clk_hw *hw,
+- unsigned long parent_rate)
+-{
+- return raspberrypi_fw_get_rate(hw, parent_rate) *
+- RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
+-}
+-
+ static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+ {
+@@ -176,140 +169,6 @@ static int raspberrypi_fw_set_rate(struc
+ return ret;
+ }
+
+-static int raspberrypi_fw_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+- unsigned long parent_rate)
+-{
+- u32 new_rate = rate / RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
+-
+- return raspberrypi_fw_set_rate(hw, new_rate, parent_rate);
+-}
+-
+-/*
+- * Sadly there is no firmware rate rounding interface. We borrowed it from
+- * clk-bcm2835.
+- */
+-static int raspberrypi_pll_determine_rate(struct clk_hw *hw,
+- struct clk_rate_request *req)
+-{
+- u64 div, final_rate;
+- u32 ndiv, fdiv;
+-
+- /* We can't use req->rate directly as it would overflow */
+- final_rate = clamp(req->rate, req->min_rate, req->max_rate);
+-
+- div = (u64)final_rate << A2W_PLL_FRAC_BITS;
+- do_div(div, req->best_parent_rate);
+-
+- ndiv = div >> A2W_PLL_FRAC_BITS;
+- fdiv = div & ((1 << A2W_PLL_FRAC_BITS) - 1);
+-
+- final_rate = ((u64)req->best_parent_rate *
+- ((ndiv << A2W_PLL_FRAC_BITS) + fdiv));
+-
+- req->rate = final_rate >> A2W_PLL_FRAC_BITS;
+-
+- return 0;
+-}
+-
+-static const struct clk_ops raspberrypi_firmware_pll_clk_ops = {
+- .is_prepared = raspberrypi_fw_is_prepared,
+- .recalc_rate = raspberrypi_fw_pll_get_rate,
+- .set_rate = raspberrypi_fw_pll_set_rate,
+- .determine_rate = raspberrypi_pll_determine_rate,
+-};
+-
+-static struct clk_hw *raspberrypi_register_pllb(struct raspberrypi_clk *rpi)
+-{
+- struct raspberrypi_clk_data *data;
+- struct clk_init_data init = {};
+- u32 min_rate = 0, max_rate = 0;
+- int ret;
+-
+- data = devm_kzalloc(rpi->dev, sizeof(*data), GFP_KERNEL);
+- if (!data)
+- return ERR_PTR(-ENOMEM);
+- data->rpi = rpi;
+- data->id = RPI_FIRMWARE_ARM_CLK_ID;
+-
+- /* All of the PLLs derive from the external oscillator. */
+- init.parent_names = (const char *[]){ "osc" };
+- init.num_parents = 1;
+- init.name = "pllb";
+- init.ops = &raspberrypi_firmware_pll_clk_ops;
+- init.flags = CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED;
+-
+- /* Get min & max rates set by the firmware */
+- ret = raspberrypi_clock_property(rpi->firmware, data,
+- RPI_FIRMWARE_GET_MIN_CLOCK_RATE,
+- &min_rate);
+- if (ret) {
+- dev_err(rpi->dev, "Failed to get %s min freq: %d\n",
+- init.name, ret);
+- return ERR_PTR(ret);
+- }
+-
+- ret = raspberrypi_clock_property(rpi->firmware, data,
+- RPI_FIRMWARE_GET_MAX_CLOCK_RATE,
+- &max_rate);
+- if (ret) {
+- dev_err(rpi->dev, "Failed to get %s max freq: %d\n",
+- init.name, ret);
+- return ERR_PTR(ret);
+- }
+-
+- if (!min_rate || !max_rate) {
+- dev_err(rpi->dev, "Unexpected frequency range: min %u, max %u\n",
+- min_rate, max_rate);
+- return ERR_PTR(-EINVAL);
+- }
+-
+- dev_info(rpi->dev, "CPU frequency range: min %u, max %u\n",
+- min_rate, max_rate);
+-
+- data->hw.init = &init;
+-
+- ret = devm_clk_hw_register(rpi->dev, &data->hw);
+- if (!ret)
+- clk_hw_set_rate_range(&data->hw,
+- min_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE,
+- max_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE);
+-
+- return ret;
+-}
+-
+-static struct clk_fixed_factor raspberrypi_clk_pllb_arm = {
+- .mult = 1,
+- .div = 2,
+- .hw.init = &(struct clk_init_data) {
+- .name = "pllb_arm",
+- .parent_names = (const char *[]){ "pllb" },
+- .num_parents = 1,
+- .ops = &clk_fixed_factor_ops,
+- .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+- },
+-};
+-
+-static struct clk_hw *raspberrypi_register_pllb_arm(struct raspberrypi_clk *rpi)
+-{
+- int ret;
+-
+- ret = devm_clk_hw_register(rpi->dev, &raspberrypi_clk_pllb_arm.hw);
+- if (ret) {
+- dev_err(rpi->dev, "Failed to initialize pllb_arm\n");
+- return ERR_PTR(ret);
+- }
+-
+- ret = devm_clk_hw_register_clkdev(rpi->dev,
+- &raspberrypi_clk_pllb_arm.hw,
+- NULL, "cpu0");
+- if (ret) {
+- dev_err(rpi->dev, "Failed to initialize clkdev\n");
+- return ERR_PTR(ret);
+- }
+-
+- return &raspberrypi_clk_pllb_arm.hw;
+-}
+-
+ static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+ {
+@@ -338,19 +197,6 @@ static struct clk_hw *raspberrypi_clk_re
+ u32 min_rate, max_rate;
+ int ret;
+
+- if (id == RPI_FIRMWARE_ARM_CLK_ID) {
+- struct clk_hw *hw;
+-
+- hw = raspberrypi_register_pllb(rpi);
+- if (IS_ERR(hw)) {
+- dev_err(rpi->dev, "Failed to initialize pllb, %ld\n",
+- PTR_ERR(hw));
+- return hw;
+- }
+-
+- return raspberrypi_register_pllb_arm(rpi);
+- }
+-
+ data = devm_kzalloc(rpi->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return ERR_PTR(-ENOMEM);
+@@ -389,6 +235,15 @@ static struct clk_hw *raspberrypi_clk_re
+
+ clk_hw_set_rate_range(&data->hw, min_rate, max_rate);
+
++ if (id == RPI_FIRMWARE_ARM_CLK_ID) {
++ ret = devm_clk_hw_register_clkdev(rpi->dev, &data->hw,
++ NULL, "cpu0");
++ if (ret) {
++ dev_err(rpi->dev, "Failed to initialize clkdev\n");
++ return ERR_PTR(ret);
++ }
++ }
++
+ return &data->hw;
+ }
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0782-clk-rpi-Only-register-a-few-firmware-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0782-clk-rpi-Only-register-a-few-firmware-clocks.patch
new file mode 100644
index 0000000000..580a90c9d3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0782-clk-rpi-Only-register-a-few-firmware-clocks.patch
@@ -0,0 +1,43 @@
+From 73a8443ea82fef7a1f8a466fff83da7863baed49 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 10 Jun 2020 16:18:17 +0200
+Subject: [PATCH] clk: rpi: Only register a few firmware clocks
+
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+---
+ drivers/clk/bcm/clk-raspberrypi.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+--- a/drivers/clk/bcm/clk-raspberrypi.c
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -268,13 +268,24 @@ static int raspberrypi_discover_clocks(s
+ while (clks->id) {
+ struct clk_hw *hw;
+
+- hw = raspberrypi_clk_register(rpi, clks->parent, clks->id);
+- if (IS_ERR(hw))
+- return PTR_ERR(hw);
++ switch (clks->id) {
++ case RPI_FIRMWARE_ARM_CLK_ID:
++ case RPI_FIRMWARE_CORE_CLK_ID:
++ case RPI_FIRMWARE_M2MC_CLK_ID:
++ case RPI_FIRMWARE_V3D_CLK_ID:
++ hw = raspberrypi_clk_register(rpi, clks->parent,
++ clks->id);
++ if (IS_ERR(hw))
++ return PTR_ERR(hw);
+
+- data->hws[clks->id] = hw;
+- data->num = clks->id + 1;
+- clks++;
++ data->hws[clks->id] = hw;
++ data->num = clks->id + 1;
++ fallthrough;
++
++ default:
++ clks++;
++ break;
++ }
+ }
+
+ return 0;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0783-clk-rpi-Fix-compatible-indentation.patch b/target/linux/bcm27xx/patches-5.4/950-0783-clk-rpi-Fix-compatible-indentation.patch
new file mode 100644
index 0000000000..da9d3b8c56
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0783-clk-rpi-Fix-compatible-indentation.patch
@@ -0,0 +1,23 @@
+From 4a1d8af9737868f6494f491e9a1efb0fb348588e Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 10 Jun 2020 16:29:08 +0200
+Subject: [PATCH] clk: rpi: Fix compatible indentation
+
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+---
+ drivers/clk/bcm/clk-raspberrypi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/bcm/clk-raspberrypi.c
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -359,8 +359,8 @@ static int raspberrypi_clk_remove(struct
+ }
+
+ static const struct of_device_id raspberrypi_clk_match[] = {
+- { .compatible = "raspberrypi,firmware-clocks" },
+- { },
++ { .compatible = "raspberrypi,firmware-clocks" },
++ { },
+ };
+ MODULE_DEVICE_TABLE(of, raspberrypi_clk_match);
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0784-SQUASH-dts-Fix-firmware-clocks-support.patch b/target/linux/bcm27xx/patches-5.4/950-0784-SQUASH-dts-Fix-firmware-clocks-support.patch
new file mode 100644
index 0000000000..35c2c4429c
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0784-SQUASH-dts-Fix-firmware-clocks-support.patch
@@ -0,0 +1,176 @@
+From 10f7562d7ce7ea6fe6324df059c865ff660811fc Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 11 Jun 2020 16:34:00 +0100
+Subject: [PATCH] SQUASH: dts: Fix firmware clocks support
+
+Commit [1] touched a lot of files and still missed some platforms.
+In particular, Pi 2 was left with no clock scaling. Simplify the
+firmware clocks DTS support and extend it to all platforms that
+use the raspberrypi-cpufreq driver.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2709-rpi.dtsi | 7 +++++++
+ arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 5 -----
+ arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 5 -----
+ arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 5 -----
+ arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 5 -----
+ arch/arm/boot/dts/bcm2711-rpi.dtsi | 7 +++++++
+ arch/arm/boot/dts/bcm2836-rpi.dtsi | 7 +++++++
+ arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts | 5 -----
+ arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 5 -----
+ arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 5 -----
+ arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi | 5 -----
+ 11 files changed, 21 insertions(+), 40 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2709-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2709-rpi.dtsi
+@@ -3,3 +3,10 @@
+ &vchiq {
+ compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq";
+ };
++
++&firmware {
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <1>;
++ };
++};
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts
+@@ -85,11 +85,6 @@
+ };
+
+ &firmware {
+- firmware_clocks: clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- #clock-cells = <1>;
+- };
+-
+ expgpio: expgpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
+@@ -96,11 +96,6 @@
+ };
+
+ &firmware {
+- firmware_clocks: clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- #clock-cells = <1>;
+- };
+-
+ expgpio: expgpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts
+@@ -58,11 +58,6 @@
+ };
+
+ &firmware {
+- firmware_clocks: clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- #clock-cells = <1>;
+- };
+-
+ expgpio: expgpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+@@ -54,11 +54,6 @@
+ };
+
+ &firmware {
+- firmware_clocks: clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- #clock-cells = <1>;
+- };
+-
+ expgpio: gpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi
+@@ -170,3 +170,10 @@
+ &genet {
+ compatible = "brcm,bcm2711-genet-v5", "brcm,genet-v5";
+ };
++
++&firmware {
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <1>;
++ };
++};
+--- a/arch/arm/boot/dts/bcm2836-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2836-rpi.dtsi
+@@ -4,3 +4,10 @@
+ &vchiq {
+ compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq";
+ };
++
++&firmware {
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <1>;
++ };
++};
+--- a/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
++++ b/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
+@@ -31,11 +31,6 @@
+ };
+
+ &firmware {
+- firmware_clocks: clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- #clock-cells = <1>;
+- };
+-
+ expgpio: gpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
++++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
+@@ -37,11 +37,6 @@
+ };
+
+ &firmware {
+- firmware_clocks: clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- #clock-cells = <1>;
+- };
+-
+ expgpio: gpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
++++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
+@@ -32,11 +32,6 @@
+ };
+
+ &firmware {
+- firmware_clocks: clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- #clock-cells = <1>;
+- };
+-
+ expgpio: gpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+--- a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
++++ b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
+@@ -35,11 +35,6 @@
+ };
+
+ &firmware {
+- firmware_clocks: clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- #clock-cells = <1>;
+- };
+-
+ expgpio: gpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0785-ARM-dts-Add-bcm2711-rpi-cm4.dts.patch b/target/linux/bcm27xx/patches-5.4/950-0785-ARM-dts-Add-bcm2711-rpi-cm4.dts.patch
new file mode 100644
index 0000000000..fa6837b4f0
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0785-ARM-dts-Add-bcm2711-rpi-cm4.dts.patch
@@ -0,0 +1,631 @@
+From 104dcc1aff0ae5509ad9875c11e3e0d8c290709d Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 2 Jun 2020 17:19:51 +0100
+Subject: [PATCH] ARM: dts: Add bcm2711-rpi-cm4.dts
+
+Add initial DTS file for Compute Module 4.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/Makefile | 3 +-
+ arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 586 ++++++++++++++++++++++++++
+ arch/arm/boot/dts/overlays/README | 6 +
+ 3 files changed, 594 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4.dts
+
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -12,7 +12,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
+ bcm2710-rpi-3-b.dtb \
+ bcm2711-rpi-4-b.dtb \
+ bcm2710-rpi-3-b-plus.dtb \
+- bcm2710-rpi-cm3.dtb
++ bcm2710-rpi-cm3.dtb \
++ bcm2711-rpi-cm4.dtb
+
+ dtb-$(CONFIG_ARCH_ALPINE) += \
+ alpine-db.dtb
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
+@@ -0,0 +1,586 @@
++// SPDX-License-Identifier: GPL-2.0
++/dts-v1/;
++#include "bcm2711.dtsi"
++#include "bcm2835-rpi.dtsi"
++
++/ {
++ compatible = "raspberrypi,4-compute-module", "brcm,bcm2711";
++ model = "Raspberry Pi Compute Module 4";
++
++ chosen {
++ /* 8250 auxiliary UART instead of pl011 */
++ stdout-path = "serial1:115200n8";
++ };
++
++ /* Will be filled by the bootloader */
++ memory@0 {
++ device_type = "memory";
++ reg = <0 0 0>;
++ };
++
++ aliases {
++ ethernet0 = &genet;
++ };
++
++ leds {
++ act {
++ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
++ };
++
++ pwr {
++ label = "PWR";
++ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
++ };
++ };
++
++ wifi_pwrseq: wifi-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
++ };
++
++ sd_io_1v8_reg: sd_io_1v8_reg {
++ compatible = "regulator-gpio";
++ regulator-name = "vdd-sd-io";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ regulator-settling-time-us = <5000>;
++ gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>;
++ states = <1800000 0x1
++ 3300000 0x0>;
++ status = "okay";
++ };
++};
++
++&firmware {
++ expgpio: gpio {
++ compatible = "raspberrypi,firmware-gpio";
++ gpio-controller;
++ #gpio-cells = <2>;
++ gpio-line-names = "BT_ON",
++ "WL_ON",
++ "PWR_LED_OFF",
++ "ANT1",
++ "VDD_SD_IO_SEL",
++ "CAM_GPIO",
++ "SD_PWR_ON",
++ "ANT2";
++ status = "okay";
++
++ ant1: ant1 {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ };
++
++ ant2: ant2 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ };
++ };
++};
++
++&pwm1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm1_0_gpio40 &pwm1_1_gpio41>;
++ status = "okay";
++};
++
++/* SDHCI is used to control the SDIO for wireless */
++&sdhci {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&emmc_gpio34>;
++ bus-width = <4>;
++ non-removable;
++ mmc-pwrseq = <&wifi_pwrseq>;
++ status = "okay";
++
++ brcmf: wifi@1 {
++ reg = <1>;
++ compatible = "brcm,bcm4329-fmac";
++ };
++};
++
++/* EMMC2 is used to drive the SD card */
++&emmc2 {
++ vqmmc-supply = <&sd_io_1v8_reg>;
++ broken-cd;
++ status = "okay";
++};
++
++&genet {
++ phy-handle = <&phy1>;
++ phy-mode = "rgmii-rxid";
++ status = "okay";
++};
++
++&genet_mdio {
++ phy1: ethernet-phy@1 {
++ /* No PHY interrupt */
++ reg = <0x1>;
++ };
++};
++
++/* uart0 communicates with the BT module */
++&uart0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32>;
++ uart-has-rtscts;
++ status = "okay";
++
++ bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ max-speed = <2000000>;
++ shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
++ };
++};
++
++/* uart1 is mapped to the pin header */
++&uart1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart1_gpio14>;
++ status = "okay";
++};
++
++&vchiq {
++ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
++};
++
++&vc4 {
++ status = "okay";
++};
++
++&pixelvalve0 {
++ status = "okay";
++};
++
++&pixelvalve1 {
++ status = "okay";
++};
++
++&pixelvalve2 {
++ status = "okay";
++};
++
++&pixelvalve3 {
++ status = "okay";
++};
++
++&pixelvalve4 {
++ status = "okay";
++};
++
++&hdmi0 {
++ status = "okay";
++};
++
++&ddc0 {
++ status = "okay";
++};
++
++&hdmi1 {
++ status = "okay";
++};
++
++&ddc1 {
++ status = "okay";
++};
++
++// =============================================
++// Downstream rpi- changes
++
++#include "bcm270x.dtsi"
++
++/ {
++ soc {
++ /delete-node/ pixelvalve@7e807000;
++ /delete-node/ hdmi@7e902000;
++ };
++};
++
++#include "bcm2711-rpi.dtsi"
++#include "bcm283x-rpi-csi1-2lane.dtsi"
++#include "bcm283x-rpi-i2c0mux_0_44.dtsi"
++
++/delete-node/ &emmc2;
++
++/ {
++ chosen {
++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1";
++ };
++
++ aliases {
++ serial0 = &uart1;
++ serial1 = &uart0;
++ mmc0 = &emmc2;
++ mmc1 = &mmcnr;
++ mmc2 = &sdhost;
++ /delete-property/ i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ /delete-property/ ethernet;
++ /delete-property/ intc;
++ pcie0 = &pcie0;
++ emmc2bus = &emmc2bus;
++ };
++
++ emmc2bus: emmc2bus {
++ compatible = "simple-bus";
++ #address-cells = <2>;
++ #size-cells = <1>;
++
++ ranges = <0x0 0x7e000000 0x0 0xfe000000 0x01800000>;
++ dma-ranges = <0x0 0xc0000000 0x0 0x00000000 0x40000000>;
++
++ emmc2: emmc2@7e340000 {
++ compatible = "brcm,bcm2711-emmc2";
++ status = "okay";
++ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clocks BCM2711_CLOCK_EMMC2>;
++ reg = <0x0 0x7e340000 0x100>;
++ vqmmc-supply = <&sd_io_1v8_reg>;
++ broken-cd;
++ };
++ };
++
++ /delete-node/ wifi-pwrseq;
++};
++
++&mmcnr {
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdio_pins>;
++ bus-width = <4>;
++ status = "okay";
++};
++
++&uart0 {
++ pinctrl-0 = <&uart0_pins &bt_pins>;
++ status = "okay";
++
++ /delete-node/ bluetooth;
++};
++
++&uart1 {
++ pinctrl-0 = <&uart1_pins>;
++};
++
++&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>;
++ };
++};
++
++&gpio {
++ spi0_pins: spi0_pins {
++ brcm,pins = <9 10 11>;
++ brcm,function = <BCM2835_FSEL_ALT0>;
++ };
++
++ spi0_cs_pins: spi0_cs_pins {
++ brcm,pins = <8 7>;
++ brcm,function = <BCM2835_FSEL_GPIO_OUT>;
++ };
++
++ spi3_pins: spi3_pins {
++ brcm,pins = <1 2 3>;
++ brcm,function = <BCM2835_FSEL_ALT3>;
++ };
++
++ spi3_cs_pins: spi3_cs_pins {
++ brcm,pins = <0 24>;
++ brcm,function = <BCM2835_FSEL_GPIO_OUT>;
++ };
++
++ spi4_pins: spi4_pins {
++ brcm,pins = <5 6 7>;
++ brcm,function = <BCM2835_FSEL_ALT3>;
++ };
++
++ spi4_cs_pins: spi4_cs_pins {
++ brcm,pins = <4 25>;
++ brcm,function = <BCM2835_FSEL_GPIO_OUT>;
++ };
++
++ spi5_pins: spi5_pins {
++ brcm,pins = <13 14 15>;
++ brcm,function = <BCM2835_FSEL_ALT3>;
++ };
++
++ spi5_cs_pins: spi5_cs_pins {
++ brcm,pins = <12 26>;
++ brcm,function = <BCM2835_FSEL_GPIO_OUT>;
++ };
++
++ spi6_pins: spi6_pins {
++ brcm,pins = <19 20 21>;
++ brcm,function = <BCM2835_FSEL_ALT3>;
++ };
++
++ spi6_cs_pins: spi6_cs_pins {
++ brcm,pins = <18 27>;
++ brcm,function = <BCM2835_FSEL_GPIO_OUT>;
++ };
++
++ i2c0_pins: i2c0 {
++ brcm,pins = <0 1>;
++ brcm,function = <BCM2835_FSEL_ALT0>;
++ brcm,pull = <BCM2835_PUD_UP>;
++ };
++
++ i2c1_pins: i2c1 {
++ brcm,pins = <2 3>;
++ brcm,function = <BCM2835_FSEL_ALT0>;
++ brcm,pull = <BCM2835_PUD_UP>;
++ };
++
++ i2c3_pins: i2c3 {
++ brcm,pins = <4 5>;
++ brcm,function = <BCM2835_FSEL_ALT5>;
++ brcm,pull = <BCM2835_PUD_UP>;
++ };
++
++ i2c4_pins: i2c4 {
++ brcm,pins = <8 9>;
++ brcm,function = <BCM2835_FSEL_ALT5>;
++ brcm,pull = <BCM2835_PUD_UP>;
++ };
++
++ i2c5_pins: i2c5 {
++ brcm,pins = <12 13>;
++ brcm,function = <BCM2835_FSEL_ALT5>;
++ brcm,pull = <BCM2835_PUD_UP>;
++ };
++
++ i2c6_pins: i2c6 {
++ brcm,pins = <22 23>;
++ brcm,function = <BCM2835_FSEL_ALT5>;
++ brcm,pull = <BCM2835_PUD_UP>;
++ };
++
++ i2s_pins: i2s {
++ brcm,pins = <18 19 20 21>;
++ brcm,function = <BCM2835_FSEL_ALT0>;
++ };
++
++ sdio_pins: sdio_pins {
++ brcm,pins = <34 35 36 37 38 39>;
++ brcm,function = <BCM2835_FSEL_ALT3>; // alt3 = SD1
++ brcm,pull = <0 2 2 2 2 2>;
++ };
++
++ bt_pins: bt_pins {
++ brcm,pins = "-"; // non-empty to keep btuart happy, //4 = 0
++ // to fool pinctrl
++ brcm,function = <0>;
++ brcm,pull = <2>;
++ };
++
++ uart0_pins: uart0_pins {
++ brcm,pins = <32 33>;
++ brcm,function = <BCM2835_FSEL_ALT3>;
++ brcm,pull = <0 2>;
++ };
++
++ uart1_pins: uart1_pins {
++ brcm,pins;
++ brcm,function;
++ brcm,pull;
++ };
++
++ uart2_pins: uart2_pins {
++ brcm,pins = <0 1>;
++ brcm,function = <BCM2835_FSEL_ALT4>;
++ brcm,pull = <0 2>;
++ };
++
++ uart3_pins: uart3_pins {
++ brcm,pins = <4 5>;
++ brcm,function = <BCM2835_FSEL_ALT4>;
++ brcm,pull = <0 2>;
++ };
++
++ uart4_pins: uart4_pins {
++ brcm,pins = <8 9>;
++ brcm,function = <BCM2835_FSEL_ALT4>;
++ brcm,pull = <0 2>;
++ };
++
++ uart5_pins: uart5_pins {
++ brcm,pins = <12 13>;
++ brcm,function = <BCM2835_FSEL_ALT4>;
++ brcm,pull = <0 2>;
++ };
++};
++
++&i2c0if {
++ clock-frequency = <100000>;
++};
++
++&i2c1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c1_pins>;
++ clock-frequency = <100000>;
++};
++
++&i2s {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s_pins>;
++};
++
++/ {
++ __overrides__ {
++ /delete-property/ i2c2_baudrate;
++ /delete-property/ i2c2_iknowwhatimdoing;
++ };
++};
++
++// =============================================
++// Board specific stuff here
++
++/ {
++ sd_vcc_reg: sd_vcc_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc-sd";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ enable-active-high;
++ gpio = <&expgpio 6 GPIO_ACTIVE_HIGH>;
++ };
++};
++
++&sdhost {
++ status = "disabled";
++};
++
++&emmc2 {
++ vmmc-supply = <&sd_vcc_reg>;
++ bus-width = <8>;
++};
++
++&phy1 {
++ led-modes = <0x00 0x08>; /* link/activity link */
++};
++
++&gpio {
++ audio_pins: audio_pins {
++ brcm,pins = <40 41>;
++ brcm,function = <4>;
++ };
++};
++
++&leds {
++ act_led: act {
++ label = "led0";
++ linux,default-trigger = "mmc0";
++ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
++ };
++
++ pwr_led: pwr {
++ label = "led1";
++ linux,default-trigger = "default-on";
++ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&pwm1 {
++ status = "disabled";
++};
++
++&audio {
++ pinctrl-names = "default";
++ pinctrl-0 = <&audio_pins>;
++};
++
++&vc4 {
++ status = "disabled";
++};
++
++&pixelvalve0 {
++ status = "disabled";
++};
++
++&pixelvalve1 {
++ status = "disabled";
++};
++
++&pixelvalve2 {
++ status = "disabled";
++};
++
++&pixelvalve3 {
++ status = "disabled";
++};
++
++&pixelvalve4 {
++ status = "disabled";
++};
++
++&hdmi0 {
++ status = "disabled";
++};
++
++&ddc0 {
++ status = "disabled";
++};
++
++&hdmi1 {
++ status = "disabled";
++};
++
++&ddc1 {
++ status = "disabled";
++};
++
++/ {
++ __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";
++
++ eth_led0 = <&phy1>,"led-modes:0";
++ eth_led1 = <&phy1>,"led-modes:4";
++
++ ant1 = <&ant1>,"output-high?=on",
++ <&ant1>, "output-low?=off",
++ <&ant2>, "output-high?=off",
++ <&ant2>, "output-low?=on";
++ ant2 = <&ant1>,"output-high?=off",
++ <&ant1>, "output-low?=on",
++ <&ant2>, "output-high?=on",
++ <&ant2>, "output-low?=off";
++ noant = <&ant1>,"output-high?=off",
++ <&ant1>, "output-low?=on",
++ <&ant2>, "output-high?=off",
++ <&ant2>, "output-low?=on";
++
++ spi_dma4 = <&spi0>, "dmas:0=", <&dma40>,
++ <&spi0>, "dmas:8=", <&dma40>;
++ };
++};
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -92,6 +92,12 @@ Name: <The base DTB>
+ Info: Configures the base Raspberry Pi hardware
+ Load: <loaded automatically>
+ Params:
++ ant1 Select antenna 1 (default). CM4 only.
++
++ ant2 Select antenna 2. CM4 only.
++
++ noant Disable both antennas. CM4 only.
++
+ audio Set to "on" to enable the onboard ALSA audio
+ interface (default "off")
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0786-PCI-brcmstb-Add-DT-property-to-control-L1SS.patch b/target/linux/bcm27xx/patches-5.4/950-0786-PCI-brcmstb-Add-DT-property-to-control-L1SS.patch
new file mode 100644
index 0000000000..1d54cff647
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0786-PCI-brcmstb-Add-DT-property-to-control-L1SS.patch
@@ -0,0 +1,79 @@
+From faca7230ba711f7f966cd51bf46f83c5848a8623 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 11 Jun 2020 09:57:03 +0100
+Subject: [PATCH] PCI: brcmstb: Add DT property to control L1SS
+
+The BRCM PCIe block has controls to enable control of the CLKREQ#
+signal by the L1SS, and to gate the refclk with the CLKREQ# input.
+These controls are mutually exclusive - the upstream code sets the
+latter, but some use cases require the former.
+
+Add a Device Tree property - brcm,enable-l1ss - to switch to the
+L1SS configuration.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/pci/controller/pcie-brcmstb.c | 30 ++++++++++++++++++++-------
+ 1 file changed, 23 insertions(+), 7 deletions(-)
+
+--- a/drivers/pci/controller/pcie-brcmstb.c
++++ b/drivers/pci/controller/pcie-brcmstb.c
+@@ -102,8 +102,9 @@
+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
+
+ #define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204
+-#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2
+-#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000
++#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK BIT(1)
++#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_L1SS_ENABLE_MASK BIT(21)
++#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK BIT(27)
+
+ #define PCIE_MSI_INTR2_STATUS 0x4500
+ #define PCIE_MSI_INTR2_CLR 0x4508
+@@ -170,6 +171,7 @@ struct brcm_pcie {
+ struct pci_bus *root_bus;
+ struct device_node *np;
+ bool ssc;
++ bool l1ss;
+ int gen;
+ u64 msi_target_addr;
+ struct brcm_msi *msi;
+@@ -834,12 +836,25 @@ static int brcm_pcie_setup(struct brcm_p
+ PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK);
+ writel(tmp, base + PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1);
+
+- /*
+- * Refclk from RC should be gated with CLKREQ# input when ASPM L0s,L1
+- * is enabled => setting the CLKREQ_DEBUG_ENABLE field to 1.
+- */
+ tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
+- tmp |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK;
++ if (pcie->l1ss) {
++ /*
++ * Enable CLKREQ# signalling include L1 Substate control of
++ * the CLKREQ# signal and the external reference clock buffer.
++ * meet requirement for Endpoints that require CLKREQ#
++ * assertion to clock active within 400ns.
++ */
++ tmp &= ~PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK;
++ tmp |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_L1SS_ENABLE_MASK;
++ } else {
++ /*
++ * Refclk from RC should be gated with CLKREQ# input when
++ * ASPM L0s,L1 is enabled => setting the CLKREQ_DEBUG_ENABLE
++ * field to 1.
++ */
++ tmp &= ~PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_L1SS_ENABLE_MASK;
++ tmp |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK;
++ }
+ writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
+
+ return 0;
+@@ -944,6 +959,7 @@ static int brcm_pcie_probe(struct platfo
+ pcie->gen = (ret < 0) ? 0 : ret;
+
+ pcie->ssc = of_property_read_bool(np, "brcm,enable-ssc");
++ pcie->l1ss = of_property_read_bool(np, "brcm,enable-l1ss");
+
+ ret = pci_parse_request_of_pci_ranges(pcie->dev, &bridge->windows,
+ &bridge->dma_ranges, NULL);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0787-ARM-dts-Set-brcm-enable-l1ss-for-CM4.patch b/target/linux/bcm27xx/patches-5.4/950-0787-ARM-dts-Set-brcm-enable-l1ss-for-CM4.patch
new file mode 100644
index 0000000000..4b53564311
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0787-ARM-dts-Set-brcm-enable-l1ss-for-CM4.patch
@@ -0,0 +1,27 @@
+From a883d8b6624ea9b924323920cac080cb68e02110 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 11 Jun 2020 11:22:38 +0100
+Subject: [PATCH] ARM: dts: Set brcm,enable-l1ss for CM4
+
+Enable the PCIE L1SS on Compute Module 4. It's possible that this is
+also the right thing to do for Pi 4, but it has been working as is
+up to now.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
+@@ -252,6 +252,10 @@
+ /delete-node/ wifi-pwrseq;
+ };
+
++&pcie0 {
++ brcm,enable-l1ss;
++};
++
+ &mmcnr {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdio_pins>;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0788-Revert-SQUASH-Fix-spi-driver-compiler-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0788-Revert-SQUASH-Fix-spi-driver-compiler-warnings.patch
new file mode 100644
index 0000000000..437e5aba59
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0788-Revert-SQUASH-Fix-spi-driver-compiler-warnings.patch
@@ -0,0 +1,23 @@
+From 34072d0778e21edf69455d900b8a16be6b9ac95c Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 16 Jun 2020 10:23:03 +0100
+Subject: [PATCH] Revert "SQUASH: Fix spi driver compiler warnings"
+
+This reverts commit fe3f696b7e5229678ae45d1293e97b5ecc00c245.
+
+See: https://github.com/raspberrypi/linux/pull/3687
+---
+ drivers/spi/spi-bcm2835.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -1182,6 +1182,8 @@ static int bcm2835_spi_setup(struct spi_
+ {
+ struct spi_controller *ctlr = spi->controller;
+ struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
++ struct gpio_chip *chip;
++ enum gpio_lookup_flags lflags;
+ u32 cs;
+
+ /*
diff --git a/target/linux/bcm27xx/patches-5.4/950-0789-Revert-spi-spi-bcm2835-Disable-forced-software-CS.patch b/target/linux/bcm27xx/patches-5.4/950-0789-Revert-spi-spi-bcm2835-Disable-forced-software-CS.patch
new file mode 100644
index 0000000000..1479335217
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0789-Revert-spi-spi-bcm2835-Disable-forced-software-CS.patch
@@ -0,0 +1,59 @@
+From 1d78f72cb5a387922870e2a54228be25f84f95f6 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 16 Jun 2020 10:23:29 +0100
+Subject: [PATCH] Revert "spi: spi-bcm2835: Disable forced software
+ CS"
+
+This reverts commit 2697f0186db346176832b8eb79adaf5c874681e8.
+
+See: https://github.com/raspberrypi/linux/pull/3687
+---
+ drivers/spi/spi-bcm2835.c | 37 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 37 insertions(+)
+
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -1235,6 +1235,43 @@ static int bcm2835_spi_setup(struct spi_
+ return -EINVAL;
+ }
+
++ /*
++ * Translate native CS to GPIO
++ *
++ * FIXME: poking around in the gpiolib internals like this is
++ * not very good practice. Find a way to locate the real problem
++ * and fix it. Why is the GPIO descriptor in spi->cs_gpiod
++ * sometimes not assigned correctly? Erroneous device trees?
++ */
++
++ /* get the gpio chip for the base */
++ chip = gpiochip_find("pinctrl-bcm2835", chip_match_name);
++ if (!chip)
++ return 0;
++
++ /*
++ * Retrieve the corresponding GPIO line used for CS.
++ * The inversion semantics will be handled by the GPIO core
++ * code, so we pass GPIOS_OUT_LOW for "unasserted" and
++ * the correct flag for inversion semantics. The SPI_CS_HIGH
++ * on spi->mode cannot be checked for polarity in this case
++ * as the flag use_gpio_descriptors enforces SPI_CS_HIGH.
++ */
++ if (of_property_read_bool(spi->dev.of_node, "spi-cs-high"))
++ lflags = GPIO_ACTIVE_HIGH;
++ else
++ lflags = GPIO_ACTIVE_LOW;
++ spi->cs_gpiod = gpiochip_request_own_desc(chip, 8 - spi->chip_select,
++ DRV_NAME,
++ lflags,
++ GPIOD_OUT_LOW);
++ if (IS_ERR(spi->cs_gpiod))
++ return PTR_ERR(spi->cs_gpiod);
++
++ /* and set up the "mode" and level */
++ dev_info(&spi->dev, "setting up native-CS%i to use GPIO\n",
++ spi->chip_select);
++
+ return 0;
+ }
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0790-media-irs1125-Using-i2c_transfer-for-ic2-reads.patch b/target/linux/bcm27xx/patches-5.4/950-0790-media-irs1125-Using-i2c_transfer-for-ic2-reads.patch
new file mode 100644
index 0000000000..c68c6ea801
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0790-media-irs1125-Using-i2c_transfer-for-ic2-reads.patch
@@ -0,0 +1,65 @@
+From 167060f4e3303200d373ca55a39ba4b4c55adbcc Mon Sep 17 00:00:00 2001
+From: Markus Proeller <markus.proeller@pieye.org>
+Date: Tue, 16 Jun 2020 13:24:31 +0200
+Subject: [PATCH] media: irs1125: Using i2c_transfer for ic2 reads
+
+Reading data over i2c is done by using i2c_transfer to ensure that this
+operation can't be interrupted.
+
+Signed-off-by: Markus Proeller <markus.proeller@pieye.org>
+---
+ drivers/media/i2c/irs1125.c | 37 ++++++++++++++++++++++---------------
+ 1 file changed, 22 insertions(+), 15 deletions(-)
+
+--- a/drivers/media/i2c/irs1125.c
++++ b/drivers/media/i2c/irs1125.c
+@@ -248,27 +248,34 @@ static int irs1125_write(struct v4l2_sub
+
+ static int irs1125_read(struct v4l2_subdev *sd, u16 reg, u16 *val)
+ {
+- int ret;
+- unsigned char data_w[2] = { reg >> 8, reg & 0xff };
+- char rdval[2];
+-
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct i2c_msg msgs[2];
++ u8 addr_buf[2] = { reg >> 8, reg & 0xff };
++ u8 data_buf[2] = { 0, };
++ int ret;
+
+- ret = i2c_master_send(client, data_w, 2);
+- if (ret < 0) {
+- dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
+- __func__, reg);
++ /* Write register address */
++ msgs[0].addr = client->addr;
++ msgs[0].flags = 0;
++ msgs[0].len = ARRAY_SIZE(addr_buf);
++ msgs[0].buf = addr_buf;
++
++ /* Read data from register */
++ msgs[1].addr = client->addr;
++ msgs[1].flags = I2C_M_RD;
++ msgs[1].len = 2;
++ msgs[1].buf = data_buf;
++
++ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
++ if (ret != ARRAY_SIZE(msgs)) {
++ if (ret >= 0)
++ ret = -EIO;
+ return ret;
+ }
+
+- ret = i2c_master_recv(client, rdval, 2);
+- if (ret < 0)
+- dev_err(&client->dev, "%s: i2c read error, reg: %x\n",
+- __func__, reg);
+-
+- *val = rdval[1] | (rdval[0] << 8);
++ *val = data_buf[1] | (data_buf[0] << 8);
+
+- return ret;
++ return 0;
+ }
+
+ static int irs1125_write_array(struct v4l2_subdev *sd,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0791-media-irs1125-Refactoring-and-debug-messages.patch b/target/linux/bcm27xx/patches-5.4/950-0791-media-irs1125-Refactoring-and-debug-messages.patch
new file mode 100644
index 0000000000..c26ab8fd77
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0791-media-irs1125-Refactoring-and-debug-messages.patch
@@ -0,0 +1,123 @@
+From 6ba58915e8c2f884d17b651d68535959f9eff97d Mon Sep 17 00:00:00 2001
+From: Markus Proeller <markus.proeller@pieye.org>
+Date: Tue, 16 Jun 2020 13:27:42 +0200
+Subject: [PATCH] media: irs1125: Refactoring and debug messages
+
+Changed some variable names to comply with checkpatch --strict mode.
+Debug messages added.
+
+Signed-off-by: Markus Proeller <markus.proeller@pieye.org>
+---
+ drivers/media/i2c/irs1125.c | 36 ++++++++++++++++++++----------------
+ 1 file changed, 20 insertions(+), 16 deletions(-)
+
+--- a/drivers/media/i2c/irs1125.c
++++ b/drivers/media/i2c/irs1125.c
+@@ -15,6 +15,7 @@
+ #include "irs1125.h"
+ #include <linux/clk.h>
+ #include <linux/delay.h>
++#include <linux/firmware.h>
+ #include <linux/gpio/consumer.h>
+ #include <linux/i2c.h>
+ #include <linux/init.h>
+@@ -22,13 +23,13 @@
+ #include <linux/module.h>
+ #include <linux/of_graph.h>
+ #include <linux/slab.h>
++#include <linux/types.h>
+ #include <linux/videodev2.h>
+-#include <linux/firmware.h>
++#include <media/v4l2-ctrls.h>
+ #include <media/v4l2-device.h>
+ #include <media/v4l2-fwnode.h>
+ #include <media/v4l2-image-sizes.h>
+ #include <media/v4l2-mediabus.h>
+-#include <media/v4l2-ctrls.h>
+
+ #define CHECK_BIT(val, pos) ((val) & BIT(pos))
+
+@@ -38,18 +39,19 @@
+
+ #define IRS1125_ALTERNATE_FW "irs1125_af.bin"
+
+-#define IRS1125_REG_CSICFG 0xA882
+-#define IRS1125_REG_DESIGN_STEP 0xB0AD
+-#define IRS1125_REG_EFUSEVAL2 0xB09F
+-#define IRS1125_REG_EFUSEVAL3 0xB0A0
+-#define IRS1125_REG_EFUSEVAL4 0xB0A1
+-#define IRS1125_REG_DMEM_SHADOW 0xC320
++#define IRS1125_REG_SAFE_RECONFIG 0xA850
++#define IRS1125_REG_CSICFG 0xA882
++#define IRS1125_REG_DESIGN_STEP 0xB0AD
++#define IRS1125_REG_EFUSEVAL2 0xB09F
++#define IRS1125_REG_EFUSEVAL3 0xB0A0
++#define IRS1125_REG_EFUSEVAL4 0xB0A1
++#define IRS1125_REG_DMEM_SHADOW 0xC320
+
+-#define IRS1125_DESIGN_STEP_EXPECTED 0x0a12
++#define IRS1125_DESIGN_STEP_EXPECTED 0x0a12
+
+ #define IRS1125_ROW_START_DEF 0
+ #define IRS1125_COLUMN_START_DEF 0
+-#define IRS1125_WINDOW_HEIGHT_DEF 288
++#define IRS1125_WINDOW_HEIGHT_DEF 288
+ #define IRS1125_WINDOW_WIDTH_DEF 352
+
+ struct regval_list {
+@@ -87,7 +89,7 @@ static inline struct irs1125 *to_state(s
+ return container_of(sd, struct irs1125, sd);
+ }
+
+-static struct regval_list irs1125_26MHz[] = {
++static struct regval_list irs1125_26mhz[] = {
+ {0xB017, 0x0413},
+ {0xB086, 0x3535},
+ {0xB0AE, 0xEF02},
+@@ -153,7 +155,7 @@ static struct regval_list irs1125_26MHz[
+ {0xFFFF, 100}
+ };
+
+-static struct regval_list irs1125_seq_cfg[] = {
++static struct regval_list irs1125_seq_cfg_init[] = {
+ {0xC3A0, 0x823D},
+ {0xC3A1, 0xB13B},
+ {0xC3A2, 0x0313},
+@@ -243,6 +245,7 @@ static int irs1125_write(struct v4l2_sub
+ dev_err(&client->dev, "%s: i2c write error, reg: %x\n",
+ __func__, reg);
+
++ dev_dbg(&client->dev, "write addr 0x%04x, val 0x%04x\n", reg, val);
+ return ret;
+ }
+
+@@ -364,8 +367,8 @@ static int __sensor_init(struct v4l2_sub
+ cnt++;
+ }
+
+- ret = irs1125_write_array(sd, irs1125_26MHz,
+- ARRAY_SIZE(irs1125_26MHz));
++ ret = irs1125_write_array(sd, irs1125_26mhz,
++ ARRAY_SIZE(irs1125_26mhz));
+ if (ret < 0) {
+ dev_err(&client->dev, "write sensor default regs error\n");
+ return ret;
+@@ -415,8 +418,8 @@ static int __sensor_init(struct v4l2_sub
+ }
+ release_firmware(fw);
+
+- ret = irs1125_write_array(sd, irs1125_seq_cfg,
+- ARRAY_SIZE(irs1125_seq_cfg));
++ ret = irs1125_write_array(sd, irs1125_seq_cfg_init,
++ ARRAY_SIZE(irs1125_seq_cfg_init));
+ if (ret < 0) {
+ dev_err(&client->dev, "write default sequence failed\n");
+ return ret;
+@@ -1037,6 +1040,7 @@ static int irs1125_probe(struct i2c_clie
+ }
+
+ gpio_num = desc_to_gpio(sensor->reset);
++ dev_dbg(&client->dev, "reset on GPIO num %d\n", gpio_num);
+
+ mutex_init(&sensor->lock);
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0792-media-irs1125-Atomic-access-to-imager-reconfiguratio.patch b/target/linux/bcm27xx/patches-5.4/950-0792-media-irs1125-Atomic-access-to-imager-reconfiguratio.patch
new file mode 100644
index 0000000000..2b5d4b53d5
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0792-media-irs1125-Atomic-access-to-imager-reconfiguratio.patch
@@ -0,0 +1,381 @@
+From 3afb0a757409f5186812b3ea36c61a03855e47d2 Mon Sep 17 00:00:00 2001
+From: Markus Proeller <markus.proeller@pieye.org>
+Date: Tue, 16 Jun 2020 13:31:36 +0200
+Subject: [PATCH] media: irs1125: Atomic access to imager
+ reconfiguration
+
+Instead of changing the exposure and framerate settings for all sequences,
+they can be changed for every sequence individually now. Therefore the
+IRS1125_CID_SAFE_RECONFIG ctrl has been removed and replaced by
+IRS1125_CID_SAFE_RECONFIG_S<seq_num>_EXPO and *_FRAME ctrls.
+
+The consistency check in the sequence ctrl IRS1125_CID_SEQ_CONFIG
+is removed.
+
+Signed-off-by: Markus Proeller <markus.proeller@pieye.org>
+---
+ drivers/media/i2c/irs1125.c | 224 ++++++++++++++++++++++++------------
+ drivers/media/i2c/irs1125.h | 68 ++++++++---
+ 2 files changed, 204 insertions(+), 88 deletions(-)
+
+--- a/drivers/media/i2c/irs1125.c
++++ b/drivers/media/i2c/irs1125.c
+@@ -89,6 +89,52 @@ static inline struct irs1125 *to_state(s
+ return container_of(sd, struct irs1125, sd);
+ }
+
++static const char *expo_ctrl_names[IRS1125_NUM_SEQ_ENTRIES] = {
++ "safe reconfiguration of exposure of sequence 0",
++ "safe reconfiguration of exposure of sequence 1",
++ "safe reconfiguration of exposure of sequence 2",
++ "safe reconfiguration of exposure of sequence 3",
++ "safe reconfiguration of exposure of sequence 4",
++ "safe reconfiguration of exposure of sequence 5",
++ "safe reconfiguration of exposure of sequence 6",
++ "safe reconfiguration of exposure of sequence 7",
++ "safe reconfiguration of exposure of sequence 8",
++ "safe reconfiguration of exposure of sequence 9",
++ "safe reconfiguration of exposure of sequence 10",
++ "safe reconfiguration of exposure of sequence 11",
++ "safe reconfiguration of exposure of sequence 12",
++ "safe reconfiguration of exposure of sequence 13",
++ "safe reconfiguration of exposure of sequence 14",
++ "safe reconfiguration of exposure of sequence 15",
++ "safe reconfiguration of exposure of sequence 16",
++ "safe reconfiguration of exposure of sequence 17",
++ "safe reconfiguration of exposure of sequence 18",
++ "safe reconfiguration of exposure of sequence 19",
++};
++
++static const char *frame_ctrl_names[IRS1125_NUM_SEQ_ENTRIES] = {
++ "safe reconfiguration of framerate of sequence 0",
++ "safe reconfiguration of framerate of sequence 1",
++ "safe reconfiguration of framerate of sequence 2",
++ "safe reconfiguration of framerate of sequence 3",
++ "safe reconfiguration of framerate of sequence 4",
++ "safe reconfiguration of framerate of sequence 5",
++ "safe reconfiguration of framerate of sequence 6",
++ "safe reconfiguration of framerate of sequence 7",
++ "safe reconfiguration of framerate of sequence 8",
++ "safe reconfiguration of framerate of sequence 9",
++ "safe reconfiguration of framerate of sequence 10",
++ "safe reconfiguration of framerate of sequence 11",
++ "safe reconfiguration of framerate of sequence 12",
++ "safe reconfiguration of framerate of sequence 13",
++ "safe reconfiguration of framerate of sequence 14",
++ "safe reconfiguration of framerate of sequence 15",
++ "safe reconfiguration of framerate of sequence 16",
++ "safe reconfiguration of framerate of sequence 17",
++ "safe reconfiguration of framerate of sequence 18",
++ "safe reconfiguration of framerate of sequence 19",
++};
++
+ static struct regval_list irs1125_26mhz[] = {
+ {0xB017, 0x0413},
+ {0xB086, 0x3535},
+@@ -561,36 +607,57 @@ static int irs1125_s_ctrl(struct v4l2_ct
+ struct irs1125 *dev = container_of(ctrl->handler,
+ struct irs1125, ctrl_handler);
+ struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
+- int err, i;
+ struct irs1125_mod_pll *mod_cur, *mod_new;
+- struct irs1125_seq_cfg *cfg_cur, *cfg_new;
+ u16 addr, val;
+-
+- err = 0;
++ int err = 0, i;
+
+ switch (ctrl->id) {
+- case IRS1125_CID_SAFE_RECONFIG:
+- {
+- struct irs1125_illu *illu_cur, *illu_new;
+-
+- illu_new = (struct irs1125_illu *)ctrl->p_new.p;
+- illu_cur = (struct irs1125_illu *)ctrl->p_cur.p;
+- for (i = 0; i < IRS1125_NUM_SEQ_ENTRIES; i++) {
+- if (illu_cur[i].exposure != illu_new[i].exposure) {
+- addr = 0xA850 + i * 2;
+- val = illu_new[i].exposure;
+- err = irs1125_write(&dev->sd, addr, val);
+- if (err < 0)
+- break;
+- }
+- if (illu_cur[i].framerate != illu_new[i].framerate) {
+- addr = 0xA851 + i * 2;
+- val = illu_new[i].framerate;
+- err = irs1125_write(&dev->sd, addr, val);
+- if (err < 0)
+- break;
+- }
+- }
++ case IRS1125_CID_SAFE_RECONFIG_S0_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S0_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S1_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S1_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S2_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S2_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S3_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S3_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S4_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S4_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S5_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S5_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S6_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S6_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S7_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S7_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S8_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S8_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S9_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S9_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S10_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S10_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S11_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S11_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S12_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S12_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S13_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S13_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S14_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S14_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S15_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S15_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S16_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S16_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S17_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S17_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S18_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S18_FRAME:
++ case IRS1125_CID_SAFE_RECONFIG_S19_EXPO:
++ case IRS1125_CID_SAFE_RECONFIG_S19_FRAME: {
++ unsigned int offset = ctrl->id -
++ IRS1125_CID_SAFE_RECONFIG_S0_EXPO;
++
++ err = irs1125_write(&dev->sd,
++ IRS1125_REG_SAFE_RECONFIG + offset,
++ ctrl->val);
+ break;
+ }
+ case IRS1125_CID_MOD_PLL:
+@@ -655,40 +722,40 @@ static int irs1125_s_ctrl(struct v4l2_ct
+ }
+ }
+ break;
+- case IRS1125_CID_SEQ_CONFIG:
++ case IRS1125_CID_SEQ_CONFIG: {
++ struct irs1125_seq_cfg *cfg_new;
++
+ cfg_new = (struct irs1125_seq_cfg *)ctrl->p_new.p;
+- cfg_cur = (struct irs1125_seq_cfg *)ctrl->p_cur.p;
+ for (i = 0; i < IRS1125_NUM_SEQ_ENTRIES; i++) {
+- if (cfg_cur[i].exposure != cfg_new[i].exposure) {
+- addr = IRS1125_REG_DMEM_SHADOW + i * 4;
+- val = cfg_new[i].exposure;
+- err = irs1125_write(&dev->sd, addr, val);
+- if (err < 0)
+- break;
+- }
+- if (cfg_cur[i].framerate != cfg_new[i].framerate) {
+- addr = IRS1125_REG_DMEM_SHADOW + 1 + i * 4;
+- val = cfg_new[i].framerate;
+- err = irs1125_write(&dev->sd, addr, val);
+- if (err < 0)
+- break;
+- }
+- if (cfg_cur[i].ps != cfg_new[i].ps) {
+- addr = IRS1125_REG_DMEM_SHADOW + 2 + i * 4;
+- val = cfg_new[i].ps;
+- err = irs1125_write(&dev->sd, addr, val);
+- if (err < 0)
+- break;
+- }
+- if (cfg_cur[i].pll != cfg_new[i].pll) {
+- addr = IRS1125_REG_DMEM_SHADOW + 3 + i * 4;
+- val = cfg_new[i].pll;
+- err = irs1125_write(&dev->sd, addr, val);
+- if (err < 0)
+- break;
+- }
++ unsigned int seq_offset = i * 4;
++ u16 addr, val;
++
++ addr = IRS1125_REG_DMEM_SHADOW + seq_offset;
++ val = cfg_new[i].exposure;
++ err = irs1125_write(&dev->sd, addr, val);
++ if (err < 0)
++ break;
++
++ addr = IRS1125_REG_DMEM_SHADOW + 1 + seq_offset;
++ val = cfg_new[i].framerate;
++ err = irs1125_write(&dev->sd, addr, val);
++ if (err < 0)
++ break;
++
++ addr = IRS1125_REG_DMEM_SHADOW + 2 + seq_offset;
++ val = cfg_new[i].ps;
++ err = irs1125_write(&dev->sd, addr, val);
++ if (err < 0)
++ break;
++
++ addr = IRS1125_REG_DMEM_SHADOW + 3 + seq_offset;
++ val = cfg_new[i].pll;
++ err = irs1125_write(&dev->sd, addr, val);
++ if (err < 0)
++ break;
+ }
+ break;
++ }
+ case IRS1125_CID_NUM_SEQS:
+ err = irs1125_write(&dev->sd, 0xA88D, ctrl->val - 1);
+ if (err >= 0)
+@@ -760,19 +827,6 @@ static const struct v4l2_ctrl_config irs
+ IRS1125_NUM_MOD_PLLS}
+ }, {
+ .ops = &irs1125_ctrl_ops,
+- .id = IRS1125_CID_SAFE_RECONFIG,
+- .name = "Change exposure and pause of single seq",
+- .type = V4L2_CTRL_TYPE_U16,
+- .flags = V4L2_CTRL_FLAG_HAS_PAYLOAD,
+- .min = 0,
+- .max = U16_MAX,
+- .step = 1,
+- .def = 0,
+- .elem_size = sizeof(u16),
+- .dims = {sizeof(struct irs1125_illu) / sizeof(u16),
+- IRS1125_NUM_SEQ_ENTRIES}
+- }, {
+- .ops = &irs1125_ctrl_ops,
+ .id = IRS1125_CID_SEQ_CONFIG,
+ .name = "Change sequence settings",
+ .type = V4L2_CTRL_TYPE_U16,
+@@ -900,9 +954,16 @@ static int irs1125_ctrls_init(struct irs
+ {
+ struct v4l2_ctrl *ctrl;
+ int err, i;
+- struct v4l2_ctrl_handler *hdl;
++ struct v4l2_ctrl_handler *hdl = &sensor->ctrl_handler;
++ struct v4l2_ctrl_config ctrl_cfg = {
++ .ops = &irs1125_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_INTEGER,
++ .min = 0,
++ .max = U16_MAX,
++ .step = 1,
++ .def = 0x1000
++ };
+
+- hdl = &sensor->ctrl_handler;
+ v4l2_ctrl_handler_init(hdl, ARRAY_SIZE(irs1125_custom_ctrls));
+
+ for (i = 0; i < ARRAY_SIZE(irs1125_custom_ctrls); i++) {
+@@ -923,6 +984,27 @@ static int irs1125_ctrls_init(struct irs
+ goto error_ctrls;
+ }
+
++ for (i = 0; i < IRS1125_NUM_SEQ_ENTRIES; i++) {
++ ctrl_cfg.name = expo_ctrl_names[i];
++ ctrl_cfg.id = IRS1125_CID_SAFE_RECONFIG_S0_EXPO + i * 2;
++ ctrl = v4l2_ctrl_new_custom(hdl, &ctrl_cfg,
++ NULL);
++ if (!ctrl)
++ dev_err(dev, "Failed to init exposure control %s\n",
++ ctrl_cfg.name);
++ }
++
++ ctrl_cfg.def = 0;
++ for (i = 0; i < IRS1125_NUM_SEQ_ENTRIES; i++) {
++ ctrl_cfg.name = frame_ctrl_names[i];
++ ctrl_cfg.id = IRS1125_CID_SAFE_RECONFIG_S0_FRAME + i * 2;
++ ctrl = v4l2_ctrl_new_custom(hdl, &ctrl_cfg,
++ NULL);
++ if (!ctrl)
++ dev_err(dev, "Failed to init framerate control %s\n",
++ ctrl_cfg.name);
++ }
++
+ sensor->sd.ctrl_handler = hdl;
+ return 0;
+
+--- a/drivers/media/i2c/irs1125.h
++++ b/drivers/media/i2c/irs1125.h
+@@ -21,18 +21,57 @@
+ #define IRS1125_NUM_SEQ_ENTRIES 20
+ #define IRS1125_NUM_MOD_PLLS 4
+
+-#define IRS1125_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)
+-#define IRS1125_CID_SAFE_RECONFIG (IRS1125_CID_CUSTOM_BASE + 0)
+-#define IRS1125_CID_CONTINUOUS_TRIG (IRS1125_CID_CUSTOM_BASE + 1)
+-#define IRS1125_CID_TRIGGER (IRS1125_CID_CUSTOM_BASE + 2)
+-#define IRS1125_CID_RECONFIG (IRS1125_CID_CUSTOM_BASE + 3)
+-#define IRS1125_CID_ILLU_ON (IRS1125_CID_CUSTOM_BASE + 4)
+-#define IRS1125_CID_NUM_SEQS (IRS1125_CID_CUSTOM_BASE + 5)
+-#define IRS1125_CID_MOD_PLL (IRS1125_CID_CUSTOM_BASE + 6)
+-#define IRS1125_CID_SEQ_CONFIG (IRS1125_CID_CUSTOM_BASE + 7)
+-#define IRS1125_CID_IDENT0 (IRS1125_CID_CUSTOM_BASE + 8)
+-#define IRS1125_CID_IDENT1 (IRS1125_CID_CUSTOM_BASE + 9)
+-#define IRS1125_CID_IDENT2 (IRS1125_CID_CUSTOM_BASE + 10)
++#define IRS1125_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)
++#define IRS1125_CID_CONTINUOUS_TRIG (IRS1125_CID_CUSTOM_BASE + 1)
++#define IRS1125_CID_TRIGGER (IRS1125_CID_CUSTOM_BASE + 2)
++#define IRS1125_CID_RECONFIG (IRS1125_CID_CUSTOM_BASE + 3)
++#define IRS1125_CID_ILLU_ON (IRS1125_CID_CUSTOM_BASE + 4)
++#define IRS1125_CID_NUM_SEQS (IRS1125_CID_CUSTOM_BASE + 5)
++#define IRS1125_CID_MOD_PLL (IRS1125_CID_CUSTOM_BASE + 6)
++#define IRS1125_CID_SEQ_CONFIG (IRS1125_CID_CUSTOM_BASE + 7)
++#define IRS1125_CID_IDENT0 (IRS1125_CID_CUSTOM_BASE + 8)
++#define IRS1125_CID_IDENT1 (IRS1125_CID_CUSTOM_BASE + 9)
++#define IRS1125_CID_IDENT2 (IRS1125_CID_CUSTOM_BASE + 10)
++#define IRS1125_CID_SAFE_RECONFIG_S0_EXPO (IRS1125_CID_CUSTOM_BASE + 11)
++#define IRS1125_CID_SAFE_RECONFIG_S0_FRAME (IRS1125_CID_CUSTOM_BASE + 12)
++#define IRS1125_CID_SAFE_RECONFIG_S1_EXPO (IRS1125_CID_CUSTOM_BASE + 13)
++#define IRS1125_CID_SAFE_RECONFIG_S1_FRAME (IRS1125_CID_CUSTOM_BASE + 14)
++#define IRS1125_CID_SAFE_RECONFIG_S2_EXPO (IRS1125_CID_CUSTOM_BASE + 15)
++#define IRS1125_CID_SAFE_RECONFIG_S2_FRAME (IRS1125_CID_CUSTOM_BASE + 16)
++#define IRS1125_CID_SAFE_RECONFIG_S3_EXPO (IRS1125_CID_CUSTOM_BASE + 17)
++#define IRS1125_CID_SAFE_RECONFIG_S3_FRAME (IRS1125_CID_CUSTOM_BASE + 18)
++#define IRS1125_CID_SAFE_RECONFIG_S4_EXPO (IRS1125_CID_CUSTOM_BASE + 19)
++#define IRS1125_CID_SAFE_RECONFIG_S4_FRAME (IRS1125_CID_CUSTOM_BASE + 20)
++#define IRS1125_CID_SAFE_RECONFIG_S5_EXPO (IRS1125_CID_CUSTOM_BASE + 21)
++#define IRS1125_CID_SAFE_RECONFIG_S5_FRAME (IRS1125_CID_CUSTOM_BASE + 22)
++#define IRS1125_CID_SAFE_RECONFIG_S6_EXPO (IRS1125_CID_CUSTOM_BASE + 23)
++#define IRS1125_CID_SAFE_RECONFIG_S6_FRAME (IRS1125_CID_CUSTOM_BASE + 24)
++#define IRS1125_CID_SAFE_RECONFIG_S7_EXPO (IRS1125_CID_CUSTOM_BASE + 25)
++#define IRS1125_CID_SAFE_RECONFIG_S7_FRAME (IRS1125_CID_CUSTOM_BASE + 26)
++#define IRS1125_CID_SAFE_RECONFIG_S8_EXPO (IRS1125_CID_CUSTOM_BASE + 27)
++#define IRS1125_CID_SAFE_RECONFIG_S8_FRAME (IRS1125_CID_CUSTOM_BASE + 28)
++#define IRS1125_CID_SAFE_RECONFIG_S9_EXPO (IRS1125_CID_CUSTOM_BASE + 29)
++#define IRS1125_CID_SAFE_RECONFIG_S9_FRAME (IRS1125_CID_CUSTOM_BASE + 30)
++#define IRS1125_CID_SAFE_RECONFIG_S10_EXPO (IRS1125_CID_CUSTOM_BASE + 31)
++#define IRS1125_CID_SAFE_RECONFIG_S10_FRAME (IRS1125_CID_CUSTOM_BASE + 32)
++#define IRS1125_CID_SAFE_RECONFIG_S11_EXPO (IRS1125_CID_CUSTOM_BASE + 33)
++#define IRS1125_CID_SAFE_RECONFIG_S11_FRAME (IRS1125_CID_CUSTOM_BASE + 34)
++#define IRS1125_CID_SAFE_RECONFIG_S12_EXPO (IRS1125_CID_CUSTOM_BASE + 35)
++#define IRS1125_CID_SAFE_RECONFIG_S12_FRAME (IRS1125_CID_CUSTOM_BASE + 36)
++#define IRS1125_CID_SAFE_RECONFIG_S13_EXPO (IRS1125_CID_CUSTOM_BASE + 37)
++#define IRS1125_CID_SAFE_RECONFIG_S13_FRAME (IRS1125_CID_CUSTOM_BASE + 38)
++#define IRS1125_CID_SAFE_RECONFIG_S14_EXPO (IRS1125_CID_CUSTOM_BASE + 39)
++#define IRS1125_CID_SAFE_RECONFIG_S14_FRAME (IRS1125_CID_CUSTOM_BASE + 40)
++#define IRS1125_CID_SAFE_RECONFIG_S15_EXPO (IRS1125_CID_CUSTOM_BASE + 41)
++#define IRS1125_CID_SAFE_RECONFIG_S15_FRAME (IRS1125_CID_CUSTOM_BASE + 42)
++#define IRS1125_CID_SAFE_RECONFIG_S16_EXPO (IRS1125_CID_CUSTOM_BASE + 43)
++#define IRS1125_CID_SAFE_RECONFIG_S16_FRAME (IRS1125_CID_CUSTOM_BASE + 44)
++#define IRS1125_CID_SAFE_RECONFIG_S17_EXPO (IRS1125_CID_CUSTOM_BASE + 45)
++#define IRS1125_CID_SAFE_RECONFIG_S17_FRAME (IRS1125_CID_CUSTOM_BASE + 46)
++#define IRS1125_CID_SAFE_RECONFIG_S18_EXPO (IRS1125_CID_CUSTOM_BASE + 47)
++#define IRS1125_CID_SAFE_RECONFIG_S18_FRAME (IRS1125_CID_CUSTOM_BASE + 48)
++#define IRS1125_CID_SAFE_RECONFIG_S19_EXPO (IRS1125_CID_CUSTOM_BASE + 49)
++#define IRS1125_CID_SAFE_RECONFIG_S19_FRAME (IRS1125_CID_CUSTOM_BASE + 50)
+
+ struct irs1125_seq_cfg {
+ __u16 exposure;
+@@ -41,11 +80,6 @@ struct irs1125_seq_cfg {
+ __u16 pll;
+ };
+
+-struct irs1125_illu {
+- __u16 exposure;
+- __u16 framerate;
+-};
+-
+ struct irs1125_mod_pll {
+ __u16 pllcfg1;
+ __u16 pllcfg2;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0793-media-irs1125-Keep-HW-in-sync-after-imager-reset.patch b/target/linux/bcm27xx/patches-5.4/950-0793-media-irs1125-Keep-HW-in-sync-after-imager-reset.patch
new file mode 100644
index 0000000000..9e9b2729cc
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0793-media-irs1125-Keep-HW-in-sync-after-imager-reset.patch
@@ -0,0 +1,181 @@
+From be2df6c864ba668364011301530372f5b8798593 Mon Sep 17 00:00:00 2001
+From: Markus Proeller <markus.proeller@pieye.org>
+Date: Tue, 16 Jun 2020 13:33:56 +0200
+Subject: [PATCH] media: irs1125: Keep HW in sync after imager reset
+
+When closing the video device, the irs1125 is put in power down state.
+To keep V4L2 ctrls and the HW in sync, v4l2_ctrl_handler_setup is
+called after power up.
+
+The compound ctrl IRS1125_CID_MOD_PLL however has a default value
+of all zeros, which puts the imager into a non responding state.
+Thus, this ctrl is not written by the driver into HW after power up.
+The userspace has to take care to write senseful data.
+
+Signed-off-by: Markus Proeller <markus.proeller@pieye.org>
+---
+ drivers/media/i2c/irs1125.c | 121 +++++++++++++++++-------------------
+ 1 file changed, 58 insertions(+), 63 deletions(-)
+
+--- a/drivers/media/i2c/irs1125.c
++++ b/drivers/media/i2c/irs1125.c
+@@ -82,6 +82,7 @@ struct irs1125 {
+ struct v4l2_ctrl *ctrl_numseq;
+
+ int power_count;
++ bool mod_pll_init;
+ };
+
+ static inline struct irs1125 *to_state(struct v4l2_subdev *sd)
+@@ -276,8 +277,7 @@ static struct regval_list irs1125_seq_cf
+ {0xC039, 0x0000},
+ {0xC401, 0x0002},
+
+- {0xFFFF, 1},
+- {0xA87C, 0x0001}
++ {0xFFFF, 1}
+ };
+
+ static int irs1125_write(struct v4l2_subdev *sd, u16 reg, u16 val)
+@@ -471,7 +471,11 @@ static int __sensor_init(struct v4l2_sub
+ return ret;
+ }
+
+- return 0;
++ irs1125->mod_pll_init = true;
++ v4l2_ctrl_handler_setup(&irs1125->ctrl_handler);
++ irs1125->mod_pll_init = false;
++
++ return irs1125_write(sd, 0xA87C, 0x0001);
+ }
+
+ static int irs1125_sensor_power(struct v4l2_subdev *sd, int on)
+@@ -607,8 +611,6 @@ static int irs1125_s_ctrl(struct v4l2_ct
+ struct irs1125 *dev = container_of(ctrl->handler,
+ struct irs1125, ctrl_handler);
+ struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
+- struct irs1125_mod_pll *mod_cur, *mod_new;
+- u16 addr, val;
+ int err = 0, i;
+
+ switch (ctrl->id) {
+@@ -660,68 +662,61 @@ static int irs1125_s_ctrl(struct v4l2_ct
+ ctrl->val);
+ break;
+ }
+- case IRS1125_CID_MOD_PLL:
++ case IRS1125_CID_MOD_PLL: {
++ struct irs1125_mod_pll *mod_new;
++
++ if (dev->mod_pll_init)
++ break;
++
+ mod_new = (struct irs1125_mod_pll *)ctrl->p_new.p;
+- mod_cur = (struct irs1125_mod_pll *)ctrl->p_cur.p;
+ for (i = 0; i < IRS1125_NUM_MOD_PLLS; i++) {
+- if (mod_cur[i].pllcfg1 != mod_new[i].pllcfg1) {
+- addr = 0xC3A0 + i * 3;
+- val = mod_new[i].pllcfg1;
+- err = irs1125_write(&dev->sd, addr, val);
+- if (err < 0)
+- break;
+- }
+- if (mod_cur[i].pllcfg2 != mod_new[i].pllcfg2) {
+- addr = 0xC3A1 + i * 3;
+- val = mod_new[i].pllcfg2;
+- err = irs1125_write(&dev->sd, addr, val);
+- if (err < 0)
+- break;
+- }
+- if (mod_cur[i].pllcfg3 != mod_new[i].pllcfg3) {
+- addr = 0xC3A2 + i * 3;
+- val = mod_new[i].pllcfg3;
+- err = irs1125_write(&dev->sd, addr, val);
+- if (err < 0)
+- break;
+- }
+- if (mod_cur[i].pllcfg4 != mod_new[i].pllcfg4) {
+- addr = 0xC24C + i * 5;
+- val = mod_new[i].pllcfg4;
+- err = irs1125_write(&dev->sd, addr, val);
+- if (err < 0)
+- break;
+- }
+- if (mod_cur[i].pllcfg5 != mod_new[i].pllcfg5) {
+- addr = 0xC24D + i * 5;
+- val = mod_new[i].pllcfg5;
+- err = irs1125_write(&dev->sd, addr, val);
+- if (err < 0)
+- break;
+- }
+- if (mod_cur[i].pllcfg6 != mod_new[i].pllcfg6) {
+- addr = 0xC24E + i * 5;
+- val = mod_new[i].pllcfg6;
+- err = irs1125_write(&dev->sd, addr, val);
+- if (err < 0)
+- break;
+- }
+- if (mod_cur[i].pllcfg7 != mod_new[i].pllcfg7) {
+- addr = 0xC24F + i * 5;
+- val = mod_new[i].pllcfg7;
+- err = irs1125_write(&dev->sd, addr, val);
+- if (err < 0)
+- break;
+- }
+- if (mod_cur[i].pllcfg8 != mod_new[i].pllcfg8) {
+- addr = 0xC250 + i * 5;
+- val = mod_new[i].pllcfg8;
+- err = irs1125_write(&dev->sd, addr, val);
+- if (err < 0)
+- break;
+- }
++ unsigned int pll_offset, ssc_offset;
++
++ pll_offset = i * 3;
++ ssc_offset = i * 5;
++
++ err = irs1125_write(&dev->sd, 0xC3A0 + pll_offset,
++ mod_new[i].pllcfg1);
++ if (err < 0)
++ break;
++
++ err = irs1125_write(&dev->sd, 0xC3A1 + pll_offset,
++ mod_new[i].pllcfg2);
++ if (err < 0)
++ break;
++
++ err = irs1125_write(&dev->sd, 0xC3A2 + pll_offset,
++ mod_new[i].pllcfg3);
++ if (err < 0)
++ break;
++
++ err = irs1125_write(&dev->sd, 0xC24C + ssc_offset,
++ mod_new[i].pllcfg4);
++ if (err < 0)
++ break;
++
++ err = irs1125_write(&dev->sd, 0xC24D + ssc_offset,
++ mod_new[i].pllcfg5);
++ if (err < 0)
++ break;
++
++ err = irs1125_write(&dev->sd, 0xC24E + ssc_offset,
++ mod_new[i].pllcfg6);
++ if (err < 0)
++ break;
++
++ err = irs1125_write(&dev->sd, 0xC24F + ssc_offset,
++ mod_new[i].pllcfg7);
++ if (err < 0)
++ break;
++
++ err = irs1125_write(&dev->sd, 0xC250 + ssc_offset,
++ mod_new[i].pllcfg8);
++ if (err < 0)
++ break;
+ }
+ break;
++ }
+ case IRS1125_CID_SEQ_CONFIG: {
+ struct irs1125_seq_cfg *cfg_new;
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0794-staging-bcm2835-audio-Add-missing-MODULE_ALIAS.patch b/target/linux/bcm27xx/patches-5.4/950-0794-staging-bcm2835-audio-Add-missing-MODULE_ALIAS.patch
new file mode 100644
index 0000000000..5e096442bb
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0794-staging-bcm2835-audio-Add-missing-MODULE_ALIAS.patch
@@ -0,0 +1,30 @@
+From 1f7c929fc7b010ceca45f8b91b22e71e697b6ec7 Mon Sep 17 00:00:00 2001
+From: Maxim Mikityanskiy <maxtram95@gmail.com>
+Date: Sat, 20 Jun 2020 15:40:00 +0300
+Subject: [PATCH] staging: bcm2835-audio: Add missing MODULE_ALIAS
+
+Commit 8353fe6f1e0f ("Revert "staging: bcm2835-audio: Drop DT
+dependency"") reverts the upstream change and makes bcm2835-audio use
+device tree again, however, it also removes the MODULE_ALIAS for the
+platform device. This MODULE_ALIAS is needed, because VCHIQ registers
+bcm2835-audio as a child platform device since commit 25c7597af20d
+("staging: vchiq_arm: Register a platform device for audio"), and this
+mechanism is adopted also in the downstream kernel.
+
+This commit puts back that MODULE_ALIAS to make bcm2835-audio
+autoprobing work again. The rest of VCHIQ children have their
+MODULE_ALIASes in place.
+
+Fixes: 8353fe6f1e0f ("Revert "staging: bcm2835-audio: Drop DT dependency"")
+Signed-off-by: Maxim Mikityanskiy <maxtram95@gmail.com>
+---
+ drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c
++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c
+@@ -438,3 +438,4 @@ module_platform_driver(bcm2835_alsa_driv
+ MODULE_AUTHOR("Dom Cobley");
+ MODULE_DESCRIPTION("Alsa driver for BCM2835 chip");
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:bcm2835_audio");
diff --git a/target/linux/bcm27xx/patches-5.4/950-0795-media-v4l2-subdev-Introduce-get-set-_mbus_config-pad.patch b/target/linux/bcm27xx/patches-5.4/950-0795-media-v4l2-subdev-Introduce-get-set-_mbus_config-pad.patch
new file mode 100644
index 0000000000..910828421b
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0795-media-v4l2-subdev-Introduce-get-set-_mbus_config-pad.patch
@@ -0,0 +1,63 @@
+From 487203abdef24b7d3cdd110f1b1e699fd22aa02c Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Tue, 16 Jun 2020 16:12:36 +0200
+Subject: [PATCH]_mbus_config
+ pad ops
+
+Upstream https://patchwork.linuxtv.org/patch/64669/
+
+Introduce two new pad operations to allow retrieving and configuring the
+media bus parameters on a subdevice pad.
+
+The newly introduced operations aims to replace the s/g_mbus_config video
+operations, which have been on their way for deprecation since a long
+time.
+
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+---
+ include/media/v4l2-subdev.h | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+--- a/include/media/v4l2-subdev.h
++++ b/include/media/v4l2-subdev.h
+@@ -670,6 +670,29 @@ struct v4l2_subdev_pad_config {
+ *
+ * @set_frame_desc: set the low level media bus frame parameters, @fd array
+ * may be adjusted by the subdev driver to device capabilities.
++ *
++ * @get_mbus_config: get the media bus configuration of a remote sub-device.
++ * The media bus configuration is usually retrieved from the
++ * firmware interface at sub-device probe time, immediately
++ * applied to the hardware and eventually adjusted by the
++ * driver. Remote sub-devices (usually video receivers) shall
++ * use this operation to query the transmitting end bus
++ * configuration in order to adjust their own one accordingly.
++ * Callers should make sure they get the most up-to-date as
++ * possible configuration from the remote end, likely calling
++ * this operation as close as possible to stream on time. The
++ * operation shall fail if the pad index it has been called on
++ * is not valid.
++ *
++ * @set_mbus_config: set the media bus configuration of a remote sub-device.
++ * This operations is intended to allow, in combination with
++ * the get_mbus_config operation, the negotiation of media bus
++ * configuration parameters between media sub-devices. The
++ * operation shall not fail if the requested configuration is
++ * not supported, but the driver shall update the content of
++ * the %config argument to reflect what has been actually
++ * applied to the hardware. The operation shall fail if the
++ * pad index it has been called on is not valid.
+ */
+ struct v4l2_subdev_pad_ops {
+ int (*init_cfg)(struct v4l2_subdev *sd,
+@@ -710,6 +733,10 @@ struct v4l2_subdev_pad_ops {
+ struct v4l2_mbus_frame_desc *fd);
+ int (*set_frame_desc)(struct v4l2_subdev *sd, unsigned int pad,
+ struct v4l2_mbus_frame_desc *fd);
++ int (*get_mbus_config)(struct v4l2_subdev *sd, unsigned int pad,
++ struct v4l2_mbus_config *config);
++ int (*set_mbus_config)(struct v4l2_subdev *sd, unsigned int pad,
++ struct v4l2_mbus_config *config);
+ };
+
+ /**
diff --git a/target/linux/bcm27xx/patches-5.4/950-0796-media-i2c-Use-the-new-get_mbus_config-pad-op.patch b/target/linux/bcm27xx/patches-5.4/950-0796-media-i2c-Use-the-new-get_mbus_config-pad-op.patch
new file mode 100644
index 0000000000..5c432d0c00
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0796-media-i2c-Use-the-new-get_mbus_config-pad-op.patch
@@ -0,0 +1,235 @@
+From 87fde70ab0ba99860153b127e6821be5ae74e73b Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Tue, 16 Jun 2020 16:12:37 +0200
+Subject: [PATCH] media: i2c: Use the new get_mbus_config pad op
+
+Upstream https://patchwork.linuxtv.org/patch/64669/
+
+Move the existing users of the g_mbus_config video operation to use the
+newly introduced get_mbus_config pad operations.
+
+All the ported drivers report a static media bus configuration and do no
+support s_mbus_config so the operation implementation has not changed.
+
+Bridge drivers needs to call the new pad operation and will receive an
+-ENOICTLCMD when calling the old g_mbus_config video operation
+
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+---
+ drivers/media/i2c/adv7180.c | 7 ++++---
+ drivers/media/i2c/ml86v7667.c | 7 ++++---
+ drivers/media/i2c/mt9m001.c | 7 ++++---
+ drivers/media/i2c/mt9m111.c | 7 ++++---
+ drivers/media/i2c/ov9640.c | 7 ++++---
+ drivers/media/i2c/tc358743.c | 7 ++++---
+ drivers/media/i2c/tvp5150.c | 7 ++++---
+ 7 files changed, 28 insertions(+), 21 deletions(-)
+
+--- a/drivers/media/i2c/adv7180.c
++++ b/drivers/media/i2c/adv7180.c
+@@ -749,8 +749,9 @@ static int adv7180_set_pad_format(struct
+ return ret;
+ }
+
+-static int adv7180_g_mbus_config(struct v4l2_subdev *sd,
+- struct v4l2_mbus_config *cfg)
++static int adv7180_get_mbus_config(struct v4l2_subdev *sd,
++ unsigned int pad,
++ struct v4l2_mbus_config *cfg)
+ {
+ struct adv7180_state *state = to_state(sd);
+
+@@ -841,7 +842,6 @@ static const struct v4l2_subdev_video_op
+ .querystd = adv7180_querystd,
+ .g_input_status = adv7180_g_input_status,
+ .s_routing = adv7180_s_routing,
+- .g_mbus_config = adv7180_g_mbus_config,
+ .g_pixelaspect = adv7180_g_pixelaspect,
+ .g_tvnorms = adv7180_g_tvnorms,
+ .s_stream = adv7180_s_stream,
+@@ -857,6 +857,7 @@ static const struct v4l2_subdev_pad_ops
+ .enum_mbus_code = adv7180_enum_mbus_code,
+ .set_fmt = adv7180_set_pad_format,
+ .get_fmt = adv7180_get_pad_format,
++ .get_mbus_config = adv7180_get_mbus_config,
+ };
+
+ static const struct v4l2_subdev_sensor_ops adv7180_sensor_ops = {
+--- a/drivers/media/i2c/ml86v7667.c
++++ b/drivers/media/i2c/ml86v7667.c
+@@ -219,8 +219,9 @@ static int ml86v7667_fill_fmt(struct v4l
+ return 0;
+ }
+
+-static int ml86v7667_g_mbus_config(struct v4l2_subdev *sd,
+- struct v4l2_mbus_config *cfg)
++static int ml86v7667_get_mbus_config(struct v4l2_subdev *sd,
++ unsigned int pad,
++ struct v4l2_mbus_config *cfg)
+ {
+ cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
+ V4L2_MBUS_DATA_ACTIVE_HIGH;
+@@ -291,13 +292,13 @@ static const struct v4l2_subdev_video_op
+ .s_std = ml86v7667_s_std,
+ .querystd = ml86v7667_querystd,
+ .g_input_status = ml86v7667_g_input_status,
+- .g_mbus_config = ml86v7667_g_mbus_config,
+ };
+
+ static const struct v4l2_subdev_pad_ops ml86v7667_subdev_pad_ops = {
+ .enum_mbus_code = ml86v7667_enum_mbus_code,
+ .get_fmt = ml86v7667_fill_fmt,
+ .set_fmt = ml86v7667_fill_fmt,
++ .get_mbus_config = ml86v7667_get_mbus_config,
+ };
+
+ static const struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = {
+--- a/drivers/media/i2c/mt9m001.c
++++ b/drivers/media/i2c/mt9m001.c
+@@ -689,8 +689,9 @@ static int mt9m001_enum_mbus_code(struct
+ return 0;
+ }
+
+-static int mt9m001_g_mbus_config(struct v4l2_subdev *sd,
+- struct v4l2_mbus_config *cfg)
++static int mt9m001_get_mbus_config(struct v4l2_subdev *sd,
++ unsigned int pad,
++ struct v4l2_mbus_config *cfg)
+ {
+ /* MT9M001 has all capture_format parameters fixed */
+ cfg->flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
+@@ -703,7 +704,6 @@ static int mt9m001_g_mbus_config(struct
+
+ static const struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
+ .s_stream = mt9m001_s_stream,
+- .g_mbus_config = mt9m001_g_mbus_config,
+ };
+
+ static const struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
+@@ -717,6 +717,7 @@ static const struct v4l2_subdev_pad_ops
+ .set_selection = mt9m001_set_selection,
+ .get_fmt = mt9m001_get_fmt,
+ .set_fmt = mt9m001_set_fmt,
++ .get_mbus_config = mt9m001_get_mbus_config,
+ };
+
+ static const struct v4l2_subdev_ops mt9m001_subdev_ops = {
+--- a/drivers/media/i2c/mt9m111.c
++++ b/drivers/media/i2c/mt9m111.c
+@@ -1137,8 +1137,9 @@ static int mt9m111_init_cfg(struct v4l2_
+ return 0;
+ }
+
+-static int mt9m111_g_mbus_config(struct v4l2_subdev *sd,
+- struct v4l2_mbus_config *cfg)
++static int mt9m111_get_mbus_config(struct v4l2_subdev *sd,
++ unsigned int pad,
++ struct v4l2_mbus_config *cfg)
+ {
+ struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
+
+@@ -1155,7 +1156,6 @@ static int mt9m111_g_mbus_config(struct
+ }
+
+ static const struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
+- .g_mbus_config = mt9m111_g_mbus_config,
+ .s_stream = mt9m111_s_stream,
+ .g_frame_interval = mt9m111_g_frame_interval,
+ .s_frame_interval = mt9m111_s_frame_interval,
+@@ -1168,6 +1168,7 @@ static const struct v4l2_subdev_pad_ops
+ .set_selection = mt9m111_set_selection,
+ .get_fmt = mt9m111_get_fmt,
+ .set_fmt = mt9m111_set_fmt,
++ .get_mbus_config = mt9m111_get_mbus_config,
+ };
+
+ static const struct v4l2_subdev_ops mt9m111_subdev_ops = {
+--- a/drivers/media/i2c/ov9640.c
++++ b/drivers/media/i2c/ov9640.c
+@@ -648,8 +648,9 @@ static const struct v4l2_subdev_core_ops
+ };
+
+ /* Request bus settings on camera side */
+-static int ov9640_g_mbus_config(struct v4l2_subdev *sd,
+- struct v4l2_mbus_config *cfg)
++static int ov9640_get_mbus_config(struct v4l2_subdev *sd,
++ unsigned int pad,
++ struct v4l2_mbus_config *cfg)
+ {
+ cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
+ V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+@@ -661,13 +662,13 @@ static int ov9640_g_mbus_config(struct v
+
+ static const struct v4l2_subdev_video_ops ov9640_video_ops = {
+ .s_stream = ov9640_s_stream,
+- .g_mbus_config = ov9640_g_mbus_config,
+ };
+
+ static const struct v4l2_subdev_pad_ops ov9640_pad_ops = {
+ .enum_mbus_code = ov9640_enum_mbus_code,
+ .get_selection = ov9640_get_selection,
+ .set_fmt = ov9640_set_fmt,
++ .get_mbus_config = ov9640_get_mbus_config,
+ };
+
+ static const struct v4l2_subdev_ops ov9640_subdev_ops = {
+--- a/drivers/media/i2c/tc358743.c
++++ b/drivers/media/i2c/tc358743.c
+@@ -1621,8 +1621,9 @@ static int tc358743_dv_timings_cap(struc
+ return 0;
+ }
+
+-static int tc358743_g_mbus_config(struct v4l2_subdev *sd,
+- struct v4l2_mbus_config *cfg)
++static int tc358743_get_mbus_config(struct v4l2_subdev *sd,
++ unsigned int pad,
++ struct v4l2_mbus_config *cfg)
+ {
+ struct tc358743_state *state = to_state(sd);
+ const u32 mask = V4L2_MBUS_CSI2_LANE_MASK;
+@@ -1852,7 +1853,6 @@ static const struct v4l2_subdev_video_op
+ .s_dv_timings = tc358743_s_dv_timings,
+ .g_dv_timings = tc358743_g_dv_timings,
+ .query_dv_timings = tc358743_query_dv_timings,
+- .g_mbus_config = tc358743_g_mbus_config,
+ .s_stream = tc358743_s_stream,
+ };
+
+@@ -1864,6 +1864,7 @@ static const struct v4l2_subdev_pad_ops
+ .set_edid = tc358743_s_edid,
+ .enum_dv_timings = tc358743_enum_dv_timings,
+ .dv_timings_cap = tc358743_dv_timings_cap,
++ .get_mbus_config = tc358743_get_mbus_config,
+ };
+
+ static const struct v4l2_subdev_ops tc358743_ops = {
+--- a/drivers/media/i2c/tvp5150.c
++++ b/drivers/media/i2c/tvp5150.c
+@@ -1104,8 +1104,9 @@ static int tvp5150_get_selection(struct
+ }
+ }
+
+-static int tvp5150_g_mbus_config(struct v4l2_subdev *sd,
+- struct v4l2_mbus_config *cfg)
++static int tvp5150_get_mbus_config(struct v4l2_subdev *sd,
++ unsigned int pad,
++ struct v4l2_mbus_config *cfg)
+ {
+ struct tvp5150 *decoder = to_tvp5150(sd);
+
+@@ -1411,7 +1412,6 @@ static const struct v4l2_subdev_video_op
+ .querystd = tvp5150_querystd,
+ .s_stream = tvp5150_s_stream,
+ .s_routing = tvp5150_s_routing,
+- .g_mbus_config = tvp5150_g_mbus_config,
+ };
+
+ static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = {
+@@ -1429,6 +1429,7 @@ static const struct v4l2_subdev_pad_ops
+ .get_fmt = tvp5150_fill_fmt,
+ .get_selection = tvp5150_get_selection,
+ .set_selection = tvp5150_set_selection,
++ .get_mbus_config = tvp5150_get_mbus_config,
+ };
+
+ static const struct v4l2_subdev_ops tvp5150_ops = {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0797-media-i2c-ov6650-Use-new-get-set-_mbus_config-ops.patch b/target/linux/bcm27xx/patches-5.4/950-0797-media-i2c-ov6650-Use-new-get-set-_mbus_config-ops.patch
new file mode 100644
index 0000000000..d1c0a65baf
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0797-media-i2c-ov6650-Use-new-get-set-_mbus_config-ops.patch
@@ -0,0 +1,134 @@
+From 0dd7e12bb7dc81e09440f3330465c31349497dc3 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Tue, 16 Jun 2020 16:12:38 +0200
+Subject: [PATCH]_mbus_config
+ ops
+
+Upstream https://patchwork.linuxtv.org/patch/64674/
+
+Use the new get_mbus_config and set_mbus_config pad operations in place
+of the video operations currently in use.
+
+Compared to other drivers where the same conversion has been performed,
+ov6650 proved to be a bit more tricky, as the existing g_mbus_config
+implementation did not report the currently applied configuration but
+the set of all possible configuration options.
+
+Adapt the driver to support the semantic of the two newly introduced
+operations:
+- get_mbus_config reports the current media bus configuration
+- set_mbus_config applies only changes explicitly requested and updates
+ the provided cfg parameter to report what has actually been applied to
+ the hardware.
+
+Compile-tested only.
+
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+---
+ drivers/media/i2c/ov6650.c | 56 ++++++++++++++++++++++++++------------
+ 1 file changed, 39 insertions(+), 17 deletions(-)
+
+--- a/drivers/media/i2c/ov6650.c
++++ b/drivers/media/i2c/ov6650.c
+@@ -909,46 +909,68 @@ static const struct v4l2_subdev_core_ops
+ };
+
+ /* Request bus settings on camera side */
+-static int ov6650_g_mbus_config(struct v4l2_subdev *sd,
+- struct v4l2_mbus_config *cfg)
++static int ov6650_get_mbus_config(struct v4l2_subdev *sd,
++ unsigned int pad,
++ struct v4l2_mbus_config *cfg)
+ {
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ u8 comj, comf;
++ int ret;
++
++ ret = ov6650_reg_read(client, REG_COMJ, &comj);
++ if (ret)
++ return ret;
++
++ ret = ov6650_reg_read(client, REG_COMF, &comf);
++ if (ret)
++ return ret;
+
+- cfg->flags = V4L2_MBUS_MASTER |
+- V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
+- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
+- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
+- V4L2_MBUS_DATA_ACTIVE_HIGH;
++ cfg->flags = V4L2_MBUS_MASTER
++ | ((comj & COMJ_VSYNC_HIGH) ? V4L2_MBUS_VSYNC_ACTIVE_HIGH
++ : V4L2_MBUS_VSYNC_ACTIVE_LOW)
++ | ((comf & COMF_HREF_LOW) ? V4L2_MBUS_HSYNC_ACTIVE_LOW
++ : V4L2_MBUS_HSYNC_ACTIVE_HIGH)
++ | ((comj & COMJ_PCLK_RISING) ? V4L2_MBUS_PCLK_SAMPLE_RISING
++ : V4L2_MBUS_PCLK_SAMPLE_FALLING);
+ cfg->type = V4L2_MBUS_PARALLEL;
+
+ return 0;
+ }
+
+ /* Alter bus settings on camera side */
+-static int ov6650_s_mbus_config(struct v4l2_subdev *sd,
+- const struct v4l2_mbus_config *cfg)
++static int ov6650_set_mbus_config(struct v4l2_subdev *sd,
++ unsigned int pad,
++ struct v4l2_mbus_config *cfg)
+ {
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+- int ret;
++ int ret = 0;
+
+ if (cfg->flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
+ ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0);
+- else
++ else if (cfg->flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
+ ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING);
+ if (ret)
+- return ret;
++ goto error;
+
+ if (cfg->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
+ ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0);
+- else
++ else if (cfg->flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
+ ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW);
+ if (ret)
+- return ret;
++ goto error;
+
+ if (cfg->flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
+ ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0);
+- else
++ else if (cfg->flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
+ ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH);
+
++error:
++ /*
++ * Update the configuration to report what is actually applied to
++ * the hardware.
++ */
++ ov6650_get_mbus_config(sd, pad, cfg);
++
+ return ret;
+ }
+
+@@ -956,8 +978,6 @@ static const struct v4l2_subdev_video_op
+ .s_stream = ov6650_s_stream,
+ .g_frame_interval = ov6650_g_frame_interval,
+ .s_frame_interval = ov6650_s_frame_interval,
+- .g_mbus_config = ov6650_g_mbus_config,
+- .s_mbus_config = ov6650_s_mbus_config,
+ };
+
+ static const struct v4l2_subdev_pad_ops ov6650_pad_ops = {
+@@ -966,6 +986,8 @@ static const struct v4l2_subdev_pad_ops
+ .set_selection = ov6650_set_selection,
+ .get_fmt = ov6650_get_fmt,
+ .set_fmt = ov6650_set_fmt,
++ .get_mbus_config = ov6650_get_mbus_config,
++ .set_mbus_config = ov6650_set_mbus_config,
+ };
+
+ static const struct v4l2_subdev_ops ov6650_subdev_ops = {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch b/target/linux/bcm27xx/patches-5.4/950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch
new file mode 100644
index 0000000000..d682cf842f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch
@@ -0,0 +1,285 @@
+From 63f4970ce038e60455a6225b317d0b259e046c94 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Tue, 16 Jun 2020 16:12:39 +0200
+Subject: [PATCH] media: pxa_camera: Use the new set_mbus_config op
+
+Upstream https://patchwork.linuxtv.org/patch/64671/
+
+Move the PXA camera driver to use the new set_mbus_config pad operation.
+For this platform the change is not only cosmetic, as the pxa driver is
+currently the only driver in mainline to make use of the g_mbus_config
+and s_mbus_config video operations.
+
+The existing driver semantic is the following:
+- Collect all supported mbus config flags from the remote end
+- Match them with the supported PXA mbus configuration flags
+- If the remote subdevice allows multiple options for for VSYNC, HSYNC
+ and PCLK polarity, use platform data requested settings
+
+The semantic of the new get_mbus_config and set_mbus_config differs from
+the corresponding video ops, particularly in the fact get_mbus_config
+reports the current mbus configuration and not the set of supported
+configuration options, with set_mbus_config always reporting the actual
+mbus configuration applied to the remote subdevice.
+
+Adapt the driver to perform the following
+- Set the remote subdevice mbus configuration according to the PXA
+ platform data preferences.
+- If the applied configuration differs from the requested one (i.e. the
+ remote subdevice does not allow changing one setting) make sure that
+ - The remote end does not claim for DATA_ACTIVE_LOW, which seems not
+ supported by the platform
+ - The bus mastering roles match
+
+While at there remove a few checks performed on the media bus
+configuration at get_format() time as they do not belong there.
+
+Compile-tested only.
+
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+---
+ drivers/media/platform/pxa_camera.c | 189 ++++++++--------------------
+ 1 file changed, 51 insertions(+), 138 deletions(-)
+
+--- a/drivers/media/platform/pxa_camera.c
++++ b/drivers/media/platform/pxa_camera.c
+@@ -605,42 +605,6 @@ static const struct pxa_mbus_pixelfmt *p
+ return pxa_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt));
+ }
+
+-static unsigned int pxa_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
+- unsigned int flags)
+-{
+- unsigned long common_flags;
+- bool hsync = true, vsync = true, pclk, data, mode;
+- bool mipi_lanes, mipi_clock;
+-
+- common_flags = cfg->flags & flags;
+-
+- switch (cfg->type) {
+- case V4L2_MBUS_PARALLEL:
+- hsync = common_flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+- V4L2_MBUS_HSYNC_ACTIVE_LOW);
+- vsync = common_flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+- V4L2_MBUS_VSYNC_ACTIVE_LOW);
+- /* fall through */
+- case V4L2_MBUS_BT656:
+- pclk = common_flags & (V4L2_MBUS_PCLK_SAMPLE_RISING |
+- V4L2_MBUS_PCLK_SAMPLE_FALLING);
+- data = common_flags & (V4L2_MBUS_DATA_ACTIVE_HIGH |
+- V4L2_MBUS_DATA_ACTIVE_LOW);
+- mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE);
+- return (!hsync || !vsync || !pclk || !data || !mode) ?
+- 0 : common_flags;
+- case V4L2_MBUS_CSI2_DPHY:
+- mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES;
+- mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK |
+- V4L2_MBUS_CSI2_CONTINUOUS_CLOCK);
+- return (!mipi_lanes || !mipi_clock) ? 0 : common_flags;
+- default:
+- WARN_ON(1);
+- return -EINVAL;
+- }
+- return 0;
+-}
+-
+ /**
+ * struct pxa_camera_format_xlate - match between host and sensor formats
+ * @code: code of a sensor provided format
+@@ -1231,31 +1195,6 @@ static irqreturn_t pxa_camera_irq(int ir
+ return IRQ_HANDLED;
+ }
+
+-static int test_platform_param(struct pxa_camera_dev *pcdev,
+- unsigned char buswidth, unsigned long *flags)
+-{
+- /*
+- * Platform specified synchronization and pixel clock polarities are
+- * only a recommendation and are only used during probing. The PXA270
+- * quick capture interface supports both.
+- */
+- *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ?
+- V4L2_MBUS_MASTER : V4L2_MBUS_SLAVE) |
+- V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+- V4L2_MBUS_HSYNC_ACTIVE_LOW |
+- V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+- V4L2_MBUS_VSYNC_ACTIVE_LOW |
+- V4L2_MBUS_DATA_ACTIVE_HIGH |
+- V4L2_MBUS_PCLK_SAMPLE_RISING |
+- V4L2_MBUS_PCLK_SAMPLE_FALLING;
+-
+- /* If requested data width is supported by the platform, use it */
+- if ((1 << (buswidth - 1)) & pcdev->width_flags)
+- return 0;
+-
+- return -EINVAL;
+-}
+-
+ static void pxa_camera_setup_cicr(struct pxa_camera_dev *pcdev,
+ unsigned long flags, __u32 pixfmt)
+ {
+@@ -1598,99 +1537,78 @@ static int pxa_camera_init_videobuf2(str
+ */
+ static int pxa_camera_set_bus_param(struct pxa_camera_dev *pcdev)
+ {
++ unsigned int bus_width = pcdev->current_fmt->host_fmt->bits_per_sample;
+ struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+ u32 pixfmt = pcdev->current_fmt->host_fmt->fourcc;
+- unsigned long bus_flags, common_flags;
++ int mbus_config;
+ int ret;
+
+- ret = test_platform_param(pcdev,
+- pcdev->current_fmt->host_fmt->bits_per_sample,
+- &bus_flags);
+- if (ret < 0)
+- return ret;
+-
+- ret = sensor_call(pcdev, video, g_mbus_config, &cfg);
+- if (!ret) {
+- common_flags = pxa_mbus_config_compatible(&cfg,
+- bus_flags);
+- if (!common_flags) {
+- dev_warn(pcdev_to_dev(pcdev),
+- "Flags incompatible: camera 0x%x, host 0x%lx\n",
+- cfg.flags, bus_flags);
+- return -EINVAL;
+- }
+- } else if (ret != -ENOIOCTLCMD) {
+- return ret;
+- } else {
+- common_flags = bus_flags;
++ if (!((1 << (bus_width - 1)) & pcdev->width_flags)) {
++ dev_err(pcdev_to_dev(pcdev), "Unsupported bus width %u",
++ bus_width);
++ return -EINVAL;
+ }
+
+ pcdev->channels = 1;
+
+ /* Make choices, based on platform preferences */
+- if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
+- (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
+- if (pcdev->platform_flags & PXA_CAMERA_HSP)
+- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
+- else
+- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
+- }
+-
+- if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
+- (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
+- if (pcdev->platform_flags & PXA_CAMERA_VSP)
+- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
+- else
+- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
+- }
+-
+- if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
+- (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
+- if (pcdev->platform_flags & PXA_CAMERA_PCP)
+- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
+- else
+- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
+- }
+-
+- cfg.flags = common_flags;
+- ret = sensor_call(pcdev, video, s_mbus_config, &cfg);
+- if (ret < 0 && ret != -ENOIOCTLCMD) {
+- dev_dbg(pcdev_to_dev(pcdev),
+- "camera s_mbus_config(0x%lx) returned %d\n",
+- common_flags, ret);
+- return ret;
+- }
++ mbus_config = 0;
++ if (pcdev->platform_flags & PXA_CAMERA_MASTER)
++ mbus_config |= V4L2_MBUS_MASTER;
++ else
++ mbus_config |= V4L2_MBUS_SLAVE;
+
+- pxa_camera_setup_cicr(pcdev, common_flags, pixfmt);
++ if (pcdev->platform_flags & PXA_CAMERA_HSP)
++ mbus_config |= V4L2_MBUS_HSYNC_ACTIVE_HIGH;
++ else
++ mbus_config |= V4L2_MBUS_HSYNC_ACTIVE_LOW;
+
+- return 0;
+-}
++ if (pcdev->platform_flags & PXA_CAMERA_VSP)
++ mbus_config |= V4L2_MBUS_VSYNC_ACTIVE_HIGH;
++ else
++ mbus_config |= V4L2_MBUS_VSYNC_ACTIVE_LOW;
+
+-static int pxa_camera_try_bus_param(struct pxa_camera_dev *pcdev,
+- unsigned char buswidth)
+-{
+- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+- unsigned long bus_flags, common_flags;
+- int ret = test_platform_param(pcdev, buswidth, &bus_flags);
++ if (pcdev->platform_flags & PXA_CAMERA_PCP)
++ mbus_config |= V4L2_MBUS_PCLK_SAMPLE_RISING;
++ else
++ mbus_config |= V4L2_MBUS_PCLK_SAMPLE_FALLING;
++ mbus_config |= V4L2_MBUS_DATA_ACTIVE_HIGH;
+
+- if (ret < 0)
++ cfg.flags = mbus_config;
++ ret = sensor_call(pcdev, pad, set_mbus_config, 0, &cfg);
++ if (ret < 0 && ret != -ENOIOCTLCMD) {
++ dev_err(pcdev_to_dev(pcdev),
++ "Failed to call set_mbus_config: %d\n", ret);
+ return ret;
++ }
++
++ /*
++ * If the requested media bus configuration has not been fully applied
++ * make sure it is supported by the platform.
++ *
++ * PXA does not support V4L2_MBUS_DATA_ACTIVE_LOW and the bus mastering
++ * roles should match.
++ */
++ if (cfg.flags != mbus_config) {
++ unsigned int pxa_mbus_role = mbus_config & (V4L2_MBUS_MASTER |
++ V4L2_MBUS_SLAVE);
++ if (pxa_mbus_role != (cfg.flags & (V4L2_MBUS_MASTER |
++ V4L2_MBUS_SLAVE))) {
++ dev_err(pcdev_to_dev(pcdev),
++ "Unsupported mbus configuration: bus mastering\n");
++ return -EINVAL;
++ }
+
+- ret = sensor_call(pcdev, video, g_mbus_config, &cfg);
+- if (!ret) {
+- common_flags = pxa_mbus_config_compatible(&cfg,
+- bus_flags);
+- if (!common_flags) {
+- dev_warn(pcdev_to_dev(pcdev),
+- "Flags incompatible: camera 0x%x, host 0x%lx\n",
+- cfg.flags, bus_flags);
++ if (cfg.flags & V4L2_MBUS_DATA_ACTIVE_LOW) {
++ dev_err(pcdev_to_dev(pcdev),
++ "Unsupported mbus configuration: DATA_ACTIVE_LOW\n");
+ return -EINVAL;
+ }
+- } else if (ret == -ENOIOCTLCMD) {
+- ret = 0;
+ }
+
+- return ret;
++ pxa_camera_setup_cicr(pcdev, cfg.flags, pixfmt);
++
++ return 0;
+ }
+
+ static const struct pxa_mbus_pixelfmt pxa_camera_formats[] = {
+@@ -1738,11 +1656,6 @@ static int pxa_camera_get_formats(struct
+ return 0;
+ }
+
+- /* This also checks support for the requested bits-per-sample */
+- ret = pxa_camera_try_bus_param(pcdev, fmt->bits_per_sample);
+- if (ret < 0)
+- return 0;
+-
+ switch (code.code) {
+ case MEDIA_BUS_FMT_UYVY8_2X8:
+ formats++;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0799-media-v4l2-subdev-Remove-s-g-_mbus_config-video-ops.patch b/target/linux/bcm27xx/patches-5.4/950-0799-media-v4l2-subdev-Remove-s-g-_mbus_config-video-ops.patch
new file mode 100644
index 0000000000..a7186da342
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0799-media-v4l2-subdev-Remove-s-g-_mbus_config-video-ops.patch
@@ -0,0 +1,43 @@
+From 316ebebe8edf42f264a0b2225adc5baa46451415 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Tue, 16 Jun 2020 16:12:40 +0200
+Subject: [PATCH]_mbus_config video
+ ops
+
+Upstream https://patchwork.linuxtv.org/patch/64670/
+
+With all sensor and platform drivers now converted to use the new
+get_mbus_config and set_mbus_config pad operations, remove the
+deprecated video operations g_mbus_config and s_mbus_config.
+
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+---
+ include/media/v4l2-subdev.h | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+--- a/include/media/v4l2-subdev.h
++++ b/include/media/v4l2-subdev.h
+@@ -402,12 +402,6 @@ struct v4l2_mbus_frame_desc {
+ *
+ * @query_dv_timings: callback for VIDIOC_QUERY_DV_TIMINGS() ioctl handler code.
+ *
+- * @g_mbus_config: get supported mediabus configurations
+- *
+- * @s_mbus_config: set a certain mediabus configuration. This operation is added
+- * for compatibility with soc-camera drivers and should not be used by new
+- * software.
+- *
+ * @s_rx_buffer: set a host allocated memory buffer for the subdev. The subdev
+ * can adjust @size to a lower value and must not write more data to the
+ * buffer starting at @data than the original value of @size.
+@@ -435,10 +429,6 @@ struct v4l2_subdev_video_ops {
+ struct v4l2_dv_timings *timings);
+ int (*query_dv_timings)(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings *timings);
+- int (*g_mbus_config)(struct v4l2_subdev *sd,
+- struct v4l2_mbus_config *cfg);
+- int (*s_mbus_config)(struct v4l2_subdev *sd,
+- const struct v4l2_mbus_config *cfg);
+ int (*s_rx_buffer)(struct v4l2_subdev *sd, void *buf,
+ unsigned int *size);
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0800-staging-media-imx-Update-TODO-entry.patch b/target/linux/bcm27xx/patches-5.4/950-0800-staging-media-imx-Update-TODO-entry.patch
new file mode 100644
index 0000000000..6d4b569b7f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0800-staging-media-imx-Update-TODO-entry.patch
@@ -0,0 +1,28 @@
+From 3dff4096a98f9ebb3fbc1ed7275d2d64f299db26 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Tue, 16 Jun 2020 16:12:41 +0200
+Subject: [PATCH] staging: media: imx: Update TODO entry
+
+Upstream https://patchwork.linuxtv.org/patch/64672/
+
+Update the TODO entry that mentioned a potential use case for the now
+removed g_mbus_config video operation.
+
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+---
+ drivers/staging/media/imx/TODO | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/staging/media/imx/TODO
++++ b/drivers/staging/media/imx/TODO
+@@ -10,6 +10,10 @@
+ driver uses the parsed DT bus config method until this issue is
+ resolved.
+
++ 2020-06: g_mbus has been removed in favour of the get_mbus_config pad
++ operation which should be used to avoid parsing the remote endpoint
++ configuration.
++
+ - This media driver supports inheriting V4L2 controls to the
+ video capture devices, from the subdevices in the capture device's
+ pipeline. The controls for each capture device are updated in the
diff --git a/target/linux/bcm27xx/patches-5.4/950-0801-media-i2c-adv748x-Adjust-TXA-data-lanes-number.patch b/target/linux/bcm27xx/patches-5.4/950-0801-media-i2c-adv748x-Adjust-TXA-data-lanes-number.patch
new file mode 100644
index 0000000000..b4a9753a84
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0801-media-i2c-adv748x-Adjust-TXA-data-lanes-number.patch
@@ -0,0 +1,123 @@
+From a3fddd6eaaa8740aceeeefea6548d5313412a062 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Tue, 16 Jun 2020 16:12:42 +0200
+Subject: [PATCH] media: i2c: adv748x: Adjust TXA data lanes number
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Upstream https://patchwork.linuxtv.org/patch/64673/
+
+When outputting SD-Core output through the TXA MIPI CSI-2 interface,
+the number of enabled data lanes should be reduced in order to guarantee
+that the two video formats produced by the SD-Core (480i and 576i)
+generate a MIPI CSI-2 link clock frequency compatible with the MIPI D-PHY
+specifications.
+
+Limit the number of enabled data lanes to 2, which is guaranteed to
+support 480i and 576i formats.
+
+Cache the number of enabled data lanes to be able to report it through
+the new get_mbus_config operation.
+
+Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+---
+ drivers/media/i2c/adv748x/adv748x-core.c | 31 ++++++++++++++++++------
+ drivers/media/i2c/adv748x/adv748x.h | 1 +
+ 2 files changed, 25 insertions(+), 7 deletions(-)
+
+--- a/drivers/media/i2c/adv748x/adv748x-core.c
++++ b/drivers/media/i2c/adv748x/adv748x-core.c
+@@ -241,10 +241,10 @@ static int adv748x_power_up_tx(struct ad
+ int ret = 0;
+
+ /* Enable n-lane MIPI */
+- adv748x_write_check(state, page, 0x00, 0x80 | tx->num_lanes, &ret);
++ adv748x_write_check(state, page, 0x00, 0x80 | tx->active_lanes, &ret);
+
+ /* Set Auto DPHY Timing */
+- adv748x_write_check(state, page, 0x00, 0xa0 | tx->num_lanes, &ret);
++ adv748x_write_check(state, page, 0x00, 0xa0 | tx->active_lanes, &ret);
+
+ /* ADI Required Write */
+ if (tx->src == &state->hdmi.sd) {
+@@ -270,7 +270,7 @@ static int adv748x_power_up_tx(struct ad
+ usleep_range(2000, 2500);
+
+ /* Power-up CSI-TX */
+- adv748x_write_check(state, page, 0x00, 0x20 | tx->num_lanes, &ret);
++ adv748x_write_check(state, page, 0x00, 0x20 | tx->active_lanes, &ret);
+ usleep_range(1000, 1500);
+
+ /* ADI Required Writes */
+@@ -292,7 +292,7 @@ static int adv748x_power_down_tx(struct
+ adv748x_write_check(state, page, 0x1e, 0x00, &ret);
+
+ /* Enable n-lane MIPI */
+- adv748x_write_check(state, page, 0x00, 0x80 | tx->num_lanes, &ret);
++ adv748x_write_check(state, page, 0x00, 0x80 | tx->active_lanes, &ret);
+
+ /* i2c_mipi_pll_en - 1'b1 */
+ adv748x_write_check(state, page, 0xda, 0x01, &ret);
+@@ -357,14 +357,29 @@ static int adv748x_link_setup(struct med
+ if (state->afe.tx) {
+ /* AFE Requires TXA enabled, even when output to TXB */
+ io10 |= ADV748X_IO_10_CSI4_EN;
+- if (is_txa(tx))
++ if (is_txa(tx)) {
++ /*
++ * Output from the SD-core (480i and 576i) from the TXA
++ * interface requires reducing the number of enabled
++ * data lanes in order to guarantee a valid link
++ * frequency.
++ */
++ tx->active_lanes = min(tx->num_lanes, 2U);
+ io10 |= ADV748X_IO_10_CSI4_IN_SEL_AFE;
+- else
++ } else {
++ /* TXB has a single data lane, no need to adjust. */
+ io10 |= ADV748X_IO_10_CSI1_EN;
++ }
+ }
+
+- if (state->hdmi.tx)
++ if (state->hdmi.tx) {
++ /*
++ * Restore the number of active lanes, in case we have gone
++ * through an AFE->TXA streaming sessions.
++ */
++ tx->active_lanes = tx->num_lanes;
+ io10 |= ADV748X_IO_10_CSI4_EN;
++ }
+
+ return io_clrset(state, ADV748X_IO_10, io10_mask, io10);
+ }
+@@ -596,6 +611,7 @@ static int adv748x_parse_csi2_lanes(stru
+ }
+
+ state->txa.num_lanes = num_lanes;
++ state->txa.active_lanes = num_lanes;
+ adv_dbg(state, "TXA: using %u lanes\n", state->txa.num_lanes);
+ }
+
+@@ -607,6 +623,7 @@ static int adv748x_parse_csi2_lanes(stru
+ }
+
+ state->txb.num_lanes = num_lanes;
++ state->txb.active_lanes = num_lanes;
+ adv_dbg(state, "TXB: using %u lanes\n", state->txb.num_lanes);
+ }
+
+--- a/drivers/media/i2c/adv748x/adv748x.h
++++ b/drivers/media/i2c/adv748x/adv748x.h
+@@ -79,6 +79,7 @@ struct adv748x_csi2 {
+ unsigned int page;
+ unsigned int port;
+ unsigned int num_lanes;
++ unsigned int active_lanes;
+
+ struct media_pad pads[ADV748X_CSI2_NR_PADS];
+ struct v4l2_ctrl_handler ctrl_hdl;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0802-media-i2c-adv748x-Implement-get_mbus_config.patch b/target/linux/bcm27xx/patches-5.4/950-0802-media-i2c-adv748x-Implement-get_mbus_config.patch
new file mode 100644
index 0000000000..19c4d4c29d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0802-media-i2c-adv748x-Implement-get_mbus_config.patch
@@ -0,0 +1,63 @@
+From 3269627852346852f99244b2650daaa79056b29d Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Tue, 16 Jun 2020 16:12:43 +0200
+Subject: [PATCH] media: i2c: adv748x: Implement get_mbus_config
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Upstream https://patchwork.linuxtv.org/patch/64676/
+
+Implement the newly introduced get_mbus_config operation to report the
+number of currently used data lanes on the MIPI CSI-2 interface.
+
+Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+---
+ drivers/media/i2c/adv748x/adv748x-csi2.c | 31 ++++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+--- a/drivers/media/i2c/adv748x/adv748x-csi2.c
++++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
+@@ -214,9 +214,40 @@ unlock:
+ return ret;
+ }
+
++static int adv748x_csi2_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
++ struct v4l2_mbus_config *config)
++{
++ struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
++
++ if (pad != ADV748X_CSI2_SOURCE)
++ return -EINVAL;
++
++ config->type = V4L2_MBUS_CSI2_DPHY;
++ switch (tx->active_lanes) {
++ case 1:
++ config->flags = V4L2_MBUS_CSI2_1_LANE;
++ break;
++
++ case 2:
++ config->flags = V4L2_MBUS_CSI2_2_LANE;
++ break;
++
++ case 3:
++ config->flags = V4L2_MBUS_CSI2_3_LANE;
++ break;
++
++ case 4:
++ config->flags = V4L2_MBUS_CSI2_4_LANE;
++ break;
++ }
++
++ return 0;
++}
++
+ static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = {
+ .get_fmt = adv748x_csi2_get_format,
+ .set_fmt = adv748x_csi2_set_format,
++ .get_mbus_config = adv748x_csi2_get_mbus_config,
+ };
+
+ /* -----------------------------------------------------------------------------
diff --git a/target/linux/bcm27xx/patches-5.4/950-0803-media-rcar-csi2-Negotiate-data-lanes-number.patch b/target/linux/bcm27xx/patches-5.4/950-0803-media-rcar-csi2-Negotiate-data-lanes-number.patch
new file mode 100644
index 0000000000..f54b33e59c
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0803-media-rcar-csi2-Negotiate-data-lanes-number.patch
@@ -0,0 +1,159 @@
+From 15221304a23fd99c84a6da4b68dc0e887150d1ee Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Tue, 16 Jun 2020 16:12:44 +0200
+Subject: [PATCH] media: rcar-csi2: Negotiate data lanes number
+
+Upstream https://patchwork.linuxtv.org/patch/64675/
+
+Use the newly introduced get_mbus_config() subdevice pad operation to
+retrieve the remote subdevice MIPI CSI-2 bus configuration and configure
+the number of active data lanes accordingly.
+
+In order to be able to call the remote subdevice operation cache the
+index of the remote pad connected to the single CSI-2 input port.
+
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+---
+ drivers/media/platform/rcar-vin/rcar-csi2.c | 74 +++++++++++++++++++--
+ 1 file changed, 67 insertions(+), 7 deletions(-)
+
+--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
++++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
+@@ -362,6 +362,7 @@ struct rcar_csi2 {
+
+ struct v4l2_async_notifier notifier;
+ struct v4l2_subdev *remote;
++ unsigned int remote_pad;
+
+ struct v4l2_mbus_framefmt mf;
+
+@@ -407,13 +408,14 @@ static void rcsi2_exit_standby(struct rc
+ reset_control_deassert(priv->rstc);
+ }
+
+-static int rcsi2_wait_phy_start(struct rcar_csi2 *priv)
++static int rcsi2_wait_phy_start(struct rcar_csi2 *priv,
++ unsigned int active_lanes)
+ {
+ unsigned int timeout;
+
+ /* Wait for the clock and data lanes to enter LP-11 state. */
+ for (timeout = 0; timeout <= 20; timeout++) {
+- const u32 lane_mask = (1 << priv->lanes) - 1;
++ const u32 lane_mask = (1 << active_lanes) - 1;
+
+ if ((rcsi2_read(priv, PHCLM_REG) & PHCLM_STOPSTATECKL) &&
+ (rcsi2_read(priv, PHDLM_REG) & lane_mask) == lane_mask)
+@@ -445,7 +447,8 @@ static int rcsi2_set_phypll(struct rcar_
+ return 0;
+ }
+
+-static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp)
++static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp,
++ unsigned int active_lanes)
+ {
+ struct v4l2_subdev *source;
+ struct v4l2_ctrl *ctrl;
+@@ -470,15 +473,63 @@ static int rcsi2_calc_mbps(struct rcar_c
+ * bps = link_freq * 2
+ */
+ mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * bpp;
+- do_div(mbps, priv->lanes * 1000000);
++ do_div(mbps, active_lanes * 1000000);
+
+ return mbps;
+ }
+
++static int rcsi2_config_active_lanes(struct rcar_csi2 *priv,
++ unsigned int *active_lanes)
++{
++ struct v4l2_mbus_config mbus_config = { 0 };
++ unsigned int num_lanes = (-1U);
++ int ret;
++
++ *active_lanes = priv->lanes;
++ ret = v4l2_subdev_call(priv->remote, pad, get_mbus_config,
++ priv->remote_pad, &mbus_config);
++ if (ret == -ENOIOCTLCMD) {
++ dev_dbg(priv->dev, "No remote mbus configuration available\n");
++ return 0;
++ }
++
++ if (ret) {
++ dev_err(priv->dev, "Failed to get remote mbus configuration\n");
++ return ret;
++ }
++
++ if (mbus_config.type != V4L2_MBUS_CSI2_DPHY) {
++ dev_err(priv->dev, "Unsupported media bus type %u\n",
++ mbus_config.type);
++ return -EINVAL;
++ }
++
++ if (mbus_config.flags & V4L2_MBUS_CSI2_1_LANE)
++ num_lanes = 1;
++ else if (mbus_config.flags & V4L2_MBUS_CSI2_2_LANE)
++ num_lanes = 2;
++ else if (mbus_config.flags & V4L2_MBUS_CSI2_3_LANE)
++ num_lanes = 3;
++ else if (mbus_config.flags & V4L2_MBUS_CSI2_4_LANE)
++ num_lanes = 4;
++
++ if (num_lanes > priv->lanes) {
++ dev_err(priv->dev,
++ "Unsupported mbus config: too many data lanes %u\n",
++ num_lanes);
++ return -EINVAL;
++ }
++
++ *active_lanes = num_lanes;
++
++ return 0;
++}
++
+ static int rcsi2_start_receiver(struct rcar_csi2 *priv)
+ {
+ const struct rcar_csi2_format *format;
+ u32 phycnt, vcdt = 0, vcdt2 = 0, fld = 0;
++ unsigned int active_lanes;
+ unsigned int i;
+ int mbps, ret;
+
+@@ -520,10 +571,18 @@ static int rcsi2_start_receiver(struct r
+ fld |= FLD_FLD_NUM(1);
+ }
+
++ /*
++ * Get the number of active data lanes inspecting the remote mbus
++ * configuration.
++ */
++ ret = rcsi2_config_active_lanes(priv, &active_lanes);
++ if (ret)
++ return ret;
++
+ phycnt = PHYCNT_ENABLECLK;
+- phycnt |= (1 << priv->lanes) - 1;
++ phycnt |= (1 << active_lanes) - 1;
+
+- mbps = rcsi2_calc_mbps(priv, format->bpp);
++ mbps = rcsi2_calc_mbps(priv, format->bpp, active_lanes);
+ if (mbps < 0)
+ return mbps;
+
+@@ -570,7 +629,7 @@ static int rcsi2_start_receiver(struct r
+ rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ);
+ rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ | PHYCNT_RSTZ);
+
+- ret = rcsi2_wait_phy_start(priv);
++ ret = rcsi2_wait_phy_start(priv, active_lanes);
+ if (ret)
+ return ret;
+
+@@ -747,6 +806,7 @@ static int rcsi2_notify_bound(struct v4l
+ }
+
+ priv->remote = subdev;
++ priv->remote_pad = pad;
+
+ dev_dbg(priv->dev, "Bound %s pad: %d\n", subdev->name, pad);
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0804-drivers-media-Remove-the-downstream-version-of-bcm28.patch b/target/linux/bcm27xx/patches-5.4/950-0804-drivers-media-Remove-the-downstream-version-of-bcm28.patch
new file mode 100644
index 0000000000..f4a89a99bd
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0804-drivers-media-Remove-the-downstream-version-of-bcm28.patch
@@ -0,0 +1,3175 @@
+From c6a423459a233669b280e1a4e4836881d77c9ff0 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 23 Jun 2020 10:05:57 +0100
+Subject: [PATCH] drivers: media: Remove the downstream version of
+ bcm2835-unicam
+
+About to be replaced by the upstream version.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/platform/bcm2835/Kconfig | 14 -
+ drivers/media/platform/bcm2835/Makefile | 3 -
+ .../media/platform/bcm2835/bcm2835-unicam.c | 2873 -----------------
+ .../media/platform/bcm2835/vc4-regs-unicam.h | 253 --
+ 4 files changed, 3143 deletions(-)
+ delete mode 100644 drivers/media/platform/bcm2835/Kconfig
+ delete mode 100644 drivers/media/platform/bcm2835/Makefile
+ delete mode 100644 drivers/media/platform/bcm2835/bcm2835-unicam.c
+ delete mode 100644 drivers/media/platform/bcm2835/vc4-regs-unicam.h
+
+--- a/drivers/media/platform/bcm2835/Kconfig
++++ /dev/null
+@@ -1,14 +0,0 @@
+-# Broadcom VideoCore4 V4L2 camera support
+-
+-config VIDEO_BCM2835_UNICAM
+- tristate "Broadcom BCM2835 Unicam video capture driver"
+- depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER
+- depends on ARCH_BCM2835 || COMPILE_TEST
+- select VIDEOBUF2_DMA_CONTIG
+- select V4L2_FWNODE
+- help
+- Say Y here to enable V4L2 subdevice for CSI2 receiver.
+- This is a V4L2 subdevice that interfaces directly to the VC4 peripheral.
+-
+- To compile this driver as a module, choose M here. The module
+- will be called bcm2835-unicam.
+--- a/drivers/media/platform/bcm2835/Makefile
++++ /dev/null
+@@ -1,3 +0,0 @@
+-# Makefile for BCM2835 Unicam driver
+-
+-obj-$(CONFIG_VIDEO_BCM2835_UNICAM) += bcm2835-unicam.o
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ /dev/null
+@@ -1,2873 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0-only
+-/*
+- * BCM2835 Unicam Capture Driver
+- *
+- * Copyright (C) 2017-2020 - Raspberry Pi (Trading) Ltd.
+- *
+- * Dave Stevenson <dave.stevenson@raspberrypi.com>
+- *
+- * Based on TI am437x driver by
+- * Benoit Parrot <bparrot@ti.com>
+- * Lad, Prabhakar <prabhakar.csengg@gmail.com>
+- *
+- * and TI CAL camera interface driver by
+- * Benoit Parrot <bparrot@ti.com>
+- *
+- *
+- * There are two camera drivers in the kernel for BCM283x - this one
+- * and bcm2835-camera (currently in staging).
+- *
+- * This driver directly controls the Unicam peripheral - there is no
+- * involvement with the VideoCore firmware. Unicam receives CSI-2 or
+- * CCP2 data and writes it into SDRAM.
+- * The only potential processing options are to repack Bayer data into an
+- * alternate format, and applying windowing.
+- * The repacking does not shift the data, so can repack V4L2_PIX_FMT_Sxxxx10P
+- * to V4L2_PIX_FMT_Sxxxx10, or V4L2_PIX_FMT_Sxxxx12P to V4L2_PIX_FMT_Sxxxx12,
+- * but not generically up to V4L2_PIX_FMT_Sxxxx16. The driver will add both
+- * formats where the relevant formats are defined, and will automatically
+- * configure the repacking as required.
+- * Support for windowing may be added later.
+- *
+- * It should be possible to connect this driver to any sensor with a
+- * suitable output interface and V4L2 subdevice driver.
+- *
+- * bcm2835-camera uses the VideoCore firmware to control the sensor,
+- * Unicam, ISP, and all tuner control loops. Fully processed frames are
+- * delivered to the driver by the firmware. It only has sensor drivers
+- * for Omnivision OV5647, and Sony IMX219 sensors.
+- *
+- * The two drivers are mutually exclusive for the same Unicam instance.
+- * The VideoCore firmware checks the device tree configuration during boot.
+- * If it finds device tree nodes called csi0 or csi1 it will block the
+- * firmware from accessing the peripheral, and bcm2835-camera will
+- * not be able to stream data.
+- */
+-
+-#include <linux/clk.h>
+-#include <linux/delay.h>
+-#include <linux/device.h>
+-#include <linux/dma-mapping.h>
+-#include <linux/err.h>
+-#include <linux/init.h>
+-#include <linux/interrupt.h>
+-#include <linux/io.h>
+-#include <linux/module.h>
+-#include <linux/of_device.h>
+-#include <linux/of_graph.h>
+-#include <linux/pinctrl/consumer.h>
+-#include <linux/platform_device.h>
+-#include <linux/pm_runtime.h>
+-#include <linux/slab.h>
+-#include <linux/uaccess.h>
+-#include <linux/videodev2.h>
+-
+-#include <media/v4l2-common.h>
+-#include <media/v4l2-ctrls.h>
+-#include <media/v4l2-dev.h>
+-#include <media/v4l2-device.h>
+-#include <media/v4l2-dv-timings.h>
+-#include <media/v4l2-event.h>
+-#include <media/v4l2-ioctl.h>
+-#include <media/v4l2-fwnode.h>
+-#include <media/videobuf2-dma-contig.h>
+-
+-#include "vc4-regs-unicam.h"
+-
+-#define UNICAM_MODULE_NAME "unicam"
+-#define UNICAM_VERSION "0.1.0"
+-
+-static int debug;
+-module_param(debug, int, 0644);
+-MODULE_PARM_DESC(debug, "Debug level 0-3");
+-
+-#define unicam_dbg(level, dev, fmt, arg...) \
+- v4l2_dbg(level, debug, &(dev)->v4l2_dev, fmt, ##arg)
+-#define unicam_info(dev, fmt, arg...) \
+- v4l2_info(&(dev)->v4l2_dev, fmt, ##arg)
+-#define unicam_err(dev, fmt, arg...) \
+- v4l2_err(&(dev)->v4l2_dev, fmt, ##arg)
+-
+-/* To protect against a dodgy sensor driver never returning an error from
+- * enum_mbus_code, set a maximum index value to be used.
+- */
+-#define MAX_ENUM_MBUS_CODE 128
+-
+-/*
+- * Stride is a 16 bit register, but also has to be a multiple of 32.
+- */
+-#define BPL_ALIGNMENT 32
+-#define MAX_BYTESPERLINE ((1 << 16) - BPL_ALIGNMENT)
+-/*
+- * Max width is therefore determined by the max stride divided by
+- * the number of bits per pixel. Take 32bpp as a
+- * worst case.
+- * No imposed limit on the height, so adopt a square image for want
+- * of anything better.
+- */
+-#define MAX_WIDTH (MAX_BYTESPERLINE / 4)
+-#define MAX_HEIGHT MAX_WIDTH
+-/* Define a nominal minimum image size */
+-#define MIN_WIDTH 16
+-#define MIN_HEIGHT 16
+-/* Default size of the embedded buffer */
+-#define UNICAM_EMBEDDED_SIZE 8192
+-
+-/*
+- * Size of the dummy buffer. Can be any size really, but the DMA
+- * allocation works in units of page sizes.
+- */
+-#define DUMMY_BUF_SIZE (PAGE_SIZE)
+-
+-enum pad_types {
+- IMAGE_PAD,
+- METADATA_PAD,
+- MAX_NODES
+-};
+-
+-/*
+- * struct unicam_fmt - Unicam media bus format information
+- * @pixelformat: V4L2 pixel format FCC identifier. 0 if n/a.
+- * @repacked_fourcc: V4L2 pixel format FCC identifier if the data is expanded
+- * out to 16bpp. 0 if n/a.
+- * @code: V4L2 media bus format code.
+- * @depth: Bits per pixel as delivered from the source.
+- * @csi_dt: CSI data type.
+- * @check_variants: Flag to denote that there are multiple mediabus formats
+- * still in the list that could match this V4L2 format.
+- */
+-struct unicam_fmt {
+- u32 fourcc;
+- u32 repacked_fourcc;
+- u32 code;
+- u8 depth;
+- u8 csi_dt;
+- u8 check_variants;
+-};
+-
+-static const struct unicam_fmt formats[] = {
+- /* YUV Formats */
+- {
+- .fourcc = V4L2_PIX_FMT_YUYV,
+- .code = MEDIA_BUS_FMT_YUYV8_2X8,
+- .depth = 16,
+- .csi_dt = 0x1e,
+- .check_variants = 1,
+- }, {
+- .fourcc = V4L2_PIX_FMT_UYVY,
+- .code = MEDIA_BUS_FMT_UYVY8_2X8,
+- .depth = 16,
+- .csi_dt = 0x1e,
+- .check_variants = 1,
+- }, {
+- .fourcc = V4L2_PIX_FMT_YVYU,
+- .code = MEDIA_BUS_FMT_YVYU8_2X8,
+- .depth = 16,
+- .csi_dt = 0x1e,
+- .check_variants = 1,
+- }, {
+- .fourcc = V4L2_PIX_FMT_VYUY,
+- .code = MEDIA_BUS_FMT_VYUY8_2X8,
+- .depth = 16,
+- .csi_dt = 0x1e,
+- .check_variants = 1,
+- }, {
+- .fourcc = V4L2_PIX_FMT_YUYV,
+- .code = MEDIA_BUS_FMT_YUYV8_1X16,
+- .depth = 16,
+- .csi_dt = 0x1e,
+- }, {
+- .fourcc = V4L2_PIX_FMT_UYVY,
+- .code = MEDIA_BUS_FMT_UYVY8_1X16,
+- .depth = 16,
+- .csi_dt = 0x1e,
+- }, {
+- .fourcc = V4L2_PIX_FMT_YVYU,
+- .code = MEDIA_BUS_FMT_YVYU8_1X16,
+- .depth = 16,
+- .csi_dt = 0x1e,
+- }, {
+- .fourcc = V4L2_PIX_FMT_VYUY,
+- .code = MEDIA_BUS_FMT_VYUY8_1X16,
+- .depth = 16,
+- .csi_dt = 0x1e,
+- }, {
+- /* RGB Formats */
+- .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
+- .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
+- .depth = 16,
+- .csi_dt = 0x22,
+- }, {
+- .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
+- .code = MEDIA_BUS_FMT_RGB565_2X8_BE,
+- .depth = 16,
+- .csi_dt = 0x22
+- }, {
+- .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
+- .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
+- .depth = 16,
+- .csi_dt = 0x21,
+- }, {
+- .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
+- .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
+- .depth = 16,
+- .csi_dt = 0x21,
+- }, {
+- .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */
+- .code = MEDIA_BUS_FMT_RGB888_1X24,
+- .depth = 24,
+- .csi_dt = 0x24,
+- }, {
+- .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */
+- .code = MEDIA_BUS_FMT_BGR888_1X24,
+- .depth = 24,
+- .csi_dt = 0x24,
+- }, {
+- .fourcc = V4L2_PIX_FMT_RGB32, /* argb */
+- .code = MEDIA_BUS_FMT_ARGB8888_1X32,
+- .depth = 32,
+- .csi_dt = 0x0,
+- }, {
+- /* Bayer Formats */
+- .fourcc = V4L2_PIX_FMT_SBGGR8,
+- .code = MEDIA_BUS_FMT_SBGGR8_1X8,
+- .depth = 8,
+- .csi_dt = 0x2a,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SGBRG8,
+- .code = MEDIA_BUS_FMT_SGBRG8_1X8,
+- .depth = 8,
+- .csi_dt = 0x2a,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SGRBG8,
+- .code = MEDIA_BUS_FMT_SGRBG8_1X8,
+- .depth = 8,
+- .csi_dt = 0x2a,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SRGGB8,
+- .code = MEDIA_BUS_FMT_SRGGB8_1X8,
+- .depth = 8,
+- .csi_dt = 0x2a,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SBGGR10P,
+- .repacked_fourcc = V4L2_PIX_FMT_SBGGR10,
+- .code = MEDIA_BUS_FMT_SBGGR10_1X10,
+- .depth = 10,
+- .csi_dt = 0x2b,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SGBRG10P,
+- .repacked_fourcc = V4L2_PIX_FMT_SGBRG10,
+- .code = MEDIA_BUS_FMT_SGBRG10_1X10,
+- .depth = 10,
+- .csi_dt = 0x2b,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SGRBG10P,
+- .repacked_fourcc = V4L2_PIX_FMT_SGRBG10,
+- .code = MEDIA_BUS_FMT_SGRBG10_1X10,
+- .depth = 10,
+- .csi_dt = 0x2b,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SRGGB10P,
+- .repacked_fourcc = V4L2_PIX_FMT_SRGGB10,
+- .code = MEDIA_BUS_FMT_SRGGB10_1X10,
+- .depth = 10,
+- .csi_dt = 0x2b,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SBGGR12P,
+- .repacked_fourcc = V4L2_PIX_FMT_SBGGR12,
+- .code = MEDIA_BUS_FMT_SBGGR12_1X12,
+- .depth = 12,
+- .csi_dt = 0x2c,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SGBRG12P,
+- .repacked_fourcc = V4L2_PIX_FMT_SGBRG12,
+- .code = MEDIA_BUS_FMT_SGBRG12_1X12,
+- .depth = 12,
+- .csi_dt = 0x2c,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SGRBG12P,
+- .repacked_fourcc = V4L2_PIX_FMT_SGRBG12,
+- .code = MEDIA_BUS_FMT_SGRBG12_1X12,
+- .depth = 12,
+- .csi_dt = 0x2c,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SRGGB12P,
+- .repacked_fourcc = V4L2_PIX_FMT_SRGGB12,
+- .code = MEDIA_BUS_FMT_SRGGB12_1X12,
+- .depth = 12,
+- .csi_dt = 0x2c,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SBGGR14P,
+- .code = MEDIA_BUS_FMT_SBGGR14_1X14,
+- .depth = 14,
+- .csi_dt = 0x2d,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SGBRG14P,
+- .code = MEDIA_BUS_FMT_SGBRG14_1X14,
+- .depth = 14,
+- .csi_dt = 0x2d,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SGRBG14P,
+- .code = MEDIA_BUS_FMT_SGRBG14_1X14,
+- .depth = 14,
+- .csi_dt = 0x2d,
+- }, {
+- .fourcc = V4L2_PIX_FMT_SRGGB14P,
+- .code = MEDIA_BUS_FMT_SRGGB14_1X14,
+- .depth = 14,
+- .csi_dt = 0x2d,
+- }, {
+- /*
+- * 16 bit Bayer formats could be supported, but there is no CSI2
+- * data_type defined for raw 16, and no sensors that produce it at
+- * present.
+- */
+-
+- /* Greyscale formats */
+- .fourcc = V4L2_PIX_FMT_GREY,
+- .code = MEDIA_BUS_FMT_Y8_1X8,
+- .depth = 8,
+- .csi_dt = 0x2a,
+- }, {
+- .fourcc = V4L2_PIX_FMT_Y10P,
+- .repacked_fourcc = V4L2_PIX_FMT_Y10,
+- .code = MEDIA_BUS_FMT_Y10_1X10,
+- .depth = 10,
+- .csi_dt = 0x2b,
+- }, {
+- /* NB There is no packed V4L2 fourcc for this format. */
+- .repacked_fourcc = V4L2_PIX_FMT_Y12,
+- .code = MEDIA_BUS_FMT_Y12_1X12,
+- .depth = 12,
+- .csi_dt = 0x2c,
+- },
+- /* Embedded data format */
+- {
+- .fourcc = V4L2_META_FMT_SENSOR_DATA,
+- .code = MEDIA_BUS_FMT_SENSOR_DATA,
+- .depth = 8,
+- }
+-};
+-
+-struct unicam_dmaqueue {
+- struct list_head active;
+-};
+-
+-struct unicam_buffer {
+- struct vb2_v4l2_buffer vb;
+- struct list_head list;
+-};
+-
+-struct unicam_cfg {
+- /* peripheral base address */
+- void __iomem *base;
+- /* clock gating base address */
+- void __iomem *clk_gate_base;
+-};
+-
+-#define MAX_POSSIBLE_PIX_FMTS (ARRAY_SIZE(formats))
+-
+-struct unicam_node {
+- int registered;
+- int open;
+- int streaming;
+- unsigned int pad_id;
+- /* Pointer pointing to current v4l2_buffer */
+- struct unicam_buffer *cur_frm;
+- /* Pointer pointing to next v4l2_buffer */
+- struct unicam_buffer *next_frm;
+- /* video capture */
+- const struct unicam_fmt *fmt;
+- /* Used to store current pixel format */
+- struct v4l2_format v_fmt;
+- /* Used to store current mbus frame format */
+- struct v4l2_mbus_framefmt m_fmt;
+- /* Buffer queue used in video-buf */
+- struct vb2_queue buffer_queue;
+- /* Queue of filled frames */
+- struct unicam_dmaqueue dma_queue;
+- /* IRQ lock for DMA queue */
+- spinlock_t dma_queue_lock;
+- /* lock used to access this structure */
+- struct mutex lock;
+- /* Identifies video device for this channel */
+- struct video_device video_dev;
+- /* Pointer to the parent handle */
+- struct unicam_device *dev;
+- struct media_pad pad;
+- struct v4l2_ctrl_handler ctrl_handler;
+- unsigned int embedded_lines;
+- /*
+- * Dummy buffer intended to be used by unicam
+- * if we have no other queued buffers to swap to.
+- */
+- void *dummy_buf_cpu_addr;
+- dma_addr_t dummy_buf_dma_addr;
+-};
+-
+-struct unicam_device {
+- /* V4l2 specific parameters */
+-
+- struct v4l2_fwnode_endpoint endpoint;
+-
+- struct v4l2_async_subdev asd;
+-
+- /* unicam cfg */
+- struct unicam_cfg cfg;
+- /* clock handle */
+- struct clk *clock;
+- /* V4l2 device */
+- struct v4l2_device v4l2_dev;
+- struct media_device mdev;
+-
+- /* parent device */
+- struct platform_device *pdev;
+- /* subdevice async Notifier */
+- struct v4l2_async_notifier notifier;
+- unsigned int sequence;
+-
+- /* ptr to sub device */
+- struct v4l2_subdev *sensor;
+- /* Pad config for the sensor */
+- struct v4l2_subdev_pad_config *sensor_config;
+-
+- unsigned int virtual_channel;
+- enum v4l2_mbus_type bus_type;
+- /*
+- * Stores bus.mipi_csi2.flags for CSI2 sensors, or
+- * bus.mipi_csi1.strobe for CCP2.
+- */
+- unsigned int bus_flags;
+- unsigned int max_data_lanes;
+- unsigned int active_data_lanes;
+- bool sensor_embedded_data;
+-
+- struct unicam_node node[MAX_NODES];
+-};
+-
+-/* Hardware access */
+-#define clk_write(dev, val) writel((val) | 0x5a000000, (dev)->clk_gate_base)
+-#define clk_read(dev) readl((dev)->clk_gate_base)
+-
+-#define reg_read(dev, offset) readl((dev)->base + (offset))
+-#define reg_write(dev, offset, val) writel(val, (dev)->base + (offset))
+-
+-#define reg_read_field(dev, offset, mask) get_field(reg_read((dev), (offset), \
+- mask))
+-
+-static inline int get_field(u32 value, u32 mask)
+-{
+- return (value & mask) >> __ffs(mask);
+-}
+-
+-static inline void set_field(u32 *valp, u32 field, u32 mask)
+-{
+- u32 val = *valp;
+-
+- val &= ~mask;
+- val |= (field << __ffs(mask)) & mask;
+- *valp = val;
+-}
+-
+-static inline void reg_write_field(struct unicam_cfg *dev, u32 offset,
+- u32 field, u32 mask)
+-{
+- u32 val = reg_read((dev), (offset));
+-
+- set_field(&val, field, mask);
+- reg_write((dev), (offset), val);
+-}
+-
+-/* Power management functions */
+-static inline int unicam_runtime_get(struct unicam_device *dev)
+-{
+- return pm_runtime_get_sync(&dev->pdev->dev);
+-}
+-
+-static inline void unicam_runtime_put(struct unicam_device *dev)
+-{
+- pm_runtime_put_sync(&dev->pdev->dev);
+-}
+-
+-/* Format setup functions */
+-static const struct unicam_fmt *find_format_by_code(u32 code)
+-{
+- unsigned int i;
+-
+- for (i = 0; i < ARRAY_SIZE(formats); i++) {
+- if (formats[i].code == code)
+- return &formats[i];
+- }
+-
+- return NULL;
+-}
+-
+-static int check_mbus_format(struct unicam_device *dev,
+- const struct unicam_fmt *format)
+-{
+- struct v4l2_subdev_mbus_code_enum mbus_code;
+- int ret = 0;
+- int i;
+-
+- for (i = 0; !ret && i < MAX_ENUM_MBUS_CODE; i++) {
+- memset(&mbus_code, 0, sizeof(mbus_code));
+- mbus_code.index = i;
+- mbus_code.pad = IMAGE_PAD;
+- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+-
+- ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code,
+- NULL, &mbus_code);
+-
+- if (!ret && mbus_code.code == format->code)
+- return 1;
+- }
+-
+- return 0;
+-}
+-
+-static const struct unicam_fmt *find_format_by_pix(struct unicam_device *dev,
+- u32 pixelformat)
+-{
+- unsigned int i;
+-
+- for (i = 0; i < ARRAY_SIZE(formats); i++) {
+- if (formats[i].fourcc == pixelformat ||
+- formats[i].repacked_fourcc == pixelformat) {
+- if (formats[i].check_variants &&
+- !check_mbus_format(dev, &formats[i]))
+- continue;
+- return &formats[i];
+- }
+- }
+-
+- return NULL;
+-}
+-
+-static inline unsigned int bytes_per_line(u32 width,
+- const struct unicam_fmt *fmt,
+- u32 v4l2_fourcc)
+-{
+- if (v4l2_fourcc == fmt->repacked_fourcc)
+- /* Repacking always goes to 16bpp */
+- return ALIGN(width << 1, BPL_ALIGNMENT);
+- else
+- return ALIGN((width * fmt->depth) >> 3, BPL_ALIGNMENT);
+-}
+-
+-static int __subdev_get_format(struct unicam_device *dev,
+- struct v4l2_mbus_framefmt *fmt, int pad_id)
+-{
+- struct v4l2_subdev_format sd_fmt = {
+- .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+- .pad = pad_id
+- };
+- int ret;
+-
+- ret = v4l2_subdev_call(dev->sensor, pad, get_fmt, dev->sensor_config,
+- &sd_fmt);
+- if (ret < 0)
+- return ret;
+-
+- *fmt = sd_fmt.format;
+-
+- unicam_dbg(1, dev, "%s %dx%d code:%04x\n", __func__,
+- fmt->width, fmt->height, fmt->code);
+-
+- return 0;
+-}
+-
+-static int __subdev_set_format(struct unicam_device *dev,
+- struct v4l2_mbus_framefmt *fmt, int pad_id)
+-{
+- struct v4l2_subdev_format sd_fmt = {
+- .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+- .pad = pad_id
+- };
+- int ret;
+-
+- sd_fmt.format = *fmt;
+-
+- ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_config,
+- &sd_fmt);
+- if (ret < 0)
+- return ret;
+-
+- if (pad_id == IMAGE_PAD)
+- unicam_dbg(1, dev, "%s %dx%d code:%04x\n", __func__, fmt->width,
+- fmt->height, fmt->code);
+- else
+- unicam_dbg(1, dev, "%s Embedded data code:%04x\n", __func__,
+- sd_fmt.format.code);
+-
+- return 0;
+-}
+-
+-static int unicam_calc_format_size_bpl(struct unicam_device *dev,
+- const struct unicam_fmt *fmt,
+- struct v4l2_format *f)
+-{
+- unsigned int min_bytesperline;
+-
+- v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 2,
+- &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 0,
+- 0);
+-
+- min_bytesperline = bytes_per_line(f->fmt.pix.width, fmt,
+- f->fmt.pix.pixelformat);
+-
+- if (f->fmt.pix.bytesperline > min_bytesperline &&
+- f->fmt.pix.bytesperline <= MAX_BYTESPERLINE)
+- f->fmt.pix.bytesperline = ALIGN(f->fmt.pix.bytesperline,
+- BPL_ALIGNMENT);
+- else
+- f->fmt.pix.bytesperline = min_bytesperline;
+-
+- f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+-
+- unicam_dbg(3, dev, "%s: fourcc: %08X size: %dx%d bpl:%d img_size:%d\n",
+- __func__,
+- f->fmt.pix.pixelformat,
+- f->fmt.pix.width, f->fmt.pix.height,
+- f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
+-
+- return 0;
+-}
+-
+-static int unicam_reset_format(struct unicam_node *node)
+-{
+- struct unicam_device *dev = node->dev;
+- struct v4l2_mbus_framefmt mbus_fmt;
+- int ret;
+-
+- if (dev->sensor_embedded_data || node->pad_id != METADATA_PAD) {
+- ret = __subdev_get_format(dev, &mbus_fmt, node->pad_id);
+- if (ret) {
+- unicam_err(dev, "Failed to get_format - ret %d\n", ret);
+- return ret;
+- }
+-
+- if (mbus_fmt.code != node->fmt->code) {
+- unicam_err(dev, "code mismatch - fmt->code %08x, mbus_fmt.code %08x\n",
+- node->fmt->code, mbus_fmt.code);
+- return ret;
+- }
+- }
+-
+- if (node->pad_id == IMAGE_PAD) {
+- v4l2_fill_pix_format(&node->v_fmt.fmt.pix, &mbus_fmt);
+- node->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+- unicam_calc_format_size_bpl(dev, node->fmt, &node->v_fmt);
+- } else {
+- node->v_fmt.type = V4L2_BUF_TYPE_META_CAPTURE;
+- node->v_fmt.fmt.meta.dataformat = V4L2_META_FMT_SENSOR_DATA;
+- if (dev->sensor_embedded_data) {
+- node->v_fmt.fmt.meta.buffersize =
+- mbus_fmt.width * mbus_fmt.height;
+- node->embedded_lines = mbus_fmt.height;
+- } else {
+- node->v_fmt.fmt.meta.buffersize = UNICAM_EMBEDDED_SIZE;
+- node->embedded_lines = 1;
+- }
+- }
+-
+- node->m_fmt = mbus_fmt;
+- return 0;
+-}
+-
+-static void unicam_wr_dma_addr(struct unicam_cfg *cfg, dma_addr_t dmaaddr,
+- unsigned int buffer_size, int pad_id)
+-{
+- dma_addr_t endaddr = dmaaddr + buffer_size;
+-
+- /*
+- * dmaaddr and endaddr should be a 32-bit address with the top two bits
+- * set to 0x3 to signify uncached access through the Videocore memory
+- * controller.
+- */
+- BUG_ON((dmaaddr >> 30) != 0x3 && (endaddr >> 30) != 0x3);
+-
+- if (pad_id == IMAGE_PAD) {
+- reg_write(cfg, UNICAM_IBSA0, dmaaddr);
+- reg_write(cfg, UNICAM_IBEA0, endaddr);
+- } else {
+- reg_write(cfg, UNICAM_DBSA0, dmaaddr);
+- reg_write(cfg, UNICAM_DBEA0, endaddr);
+- }
+-}
+-
+-static inline unsigned int unicam_get_lines_done(struct unicam_device *dev)
+-{
+- dma_addr_t start_addr, cur_addr;
+- unsigned int stride = dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline;
+- struct unicam_buffer *frm = dev->node[IMAGE_PAD].cur_frm;
+-
+- if (!frm)
+- return 0;
+-
+- start_addr = vb2_dma_contig_plane_dma_addr(&frm->vb.vb2_buf, 0);
+- cur_addr = reg_read(&dev->cfg, UNICAM_IBWP);
+- return (unsigned int)(cur_addr - start_addr) / stride;
+-}
+-
+-static inline void unicam_schedule_next_buffer(struct unicam_node *node)
+-{
+- struct unicam_device *dev = node->dev;
+- struct unicam_dmaqueue *dma_q = &node->dma_queue;
+- struct unicam_buffer *buf;
+- unsigned int size;
+- dma_addr_t addr;
+-
+- buf = list_entry(dma_q->active.next, struct unicam_buffer, list);
+- node->next_frm = buf;
+- list_del(&buf->list);
+-
+- addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+- size = (node->pad_id == IMAGE_PAD) ?
+- dev->node[IMAGE_PAD].v_fmt.fmt.pix.sizeimage :
+- dev->node[METADATA_PAD].v_fmt.fmt.meta.buffersize;
+-
+- unicam_wr_dma_addr(&dev->cfg, addr, size, node->pad_id);
+-}
+-
+-static inline void unicam_schedule_dummy_buffer(struct unicam_node *node)
+-{
+- struct unicam_device *dev = node->dev;
+- dma_addr_t addr = node->dummy_buf_dma_addr;
+-
+- unicam_dbg(3, dev, "Scheduling dummy buffer for node %d\n",
+- node->pad_id);
+-
+- unicam_wr_dma_addr(&dev->cfg, addr, DUMMY_BUF_SIZE, node->pad_id);
+- node->next_frm = NULL;
+-}
+-
+-static inline void unicam_process_buffer_complete(struct unicam_node *node,
+- unsigned int sequence)
+-{
+- node->cur_frm->vb.field = node->m_fmt.field;
+- node->cur_frm->vb.sequence = sequence;
+-
+- vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
+-}
+-
+-static int unicam_num_nodes_streaming(struct unicam_device *dev)
+-{
+- return dev->node[IMAGE_PAD].streaming +
+- dev->node[METADATA_PAD].streaming;
+-}
+-
+-static int unicam_all_nodes_streaming(struct unicam_device *dev)
+-{
+- int ret;
+-
+- ret = dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming;
+- ret &= !dev->node[METADATA_PAD].open ||
+- dev->node[METADATA_PAD].streaming;
+- return ret;
+-}
+-
+-static void unicam_queue_event_sof(struct unicam_device *unicam)
+-{
+- struct v4l2_event event = {
+- .type = V4L2_EVENT_FRAME_SYNC,
+- .u.frame_sync.frame_sequence = unicam->sequence,
+- };
+-
+- v4l2_event_queue(&unicam->node[IMAGE_PAD].video_dev, &event);
+-}
+-
+-/*
+- * unicam_isr : ISR handler for unicam capture
+- * @irq: irq number
+- * @dev_id: dev_id ptr
+- *
+- * It changes status of the captured buffer, takes next buffer from the queue
+- * and sets its address in unicam registers
+- */
+-static irqreturn_t unicam_isr(int irq, void *dev)
+-{
+- struct unicam_device *unicam = (struct unicam_device *)dev;
+- struct unicam_cfg *cfg = &unicam->cfg;
+- unsigned int lines_done = unicam_get_lines_done(dev);
+- unsigned int sequence = unicam->sequence;
+- int num_nodes_streaming = unicam_num_nodes_streaming(dev);
+- int ista, sta;
+- u64 ts;
+- int i;
+-
+- sta = reg_read(cfg, UNICAM_STA);
+- /* Write value back to clear the interrupts */
+- reg_write(cfg, UNICAM_STA, sta);
+-
+- ista = reg_read(cfg, UNICAM_ISTA);
+- /* Write value back to clear the interrupts */
+- reg_write(cfg, UNICAM_ISTA, ista);
+-
+- unicam_dbg(3, unicam, "ISR: ISTA: 0x%X, STA: 0x%X, sequence %d, lines done %d",
+- ista, sta, sequence, lines_done);
+-
+- if (!(sta && (UNICAM_IS | UNICAM_PI0)))
+- return IRQ_HANDLED;
+-
+- /*
+- * We must run the frame end handler first. If we have a valid next_frm
+- * and we get a simultaneout FE + FS interrupt, running the FS handler
+- * first would null out the next_frm ptr and we would have lost the
+- * buffer forever.
+- */
+- if (ista & UNICAM_FEI || sta & UNICAM_PI0) {
+- /*
+- * Ensure we have swapped buffers already as we can't
+- * stop the peripheral. If no buffer is available, use a
+- * dummy buffer to dump out frames until we get a new buffer
+- * to use.
+- */
+- for (i = 0; i < num_nodes_streaming; i++) {
+- if (unicam->node[i].cur_frm)
+- unicam_process_buffer_complete(&unicam->node[i],
+- sequence);
+- unicam->node[i].cur_frm = unicam->node[i].next_frm;
+- }
+- unicam->sequence++;
+- }
+-
+- if (ista & UNICAM_FSI) {
+- /*
+- * Timestamp is to be when the first data byte was captured,
+- * aka frame start.
+- */
+- ts = ktime_get_ns();
+- for (i = 0; i < num_nodes_streaming; i++) {
+- if (unicam->node[i].cur_frm)
+- unicam->node[i].cur_frm->vb.vb2_buf.timestamp =
+- ts;
+- /*
+- * Set the next frame output to go to a dummy frame
+- * if we have not managed to obtain another frame
+- * from the queue.
+- */
+- unicam_schedule_dummy_buffer(&unicam->node[i]);
+- }
+-
+- unicam_queue_event_sof(unicam);
+- }
+- /*
+- * Cannot swap buffer at frame end, there may be a race condition
+- * where the HW does not actually swap it if the new frame has
+- * already started.
+- */
+- if (ista & (UNICAM_FSI | UNICAM_LCI) && !(ista & UNICAM_FEI)) {
+- for (i = 0; i < num_nodes_streaming; i++) {
+- spin_lock(&unicam->node[i].dma_queue_lock);
+- if (!list_empty(&unicam->node[i].dma_queue.active) &&
+- !unicam->node[i].next_frm)
+- unicam_schedule_next_buffer(&unicam->node[i]);
+- spin_unlock(&unicam->node[i].dma_queue_lock);
+- }
+- }
+-
+- if (reg_read(&unicam->cfg, UNICAM_ICTL) & UNICAM_FCM) {
+- /* Switch out of trigger mode if selected */
+- reg_write_field(&unicam->cfg, UNICAM_ICTL, 1, UNICAM_TFC);
+- reg_write_field(&unicam->cfg, UNICAM_ICTL, 0, UNICAM_FCM);
+- }
+- return IRQ_HANDLED;
+-}
+-
+-static int unicam_querycap(struct file *file, void *priv,
+- struct v4l2_capability *cap)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+-
+- strlcpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver));
+- strlcpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card));
+-
+- snprintf(cap->bus_info, sizeof(cap->bus_info),
+- "platform:%s", dev->v4l2_dev.name);
+-
+- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+- V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS |
+- V4L2_CAP_META_CAPTURE;
+-
+- if (node->pad_id == IMAGE_PAD)
+- cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+- else
+- cap->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING;
+-
+- return 0;
+-}
+-
+-static int unicam_enum_fmt_vid_cap(struct file *file, void *priv,
+- struct v4l2_fmtdesc *f)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- struct v4l2_subdev_mbus_code_enum mbus_code;
+- const struct unicam_fmt *fmt = NULL;
+- int index = 0;
+- int ret = 0;
+- int i;
+-
+- if (node->pad_id == METADATA_PAD)
+- return -EINVAL;
+-
+- for (i = 0; !ret && i < MAX_ENUM_MBUS_CODE; i++) {
+- memset(&mbus_code, 0, sizeof(mbus_code));
+- mbus_code.index = i;
+- mbus_code.pad = IMAGE_PAD;
+- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+-
+- ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code,
+- NULL, &mbus_code);
+- if (ret < 0) {
+- unicam_dbg(2, dev,
+- "subdev->enum_mbus_code idx %d returned %d - index invalid\n",
+- i, ret);
+- return -EINVAL;
+- }
+-
+- fmt = find_format_by_code(mbus_code.code);
+- if (fmt) {
+- if (fmt->fourcc) {
+- if (index == f->index) {
+- f->pixelformat = fmt->fourcc;
+- break;
+- }
+- index++;
+- }
+- if (fmt->repacked_fourcc) {
+- if (index == f->index) {
+- f->pixelformat = fmt->repacked_fourcc;
+- break;
+- }
+- index++;
+- }
+- }
+- }
+-
+- return 0;
+-}
+-
+-static int unicam_g_fmt_vid_cap(struct file *file, void *priv,
+- struct v4l2_format *f)
+-{
+- struct v4l2_mbus_framefmt mbus_fmt = {0};
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- const struct unicam_fmt *fmt = NULL;
+- int ret;
+-
+- if (node->pad_id != IMAGE_PAD)
+- return -EINVAL;
+-
+- /*
+- * If a flip has occurred in the sensor, the fmt code might have
+- * changed. So we will need to re-fetch the format from the subdevice.
+- */
+- ret = __subdev_get_format(dev, &mbus_fmt, node->pad_id);
+- if (ret)
+- return -EINVAL;
+-
+- /* Find the V4L2 format from mbus code. We must match a known format. */
+- fmt = find_format_by_code(mbus_fmt.code);
+- if (!fmt)
+- return -EINVAL;
+-
+- if (node->fmt != fmt) {
+- /*
+- * The sensor format has changed so the pixelformat needs to
+- * be updated. Try and retain the packed/unpacked choice if
+- * at all possible.
+- */
+- if (node->fmt->repacked_fourcc ==
+- node->v_fmt.fmt.pix.pixelformat)
+- /* Using the repacked format */
+- node->v_fmt.fmt.pix.pixelformat = fmt->repacked_fourcc;
+- else
+- /* Using the native format */
+- node->v_fmt.fmt.pix.pixelformat = fmt->fourcc;
+-
+- node->fmt = fmt;
+- }
+-
+- *f = node->v_fmt;
+-
+- return 0;
+-}
+-
+-static
+-const struct unicam_fmt *get_first_supported_format(struct unicam_device *dev)
+-{
+- struct v4l2_subdev_mbus_code_enum mbus_code;
+- const struct unicam_fmt *fmt = NULL;
+- int ret = 0;
+- int j;
+-
+- for (j = 0; ret != -EINVAL && ret != -ENOIOCTLCMD; ++j) {
+- memset(&mbus_code, 0, sizeof(mbus_code));
+- mbus_code.index = j;
+- mbus_code.pad = IMAGE_PAD;
+- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+-
+- ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, NULL,
+- &mbus_code);
+- if (ret < 0) {
+- unicam_dbg(2, dev,
+- "subdev->enum_mbus_code idx %d returned %d - continue\n",
+- j, ret);
+- continue;
+- }
+-
+- unicam_dbg(2, dev, "subdev %s: code: 0x%08x idx: %d\n",
+- dev->sensor->name, mbus_code.code, j);
+-
+- fmt = find_format_by_code(mbus_code.code);
+- unicam_dbg(2, dev, "fmt 0x%08x returned as %p, V4L2 FOURCC 0x%08x, csi_dt 0x%02x\n",
+- mbus_code.code, fmt, fmt ? fmt->fourcc : 0,
+- fmt ? fmt->csi_dt : 0);
+- if (fmt)
+- return fmt;
+- }
+-
+- return NULL;
+-}
+-
+-static int unicam_try_fmt_vid_cap(struct file *file, void *priv,
+- struct v4l2_format *f)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- struct v4l2_subdev_format sd_fmt = {
+- .which = V4L2_SUBDEV_FORMAT_TRY,
+- .pad = IMAGE_PAD
+- };
+- struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format;
+- const struct unicam_fmt *fmt;
+- int ret;
+-
+- if (node->pad_id == METADATA_PAD)
+- return -EINVAL;
+-
+- fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat);
+- if (!fmt) {
+- /* Pixel format not supported by unicam. Choose the first
+- * supported format, and let the sensor choose something else.
+- */
+- unicam_dbg(3, dev, "Fourcc format (0x%08x) not found. Use first format.\n",
+- f->fmt.pix.pixelformat);
+-
+- fmt = &formats[0];
+- f->fmt.pix.pixelformat = fmt->fourcc;
+- }
+-
+- v4l2_fill_mbus_format(mbus_fmt, &f->fmt.pix, fmt->code);
+- /*
+- * No support for receiving interlaced video, so never
+- * request it from the sensor subdev.
+- */
+- mbus_fmt->field = V4L2_FIELD_NONE;
+-
+- ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_config,
+- &sd_fmt);
+- if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)
+- return ret;
+-
+- if (mbus_fmt->field != V4L2_FIELD_NONE)
+- unicam_info(dev, "Sensor trying to send interlaced video - results may be unpredictable\n");
+-
+- v4l2_fill_pix_format(&f->fmt.pix, &sd_fmt.format);
+- if (mbus_fmt->code != fmt->code) {
+- /* Sensor has returned an alternate format */
+- fmt = find_format_by_code(mbus_fmt->code);
+- if (!fmt) {
+- /* The alternate format is one unicam can't support.
+- * Find the first format that is supported by both, and
+- * then set that.
+- */
+- fmt = get_first_supported_format(dev);
+- mbus_fmt->code = fmt->code;
+-
+- ret = v4l2_subdev_call(dev->sensor, pad, set_fmt,
+- dev->sensor_config, &sd_fmt);
+- if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)
+- return ret;
+-
+- if (mbus_fmt->field != V4L2_FIELD_NONE)
+- unicam_info(dev, "Sensor trying to send interlaced video - results may be unpredictable\n");
+-
+- v4l2_fill_pix_format(&f->fmt.pix, &sd_fmt.format);
+-
+- if (mbus_fmt->code != fmt->code) {
+- /* We've set a format that the sensor reports
+- * as being supported, but it refuses to set it.
+- * Not much else we can do.
+- * Assume that the sensor driver may accept the
+- * format when it is set (rather than tried).
+- */
+- unicam_err(dev, "Sensor won't accept default format, and Unicam can't support sensor default\n");
+- }
+- }
+-
+- if (fmt->fourcc)
+- f->fmt.pix.pixelformat = fmt->fourcc;
+- else
+- f->fmt.pix.pixelformat = fmt->repacked_fourcc;
+- }
+-
+- return unicam_calc_format_size_bpl(dev, fmt, f);
+-}
+-
+-static int unicam_s_fmt_vid_cap(struct file *file, void *priv,
+- struct v4l2_format *f)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- struct vb2_queue *q = &node->buffer_queue;
+- struct v4l2_mbus_framefmt mbus_fmt = {0};
+- const struct unicam_fmt *fmt;
+- int ret;
+-
+- if (vb2_is_busy(q))
+- return -EBUSY;
+-
+- ret = unicam_try_fmt_vid_cap(file, priv, f);
+- if (ret < 0)
+- return ret;
+-
+- fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat);
+- if (!fmt) {
+- /* Unknown pixel format - adopt a default.
+- * This shouldn't happen as try_fmt should have resolved any
+- * issues first.
+- */
+- fmt = get_first_supported_format(dev);
+- if (!fmt)
+- /* It shouldn't be possible to get here with no
+- * supported formats
+- */
+- return -EINVAL;
+- f->fmt.pix.pixelformat = fmt->fourcc;
+- return -EINVAL;
+- }
+-
+- v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, fmt->code);
+-
+- ret = __subdev_set_format(dev, &mbus_fmt, node->pad_id);
+- if (ret) {
+- unicam_dbg(3, dev, "%s __subdev_set_format failed %d\n",
+- __func__, ret);
+- return ret;
+- }
+-
+- /* Just double check nothing has gone wrong */
+- if (mbus_fmt.code != fmt->code) {
+- unicam_dbg(3, dev,
+- "%s subdev changed format on us, this should not happen\n",
+- __func__);
+- return -EINVAL;
+- }
+-
+- node->fmt = fmt;
+- node->v_fmt.fmt.pix.pixelformat = f->fmt.pix.pixelformat;
+- node->v_fmt.fmt.pix.bytesperline = f->fmt.pix.bytesperline;
+- unicam_reset_format(node);
+-
+- unicam_dbg(3, dev,
+- "%s %dx%d, mbus_fmt 0x%08X, V4L2 pix 0x%08X.\n",
+- __func__, node->v_fmt.fmt.pix.width,
+- node->v_fmt.fmt.pix.height, mbus_fmt.code,
+- node->v_fmt.fmt.pix.pixelformat);
+-
+- *f = node->v_fmt;
+-
+- return 0;
+-}
+-
+-static int unicam_enum_fmt_meta_cap(struct file *file, void *priv,
+- struct v4l2_fmtdesc *f)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- struct v4l2_subdev_mbus_code_enum mbus_code;
+- const struct unicam_fmt *fmt = NULL;
+- int ret = 0;
+-
+- if (node->pad_id != METADATA_PAD || f->index != 0)
+- return -EINVAL;
+-
+- if (dev->sensor_embedded_data) {
+- memset(&mbus_code, 0, sizeof(mbus_code));
+- mbus_code.index = f->index;
+- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+- mbus_code.pad = METADATA_PAD;
+-
+- ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, NULL,
+- &mbus_code);
+- if (ret < 0) {
+- unicam_dbg(2, dev,
+- "subdev->enum_mbus_code idx 0 returned %d - index invalid\n",
+- ret);
+- return -EINVAL;
+- }
+- } else {
+- mbus_code.code = MEDIA_BUS_FMT_SENSOR_DATA;
+- }
+-
+- fmt = find_format_by_code(mbus_code.code);
+- if (fmt)
+- f->pixelformat = fmt->fourcc;
+-
+- return 0;
+-}
+-
+-static int unicam_g_fmt_meta_cap(struct file *file, void *priv,
+- struct v4l2_format *f)
+-{
+- struct unicam_node *node = video_drvdata(file);
+-
+- if (node->pad_id != METADATA_PAD)
+- return -EINVAL;
+-
+- *f = node->v_fmt;
+-
+- return 0;
+-}
+-
+-static int unicam_try_fmt_meta_cap(struct file *file, void *priv,
+- struct v4l2_format *f)
+-{
+- struct unicam_node *node = video_drvdata(file);
+-
+- if (node->pad_id != METADATA_PAD)
+- return -EINVAL;
+-
+- *f = node->v_fmt;
+-
+- return 0;
+-}
+-
+-static int unicam_s_fmt_meta_cap(struct file *file, void *priv,
+- struct v4l2_format *f)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- struct v4l2_mbus_framefmt mbus_fmt = { 0 };
+- const struct unicam_fmt *fmt;
+- int ret;
+-
+- if (node->pad_id == IMAGE_PAD)
+- return -EINVAL;
+-
+- if (dev->sensor_embedded_data) {
+- fmt = find_format_by_pix(dev, f->fmt.meta.dataformat);
+- if (!fmt) {
+- unicam_err(dev, "unknown format: V4L2 pix 0x%08x\n",
+- f->fmt.meta.dataformat);
+- return -EINVAL;
+- }
+- mbus_fmt.code = fmt->code;
+- ret = __subdev_set_format(dev, &mbus_fmt, node->pad_id);
+- if (ret) {
+- unicam_dbg(3, dev, "%s __subdev_set_format failed %d\n",
+- __func__, ret);
+- return ret;
+- }
+- }
+-
+- *f = node->v_fmt;
+-
+- unicam_dbg(3, dev, "%s size %d, V4L2 pix 0x%08x\n",
+- __func__, node->v_fmt.fmt.meta.buffersize,
+- node->v_fmt.fmt.meta.dataformat);
+-
+- return 0;
+-}
+-
+-static int unicam_queue_setup(struct vb2_queue *vq,
+- unsigned int *nbuffers,
+- unsigned int *nplanes,
+- unsigned int sizes[],
+- struct device *alloc_devs[])
+-{
+- struct unicam_node *node = vb2_get_drv_priv(vq);
+- struct unicam_device *dev = node->dev;
+- unsigned int size = node->pad_id == IMAGE_PAD ?
+- node->v_fmt.fmt.pix.sizeimage :
+- node->v_fmt.fmt.meta.buffersize;
+-
+- if (vq->num_buffers + *nbuffers < 3)
+- *nbuffers = 3 - vq->num_buffers;
+-
+- if (*nplanes) {
+- if (sizes[0] < size) {
+- unicam_err(dev, "sizes[0] %i < size %u\n", sizes[0],
+- size);
+- return -EINVAL;
+- }
+- size = sizes[0];
+- }
+-
+- *nplanes = 1;
+- sizes[0] = size;
+-
+- return 0;
+-}
+-
+-static int unicam_buffer_prepare(struct vb2_buffer *vb)
+-{
+- struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue);
+- struct unicam_device *dev = node->dev;
+- struct unicam_buffer *buf = container_of(vb, struct unicam_buffer,
+- vb.vb2_buf);
+- unsigned long size;
+-
+- if (WARN_ON(!node->fmt))
+- return -EINVAL;
+-
+- size = node->pad_id == IMAGE_PAD ? node->v_fmt.fmt.pix.sizeimage :
+- node->v_fmt.fmt.meta.buffersize;
+- if (vb2_plane_size(vb, 0) < size) {
+- unicam_err(dev, "data will not fit into plane (%lu < %lu)\n",
+- vb2_plane_size(vb, 0), size);
+- return -EINVAL;
+- }
+-
+- vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
+- return 0;
+-}
+-
+-static void unicam_buffer_queue(struct vb2_buffer *vb)
+-{
+- struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue);
+- struct unicam_buffer *buf = container_of(vb, struct unicam_buffer,
+- vb.vb2_buf);
+- struct unicam_dmaqueue *dma_queue = &node->dma_queue;
+- unsigned long flags = 0;
+-
+- spin_lock_irqsave(&node->dma_queue_lock, flags);
+- list_add_tail(&buf->list, &dma_queue->active);
+- spin_unlock_irqrestore(&node->dma_queue_lock, flags);
+-}
+-
+-static void unicam_set_packing_config(struct unicam_device *dev)
+-{
+- int pack, unpack;
+- u32 val;
+-
+- if (dev->node[IMAGE_PAD].v_fmt.fmt.pix.pixelformat ==
+- dev->node[IMAGE_PAD].fmt->fourcc) {
+- unpack = UNICAM_PUM_NONE;
+- pack = UNICAM_PPM_NONE;
+- } else {
+- switch (dev->node[IMAGE_PAD].fmt->depth) {
+- case 8:
+- unpack = UNICAM_PUM_UNPACK8;
+- break;
+- case 10:
+- unpack = UNICAM_PUM_UNPACK10;
+- break;
+- case 12:
+- unpack = UNICAM_PUM_UNPACK12;
+- break;
+- case 14:
+- unpack = UNICAM_PUM_UNPACK14;
+- break;
+- case 16:
+- unpack = UNICAM_PUM_UNPACK16;
+- break;
+- default:
+- unpack = UNICAM_PUM_NONE;
+- break;
+- }
+-
+- /* Repacking is always to 16bpp */
+- pack = UNICAM_PPM_PACK16;
+- }
+-
+- val = 0;
+- set_field(&val, unpack, UNICAM_PUM_MASK);
+- set_field(&val, pack, UNICAM_PPM_MASK);
+- reg_write(&dev->cfg, UNICAM_IPIPE, val);
+-}
+-
+-static void unicam_cfg_image_id(struct unicam_device *dev)
+-{
+- struct unicam_cfg *cfg = &dev->cfg;
+-
+- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
+- /* CSI2 mode */
+- reg_write(cfg, UNICAM_IDI0,
+- (dev->virtual_channel << 6) |
+- dev->node[IMAGE_PAD].fmt->csi_dt);
+- } else {
+- /* CCP2 mode */
+- reg_write(cfg, UNICAM_IDI0,
+- 0x80 | dev->node[IMAGE_PAD].fmt->csi_dt);
+- }
+-}
+-
+-static void unicam_enable_ed(struct unicam_device *dev)
+-{
+- struct unicam_cfg *cfg = &dev->cfg;
+- u32 val = reg_read(cfg, UNICAM_DCS);
+-
+- set_field(&val, 2, UNICAM_EDL_MASK);
+- /* Do not wrap at the end of the embedded data buffer */
+- set_field(&val, 0, UNICAM_DBOB);
+-
+- reg_write(cfg, UNICAM_DCS, val);
+-}
+-
+-static void unicam_start_rx(struct unicam_device *dev, dma_addr_t *addr)
+-{
+- struct unicam_cfg *cfg = &dev->cfg;
+- int line_int_freq = dev->node[IMAGE_PAD].v_fmt.fmt.pix.height >> 2;
+- unsigned int size, i;
+- u32 val;
+-
+- if (line_int_freq < 128)
+- line_int_freq = 128;
+-
+- /* Enable lane clocks */
+- val = 1;
+- for (i = 0; i < dev->active_data_lanes; i++)
+- val = val << 2 | 1;
+- clk_write(cfg, val);
+-
+- /* Basic init */
+- reg_write(cfg, UNICAM_CTRL, UNICAM_MEM);
+-
+- /* Enable analogue control, and leave in reset. */
+- val = UNICAM_AR;
+- set_field(&val, 7, UNICAM_CTATADJ_MASK);
+- set_field(&val, 7, UNICAM_PTATADJ_MASK);
+- reg_write(cfg, UNICAM_ANA, val);
+- usleep_range(1000, 2000);
+-
+- /* Come out of reset */
+- reg_write_field(cfg, UNICAM_ANA, 0, UNICAM_AR);
+-
+- /* Peripheral reset */
+- reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_CPR);
+- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPR);
+-
+- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPE);
+-
+- /* Enable Rx control. */
+- val = reg_read(cfg, UNICAM_CTRL);
+- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
+- set_field(&val, UNICAM_CPM_CSI2, UNICAM_CPM_MASK);
+- set_field(&val, UNICAM_DCM_STROBE, UNICAM_DCM_MASK);
+- } else {
+- set_field(&val, UNICAM_CPM_CCP2, UNICAM_CPM_MASK);
+- set_field(&val, dev->bus_flags, UNICAM_DCM_MASK);
+- }
+- /* Packet framer timeout */
+- set_field(&val, 0xf, UNICAM_PFT_MASK);
+- set_field(&val, 128, UNICAM_OET_MASK);
+- reg_write(cfg, UNICAM_CTRL, val);
+-
+- reg_write(cfg, UNICAM_IHWIN, 0);
+- reg_write(cfg, UNICAM_IVWIN, 0);
+-
+- /* AXI bus access QoS setup */
+- val = reg_read(&dev->cfg, UNICAM_PRI);
+- set_field(&val, 0, UNICAM_BL_MASK);
+- set_field(&val, 0, UNICAM_BS_MASK);
+- set_field(&val, 0xe, UNICAM_PP_MASK);
+- set_field(&val, 8, UNICAM_NP_MASK);
+- set_field(&val, 2, UNICAM_PT_MASK);
+- set_field(&val, 1, UNICAM_PE);
+- reg_write(cfg, UNICAM_PRI, val);
+-
+- reg_write_field(cfg, UNICAM_ANA, 0, UNICAM_DDL);
+-
+- /* Always start in trigger frame capture mode (UNICAM_FCM set) */
+- val = UNICAM_FSIE | UNICAM_FEIE | UNICAM_FCM | UNICAM_IBOB;
+- set_field(&val, line_int_freq, UNICAM_LCIE_MASK);
+- reg_write(cfg, UNICAM_ICTL, val);
+- reg_write(cfg, UNICAM_STA, UNICAM_STA_MASK_ALL);
+- reg_write(cfg, UNICAM_ISTA, UNICAM_ISTA_MASK_ALL);
+-
+- /* tclk_term_en */
+- reg_write_field(cfg, UNICAM_CLT, 2, UNICAM_CLT1_MASK);
+- /* tclk_settle */
+- reg_write_field(cfg, UNICAM_CLT, 6, UNICAM_CLT2_MASK);
+- /* td_term_en */
+- reg_write_field(cfg, UNICAM_DLT, 2, UNICAM_DLT1_MASK);
+- /* ths_settle */
+- reg_write_field(cfg, UNICAM_DLT, 6, UNICAM_DLT2_MASK);
+- /* trx_enable */
+- reg_write_field(cfg, UNICAM_DLT, 0, UNICAM_DLT3_MASK);
+-
+- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_SOE);
+-
+- /* Packet compare setup - required to avoid missing frame ends */
+- val = 0;
+- set_field(&val, 1, UNICAM_PCE);
+- set_field(&val, 1, UNICAM_GI);
+- set_field(&val, 1, UNICAM_CPH);
+- set_field(&val, 0, UNICAM_PCVC_MASK);
+- set_field(&val, 1, UNICAM_PCDT_MASK);
+- reg_write(cfg, UNICAM_CMP0, val);
+-
+- /* Enable clock lane and set up terminations */
+- val = 0;
+- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
+- /* CSI2 */
+- set_field(&val, 1, UNICAM_CLE);
+- set_field(&val, 1, UNICAM_CLLPE);
+- if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) {
+- set_field(&val, 1, UNICAM_CLTRE);
+- set_field(&val, 1, UNICAM_CLHSE);
+- }
+- } else {
+- /* CCP2 */
+- set_field(&val, 1, UNICAM_CLE);
+- set_field(&val, 1, UNICAM_CLHSE);
+- set_field(&val, 1, UNICAM_CLTRE);
+- }
+- reg_write(cfg, UNICAM_CLK, val);
+-
+- /*
+- * Enable required data lanes with appropriate terminations.
+- * The same value needs to be written to UNICAM_DATn registers for
+- * the active lanes, and 0 for inactive ones.
+- */
+- val = 0;
+- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
+- /* CSI2 */
+- set_field(&val, 1, UNICAM_DLE);
+- set_field(&val, 1, UNICAM_DLLPE);
+- if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) {
+- set_field(&val, 1, UNICAM_DLTRE);
+- set_field(&val, 1, UNICAM_DLHSE);
+- }
+- } else {
+- /* CCP2 */
+- set_field(&val, 1, UNICAM_DLE);
+- set_field(&val, 1, UNICAM_DLHSE);
+- set_field(&val, 1, UNICAM_DLTRE);
+- }
+- reg_write(cfg, UNICAM_DAT0, val);
+-
+- if (dev->active_data_lanes == 1)
+- val = 0;
+- reg_write(cfg, UNICAM_DAT1, val);
+-
+- if (dev->max_data_lanes > 2) {
+- /*
+- * Registers UNICAM_DAT2 and UNICAM_DAT3 only valid if the
+- * instance supports more than 2 data lanes.
+- */
+- if (dev->active_data_lanes == 2)
+- val = 0;
+- reg_write(cfg, UNICAM_DAT2, val);
+-
+- if (dev->active_data_lanes == 3)
+- val = 0;
+- reg_write(cfg, UNICAM_DAT3, val);
+- }
+-
+- reg_write(&dev->cfg, UNICAM_IBLS,
+- dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline);
+- size = dev->node[IMAGE_PAD].v_fmt.fmt.pix.sizeimage;
+- unicam_wr_dma_addr(&dev->cfg, addr[IMAGE_PAD], size, IMAGE_PAD);
+- unicam_set_packing_config(dev);
+- unicam_cfg_image_id(dev);
+-
+- val = reg_read(cfg, UNICAM_MISC);
+- set_field(&val, 1, UNICAM_FL0);
+- set_field(&val, 1, UNICAM_FL1);
+- reg_write(cfg, UNICAM_MISC, val);
+-
+- if (dev->node[METADATA_PAD].streaming && dev->sensor_embedded_data) {
+- size = dev->node[METADATA_PAD].v_fmt.fmt.meta.buffersize;
+- unicam_enable_ed(dev);
+- unicam_wr_dma_addr(&dev->cfg, addr[METADATA_PAD], size,
+- METADATA_PAD);
+- }
+-
+- /* Enable peripheral */
+- reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_CPE);
+-
+- /* Load image pointers */
+- reg_write_field(cfg, UNICAM_ICTL, 1, UNICAM_LIP_MASK);
+-
+- /* Load embedded data buffer pointers if needed */
+- if (dev->node[METADATA_PAD].streaming && dev->sensor_embedded_data)
+- reg_write_field(cfg, UNICAM_DCS, 1, UNICAM_LDP);
+-
+- /*
+- * Enable trigger only for the first frame to
+- * sync correctly to the FS from the source.
+- */
+- reg_write_field(cfg, UNICAM_ICTL, 1, UNICAM_TFC);
+-}
+-
+-static void unicam_disable(struct unicam_device *dev)
+-{
+- struct unicam_cfg *cfg = &dev->cfg;
+-
+- /* Analogue lane control disable */
+- reg_write_field(cfg, UNICAM_ANA, 1, UNICAM_DDL);
+-
+- /* Stop the output engine */
+- reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_SOE);
+-
+- /* Disable the data lanes. */
+- reg_write(cfg, UNICAM_DAT0, 0);
+- reg_write(cfg, UNICAM_DAT1, 0);
+-
+- if (dev->max_data_lanes > 2) {
+- reg_write(cfg, UNICAM_DAT2, 0);
+- reg_write(cfg, UNICAM_DAT3, 0);
+- }
+-
+- /* Peripheral reset */
+- reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_CPR);
+- usleep_range(50, 100);
+- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPR);
+-
+- /* Disable peripheral */
+- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPE);
+-
+- /* Clear ED setup */
+- reg_write(cfg, UNICAM_DCS, 0);
+-
+- /* Disable all lane clocks */
+- clk_write(cfg, 0);
+-}
+-
+-static int unicam_start_streaming(struct vb2_queue *vq, unsigned int count)
+-{
+- struct unicam_node *node = vb2_get_drv_priv(vq);
+- struct unicam_device *dev = node->dev;
+- struct unicam_buffer *buf;
+- dma_addr_t buffer_addr[MAX_NODES] = { 0 };
+- int num_nodes_streaming;
+- unsigned long flags;
+- int ret, i;
+-
+- node->streaming = 1;
+- if (!unicam_all_nodes_streaming(dev)) {
+- unicam_dbg(3, dev, "Not all nodes are streaming yet.");
+- return 0;
+- }
+-
+- dev->sequence = 0;
+- ret = unicam_runtime_get(dev);
+- if (ret < 0) {
+- unicam_dbg(3, dev, "unicam_runtime_get failed\n");
+- return ret;
+- }
+-
+- dev->active_data_lanes = dev->max_data_lanes;
+- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY &&
+- v4l2_subdev_has_op(dev->sensor, video, g_mbus_config)) {
+- struct v4l2_mbus_config mbus_config;
+-
+- ret = v4l2_subdev_call(dev->sensor, video, g_mbus_config,
+- &mbus_config);
+- if (ret < 0) {
+- unicam_dbg(3, dev, "g_mbus_config failed\n");
+- goto err_pm_put;
+- }
+-
+- dev->active_data_lanes =
+- (mbus_config.flags & V4L2_MBUS_CSI2_LANE_MASK) >>
+- __ffs(V4L2_MBUS_CSI2_LANE_MASK);
+- if (!dev->active_data_lanes)
+- dev->active_data_lanes = dev->max_data_lanes;
+- }
+- if (dev->active_data_lanes > dev->max_data_lanes) {
+- unicam_err(dev, "Device has requested %u data lanes, which is >%u configured in DT\n",
+- dev->active_data_lanes, dev->max_data_lanes);
+- ret = -EINVAL;
+- goto err_pm_put;
+- }
+-
+- unicam_dbg(1, dev, "Running with %u data lanes\n",
+- dev->active_data_lanes);
+-
+- ret = clk_set_rate(dev->clock, 100 * 1000 * 1000);
+- if (ret) {
+- unicam_err(dev, "failed to set up clock\n");
+- goto err_pm_put;
+- }
+-
+- ret = clk_prepare_enable(dev->clock);
+- if (ret) {
+- unicam_err(dev, "Failed to enable CSI clock: %d\n", ret);
+- goto err_pm_put;
+- }
+-
+- num_nodes_streaming = unicam_num_nodes_streaming(dev);
+- for (i = 0; i < num_nodes_streaming; i++) {
+- spin_lock_irqsave(&dev->node[i].dma_queue_lock, flags);
+- buf = list_entry(dev->node[i].dma_queue.active.next,
+- struct unicam_buffer, list);
+- dev->node[i].cur_frm = buf;
+- dev->node[i].next_frm = buf;
+- list_del(&buf->list);
+- spin_unlock_irqrestore(&dev->node[i].dma_queue_lock, flags);
+- buffer_addr[i] =
+- vb2_dma_contig_plane_dma_addr(&dev->node[i].cur_frm->vb.vb2_buf,
+- 0);
+- }
+-
+- unicam_start_rx(dev, buffer_addr);
+-
+- ret = v4l2_subdev_call(dev->sensor, video, s_stream, 1);
+- if (ret < 0) {
+- unicam_err(dev, "stream on failed in subdev\n");
+- goto err_disable_unicam;
+- }
+-
+- return 0;
+-
+-err_disable_unicam:
+- node->streaming = 0;
+- unicam_disable(dev);
+- clk_disable_unprepare(dev->clock);
+-err_pm_put:
+- unicam_runtime_put(dev);
+-
+- return ret;
+-}
+-
+-static void unicam_stop_streaming(struct vb2_queue *vq)
+-{
+- struct unicam_node *node = vb2_get_drv_priv(vq);
+- struct unicam_device *dev = node->dev;
+- struct unicam_dmaqueue *dma_q = &node->dma_queue;
+- struct unicam_buffer *buf, *tmp;
+- unsigned long flags;
+-
+- node->streaming = 0;
+-
+- if (node->pad_id == IMAGE_PAD) {
+- /* Stop streaming the sensor and disable the peripheral.
+- * We cannot continue streaming embedded data with the
+- * image pad disabled.
+- */
+- if (v4l2_subdev_call(dev->sensor, video, s_stream, 0) < 0)
+- unicam_err(dev, "stream off failed in subdev\n");
+-
+- unicam_disable(dev);
+- clk_disable_unprepare(dev->clock);
+- unicam_runtime_put(dev);
+-
+- } else if (node->pad_id == METADATA_PAD) {
+- /* Allow the hardware to spin in the dummy buffer.
+- * This is only really needed if the embedded data pad is
+- * disabled before the image pad. The 0x3 in the top two bits
+- * signifies uncached accesses through the Videocore memory
+- * controller.
+- */
+- unicam_wr_dma_addr(&dev->cfg, node->dummy_buf_dma_addr,
+- DUMMY_BUF_SIZE, METADATA_PAD);
+- }
+-
+- /* Clear all queued buffers for the node */
+- spin_lock_irqsave(&node->dma_queue_lock, flags);
+- list_for_each_entry_safe(buf, tmp, &dma_q->active, list) {
+- list_del(&buf->list);
+- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+- }
+-
+- if (node->cur_frm)
+- vb2_buffer_done(&node->cur_frm->vb.vb2_buf,
+- VB2_BUF_STATE_ERROR);
+- if (node->next_frm && node->cur_frm != node->next_frm)
+- vb2_buffer_done(&node->next_frm->vb.vb2_buf,
+- VB2_BUF_STATE_ERROR);
+-
+- node->cur_frm = NULL;
+- node->next_frm = NULL;
+- spin_unlock_irqrestore(&node->dma_queue_lock, flags);
+-}
+-
+-static int unicam_enum_input(struct file *file, void *priv,
+- struct v4l2_input *inp)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+-
+- if (inp->index != 0)
+- return -EINVAL;
+-
+- inp->type = V4L2_INPUT_TYPE_CAMERA;
+- if (v4l2_subdev_has_op(dev->sensor, video, s_dv_timings)) {
+- inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;
+- inp->std = 0;
+- } else if (v4l2_subdev_has_op(dev->sensor, video, s_std)) {
+- inp->capabilities = V4L2_IN_CAP_STD;
+- if (v4l2_subdev_call(dev->sensor, video, g_tvnorms, &inp->std)
+- < 0)
+- inp->std = V4L2_STD_ALL;
+- } else {
+- inp->capabilities = 0;
+- inp->std = 0;
+- }
+- sprintf(inp->name, "Camera 0");
+- return 0;
+-}
+-
+-static int unicam_g_input(struct file *file, void *priv, unsigned int *i)
+-{
+- *i = 0;
+-
+- return 0;
+-}
+-
+-static int unicam_s_input(struct file *file, void *priv, unsigned int i)
+-{
+- /*
+- * FIXME: Ideally we would like to be able to query the source
+- * subdevice for information over the input connectors it supports,
+- * and map that through in to a call to video_ops->s_routing.
+- * There is no infrastructure support for defining that within
+- * devicetree at present. Until that is implemented we can't
+- * map a user physical connector number to s_routing input number.
+- */
+- if (i > 0)
+- return -EINVAL;
+-
+- return 0;
+-}
+-
+-static int unicam_querystd(struct file *file, void *priv,
+- v4l2_std_id *std)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+-
+- return v4l2_subdev_call(dev->sensor, video, querystd, std);
+-}
+-
+-static int unicam_g_std(struct file *file, void *priv, v4l2_std_id *std)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+-
+- return v4l2_subdev_call(dev->sensor, video, g_std, std);
+-}
+-
+-static int unicam_s_std(struct file *file, void *priv, v4l2_std_id std)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- int ret;
+- v4l2_std_id current_std;
+-
+- ret = v4l2_subdev_call(dev->sensor, video, g_std, &current_std);
+- if (ret)
+- return ret;
+-
+- if (std == current_std)
+- return 0;
+-
+- if (vb2_is_busy(&node->buffer_queue))
+- return -EBUSY;
+-
+- ret = v4l2_subdev_call(dev->sensor, video, s_std, std);
+-
+- /* Force recomputation of bytesperline */
+- node->v_fmt.fmt.pix.bytesperline = 0;
+-
+- unicam_reset_format(node);
+-
+- return ret;
+-}
+-
+-static int unicam_s_edid(struct file *file, void *priv, struct v4l2_edid *edid)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+-
+- return v4l2_subdev_call(dev->sensor, pad, set_edid, edid);
+-}
+-
+-static int unicam_g_edid(struct file *file, void *priv, struct v4l2_edid *edid)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+-
+- return v4l2_subdev_call(dev->sensor, pad, get_edid, edid);
+-}
+-
+-static int unicam_s_selection(struct file *file, void *priv,
+- struct v4l2_selection *sel)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- struct v4l2_subdev_selection sdsel = {
+- .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+- .target = sel->target,
+- .flags = sel->flags,
+- .r = sel->r,
+- };
+-
+- return v4l2_subdev_call(dev->sensor, pad, set_selection, NULL, &sdsel);
+-}
+-
+-static int unicam_g_selection(struct file *file, void *priv,
+- struct v4l2_selection *sel)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- struct v4l2_subdev_selection sdsel = {
+- .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+- .target = sel->target,
+- };
+- int ret;
+-
+- ret = v4l2_subdev_call(dev->sensor, pad, get_selection, NULL, &sdsel);
+- if (!ret)
+- sel->r = sdsel.r;
+-
+- return ret;
+-}
+-
+-static int unicam_enum_framesizes(struct file *file, void *priv,
+- struct v4l2_frmsizeenum *fsize)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- const struct unicam_fmt *fmt;
+- struct v4l2_subdev_frame_size_enum fse;
+- int ret;
+-
+- if (node->pad_id == IMAGE_PAD) {
+- /* check for valid format */
+- fmt = find_format_by_pix(dev, fsize->pixel_format);
+- if (!fmt) {
+- unicam_dbg(3, dev, "Invalid pixel code: %x\n",
+- fsize->pixel_format);
+- return -EINVAL;
+- }
+- fse.code = fmt->code;
+- } else {
+- /* This pad is for embedded data, so just set the format */
+- fse.code = MEDIA_BUS_FMT_SENSOR_DATA;
+- }
+-
+- fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+- fse.index = fsize->index;
+- fse.pad = node->pad_id;
+-
+- ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_size, NULL, &fse);
+- if (ret)
+- return ret;
+-
+- unicam_dbg(1, dev, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n",
+- __func__, fse.index, fse.code, fse.min_width, fse.max_width,
+- fse.min_height, fse.max_height);
+-
+- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+- fsize->discrete.width = fse.max_width;
+- fsize->discrete.height = fse.max_height;
+-
+- return 0;
+-}
+-
+-static int unicam_enum_frameintervals(struct file *file, void *priv,
+- struct v4l2_frmivalenum *fival)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- const struct unicam_fmt *fmt;
+- struct v4l2_subdev_frame_interval_enum fie = {
+- .index = fival->index,
+- .width = fival->width,
+- .height = fival->height,
+- .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+- };
+- int ret;
+-
+- fmt = find_format_by_pix(dev, fival->pixel_format);
+- if (!fmt)
+- return -EINVAL;
+-
+- fie.code = fmt->code;
+- ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_interval,
+- NULL, &fie);
+- if (ret)
+- return ret;
+-
+- fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+- fival->discrete = fie.interval;
+-
+- return 0;
+-}
+-
+-static int unicam_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+-
+- return v4l2_g_parm_cap(video_devdata(file), dev->sensor, a);
+-}
+-
+-static int unicam_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+-
+- return v4l2_s_parm_cap(video_devdata(file), dev->sensor, a);
+-}
+-
+-static int unicam_g_dv_timings(struct file *file, void *priv,
+- struct v4l2_dv_timings *timings)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+-
+- return v4l2_subdev_call(dev->sensor, video, g_dv_timings, timings);
+-}
+-
+-static int unicam_s_dv_timings(struct file *file, void *priv,
+- struct v4l2_dv_timings *timings)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- struct v4l2_dv_timings current_timings;
+- int ret;
+-
+- ret = v4l2_subdev_call(dev->sensor, video, g_dv_timings,
+- &current_timings);
+-
+- if (v4l2_match_dv_timings(timings, &current_timings, 0, false))
+- return 0;
+-
+- if (vb2_is_busy(&node->buffer_queue))
+- return -EBUSY;
+-
+- ret = v4l2_subdev_call(dev->sensor, video, s_dv_timings, timings);
+-
+- /* Force recomputation of bytesperline */
+- node->v_fmt.fmt.pix.bytesperline = 0;
+-
+- unicam_reset_format(node);
+-
+- return ret;
+-}
+-
+-static int unicam_query_dv_timings(struct file *file, void *priv,
+- struct v4l2_dv_timings *timings)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+-
+- return v4l2_subdev_call(dev->sensor, video, query_dv_timings, timings);
+-}
+-
+-static int unicam_enum_dv_timings(struct file *file, void *priv,
+- struct v4l2_enum_dv_timings *timings)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+-
+- return v4l2_subdev_call(dev->sensor, pad, enum_dv_timings, timings);
+-}
+-
+-static int unicam_dv_timings_cap(struct file *file, void *priv,
+- struct v4l2_dv_timings_cap *cap)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+-
+- return v4l2_subdev_call(dev->sensor, pad, dv_timings_cap, cap);
+-}
+-
+-static int unicam_subscribe_event(struct v4l2_fh *fh,
+- const struct v4l2_event_subscription *sub)
+-{
+- switch (sub->type) {
+- case V4L2_EVENT_FRAME_SYNC:
+- return v4l2_event_subscribe(fh, sub, 2, NULL);
+- case V4L2_EVENT_SOURCE_CHANGE:
+- return v4l2_event_subscribe(fh, sub, 4, NULL);
+- }
+-
+- return v4l2_ctrl_subscribe_event(fh, sub);
+-}
+-
+-static int unicam_log_status(struct file *file, void *fh)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- struct unicam_cfg *cfg = &dev->cfg;
+- u32 reg;
+-
+- /* status for sub devices */
+- v4l2_device_call_all(&dev->v4l2_dev, 0, core, log_status);
+-
+- unicam_info(dev, "-----Receiver status-----\n");
+- unicam_info(dev, "V4L2 width/height: %ux%u\n",
+- node->v_fmt.fmt.pix.width, node->v_fmt.fmt.pix.height);
+- unicam_info(dev, "Mediabus format: %08x\n", node->fmt->code);
+- unicam_info(dev, "V4L2 format: %08x\n",
+- node->v_fmt.fmt.pix.pixelformat);
+- reg = reg_read(&dev->cfg, UNICAM_IPIPE);
+- unicam_info(dev, "Unpacking/packing: %u / %u\n",
+- get_field(reg, UNICAM_PUM_MASK),
+- get_field(reg, UNICAM_PPM_MASK));
+- unicam_info(dev, "----Live data----\n");
+- unicam_info(dev, "Programmed stride: %4u\n",
+- reg_read(cfg, UNICAM_IBLS));
+- unicam_info(dev, "Detected resolution: %ux%u\n",
+- reg_read(cfg, UNICAM_IHSTA),
+- reg_read(cfg, UNICAM_IVSTA));
+- unicam_info(dev, "Write pointer: %08x\n",
+- reg_read(cfg, UNICAM_IBWP));
+-
+- return 0;
+-}
+-
+-static void unicam_notify(struct v4l2_subdev *sd,
+- unsigned int notification, void *arg)
+-{
+- struct unicam_device *dev =
+- container_of(sd->v4l2_dev, struct unicam_device, v4l2_dev);
+-
+- switch (notification) {
+- case V4L2_DEVICE_NOTIFY_EVENT:
+- v4l2_event_queue(&dev->node[IMAGE_PAD].video_dev, arg);
+- break;
+- default:
+- break;
+- }
+-}
+-
+-static const struct vb2_ops unicam_video_qops = {
+- .wait_prepare = vb2_ops_wait_prepare,
+- .wait_finish = vb2_ops_wait_finish,
+- .queue_setup = unicam_queue_setup,
+- .buf_prepare = unicam_buffer_prepare,
+- .buf_queue = unicam_buffer_queue,
+- .start_streaming = unicam_start_streaming,
+- .stop_streaming = unicam_stop_streaming,
+-};
+-
+-/*
+- * unicam_open : This function is based on the v4l2_fh_open helper function.
+- * It has been augmented to handle sensor subdevice power management,
+- */
+-static int unicam_open(struct file *file)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- int ret;
+-
+- mutex_lock(&node->lock);
+-
+- ret = v4l2_fh_open(file);
+- if (ret) {
+- unicam_err(dev, "v4l2_fh_open failed\n");
+- goto unlock;
+- }
+-
+- node->open++;
+-
+- if (!v4l2_fh_is_singular_file(file))
+- goto unlock;
+-
+- ret = v4l2_subdev_call(dev->sensor, core, s_power, 1);
+- if (ret < 0 && ret != -ENOIOCTLCMD) {
+- v4l2_fh_release(file);
+- node->open--;
+- goto unlock;
+- }
+-
+- ret = 0;
+-
+-unlock:
+- mutex_unlock(&node->lock);
+- return ret;
+-}
+-
+-static int unicam_release(struct file *file)
+-{
+- struct unicam_node *node = video_drvdata(file);
+- struct unicam_device *dev = node->dev;
+- struct v4l2_subdev *sd = dev->sensor;
+- bool fh_singular;
+- int ret;
+-
+- mutex_lock(&node->lock);
+-
+- fh_singular = v4l2_fh_is_singular_file(file);
+-
+- ret = _vb2_fop_release(file, NULL);
+-
+- if (fh_singular)
+- v4l2_subdev_call(sd, core, s_power, 0);
+-
+- node->open--;
+- mutex_unlock(&node->lock);
+-
+- return ret;
+-}
+-
+-/* unicam capture driver file operations */
+-static const struct v4l2_file_operations unicam_fops = {
+- .owner = THIS_MODULE,
+- .open = unicam_open,
+- .release = unicam_release,
+- .read = vb2_fop_read,
+- .poll = vb2_fop_poll,
+- .unlocked_ioctl = video_ioctl2,
+- .mmap = vb2_fop_mmap,
+-};
+-
+-/* unicam capture ioctl operations */
+-static const struct v4l2_ioctl_ops unicam_ioctl_ops = {
+- .vidioc_querycap = unicam_querycap,
+- .vidioc_enum_fmt_vid_cap = unicam_enum_fmt_vid_cap,
+- .vidioc_g_fmt_vid_cap = unicam_g_fmt_vid_cap,
+- .vidioc_s_fmt_vid_cap = unicam_s_fmt_vid_cap,
+- .vidioc_try_fmt_vid_cap = unicam_try_fmt_vid_cap,
+-
+- .vidioc_enum_fmt_meta_cap = unicam_enum_fmt_meta_cap,
+- .vidioc_g_fmt_meta_cap = unicam_g_fmt_meta_cap,
+- .vidioc_s_fmt_meta_cap = unicam_s_fmt_meta_cap,
+- .vidioc_try_fmt_meta_cap = unicam_try_fmt_meta_cap,
+-
+- .vidioc_enum_input = unicam_enum_input,
+- .vidioc_g_input = unicam_g_input,
+- .vidioc_s_input = unicam_s_input,
+-
+- .vidioc_querystd = unicam_querystd,
+- .vidioc_s_std = unicam_s_std,
+- .vidioc_g_std = unicam_g_std,
+-
+- .vidioc_g_edid = unicam_g_edid,
+- .vidioc_s_edid = unicam_s_edid,
+-
+- .vidioc_enum_framesizes = unicam_enum_framesizes,
+- .vidioc_enum_frameintervals = unicam_enum_frameintervals,
+-
+- .vidioc_g_selection = unicam_g_selection,
+- .vidioc_s_selection = unicam_s_selection,
+-
+- .vidioc_g_parm = unicam_g_parm,
+- .vidioc_s_parm = unicam_s_parm,
+-
+- .vidioc_s_dv_timings = unicam_s_dv_timings,
+- .vidioc_g_dv_timings = unicam_g_dv_timings,
+- .vidioc_query_dv_timings = unicam_query_dv_timings,
+- .vidioc_enum_dv_timings = unicam_enum_dv_timings,
+- .vidioc_dv_timings_cap = unicam_dv_timings_cap,
+-
+- .vidioc_reqbufs = vb2_ioctl_reqbufs,
+- .vidioc_create_bufs = vb2_ioctl_create_bufs,
+- .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+- .vidioc_querybuf = vb2_ioctl_querybuf,
+- .vidioc_qbuf = vb2_ioctl_qbuf,
+- .vidioc_dqbuf = vb2_ioctl_dqbuf,
+- .vidioc_expbuf = vb2_ioctl_expbuf,
+- .vidioc_streamon = vb2_ioctl_streamon,
+- .vidioc_streamoff = vb2_ioctl_streamoff,
+-
+- .vidioc_log_status = unicam_log_status,
+- .vidioc_subscribe_event = unicam_subscribe_event,
+- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+-};
+-
+-static int
+-unicam_async_bound(struct v4l2_async_notifier *notifier,
+- struct v4l2_subdev *subdev,
+- struct v4l2_async_subdev *asd)
+-{
+- struct unicam_device *unicam = container_of(notifier->v4l2_dev,
+- struct unicam_device, v4l2_dev);
+-
+- if (unicam->sensor) {
+- unicam_info(unicam, "Rejecting subdev %s (Already set!!)",
+- subdev->name);
+- return 0;
+- }
+-
+- unicam->sensor = subdev;
+- unicam_dbg(1, unicam, "Using sensor %s for capture\n", subdev->name);
+-
+- return 0;
+-}
+-
+-static int register_node(struct unicam_device *unicam, struct unicam_node *node,
+- enum v4l2_buf_type type, int pad_id)
+-{
+- struct video_device *vdev;
+- struct vb2_queue *q;
+- struct v4l2_mbus_framefmt mbus_fmt = {0};
+- const struct unicam_fmt *fmt;
+- int ret;
+-
+- if (unicam->sensor_embedded_data || pad_id != METADATA_PAD) {
+- ret = __subdev_get_format(unicam, &mbus_fmt, pad_id);
+- if (ret) {
+- unicam_err(unicam, "Failed to get_format - ret %d\n",
+- ret);
+- return ret;
+- }
+-
+- fmt = find_format_by_code(mbus_fmt.code);
+- if (!fmt) {
+- /* Find the first format that the sensor and unicam both
+- * support
+- */
+- fmt = get_first_supported_format(unicam);
+-
+- if (!fmt)
+- /* No compatible formats */
+- return -EINVAL;
+-
+- mbus_fmt.code = fmt->code;
+- ret = __subdev_set_format(unicam, &mbus_fmt, pad_id);
+- if (ret)
+- return -EINVAL;
+- }
+- if (mbus_fmt.field != V4L2_FIELD_NONE) {
+- /* Interlaced not supported - disable it now. */
+- mbus_fmt.field = V4L2_FIELD_NONE;
+- ret = __subdev_set_format(unicam, &mbus_fmt, pad_id);
+- if (ret)
+- return -EINVAL;
+- }
+- } else {
+- /* Fix this node format as embedded data. */
+- fmt = find_format_by_code(MEDIA_BUS_FMT_SENSOR_DATA);
+- }
+-
+- node->dev = unicam;
+- node->pad_id = pad_id;
+- node->fmt = fmt;
+- if (fmt->fourcc) {
+- if (fmt->fourcc != V4L2_META_FMT_SENSOR_DATA)
+- node->v_fmt.fmt.pix.pixelformat = fmt->fourcc;
+- else
+- node->v_fmt.fmt.meta.dataformat = fmt->fourcc;
+- } else {
+- node->v_fmt.fmt.pix.pixelformat = fmt->repacked_fourcc;
+- }
+-
+- /* Read current subdev format */
+- unicam_reset_format(node);
+-
+- if (v4l2_subdev_has_op(unicam->sensor, video, s_std)) {
+- v4l2_std_id tvnorms;
+-
+- if (WARN_ON(!v4l2_subdev_has_op(unicam->sensor, video,
+- g_tvnorms)))
+- /*
+- * Subdevice should not advertise s_std but not
+- * g_tvnorms
+- */
+- return -EINVAL;
+-
+- ret = v4l2_subdev_call(unicam->sensor, video,
+- g_tvnorms, &tvnorms);
+- if (WARN_ON(ret))
+- return -EINVAL;
+- node->video_dev.tvnorms |= tvnorms;
+- }
+-
+- spin_lock_init(&node->dma_queue_lock);
+- mutex_init(&node->lock);
+-
+- vdev = &node->video_dev;
+- if (pad_id == IMAGE_PAD) {
+- /* Add controls from the subdevice */
+- ret = v4l2_ctrl_add_handler(&node->ctrl_handler,
+- unicam->sensor->ctrl_handler, NULL,
+- true);
+- if (ret < 0)
+- return ret;
+-
+- /*
+- * If the sensor subdevice has any controls, associate the node
+- * with the ctrl handler to allow access from userland.
+- */
+- if (!list_empty(&node->ctrl_handler.ctrls))
+- vdev->ctrl_handler = &node->ctrl_handler;
+- }
+-
+- q = &node->buffer_queue;
+- q->type = type;
+- q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
+- q->drv_priv = node;
+- q->ops = &unicam_video_qops;
+- q->mem_ops = &vb2_dma_contig_memops;
+- q->buf_struct_size = sizeof(struct unicam_buffer);
+- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+- q->lock = &node->lock;
+- q->min_buffers_needed = 1;
+- q->dev = &unicam->pdev->dev;
+-
+- ret = vb2_queue_init(q);
+- if (ret) {
+- unicam_err(unicam, "vb2_queue_init() failed\n");
+- return ret;
+- }
+-
+- INIT_LIST_HEAD(&node->dma_queue.active);
+-
+- vdev->release = video_device_release_empty;
+- vdev->fops = &unicam_fops;
+- vdev->ioctl_ops = &unicam_ioctl_ops;
+- vdev->v4l2_dev = &unicam->v4l2_dev;
+- vdev->vfl_dir = VFL_DIR_RX;
+- vdev->queue = q;
+- vdev->lock = &node->lock;
+- vdev->device_caps = (pad_id == IMAGE_PAD) ?
+- (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING) :
+- (V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING);
+-
+- /* Define the device names */
+- snprintf(vdev->name, sizeof(vdev->name), "%s-%s", UNICAM_MODULE_NAME,
+- node->pad_id == IMAGE_PAD ? "image" : "embedded");
+-
+- video_set_drvdata(vdev, node);
+- vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
+-
+- node->dummy_buf_cpu_addr = dma_alloc_coherent(&unicam->pdev->dev,
+- DUMMY_BUF_SIZE,
+- &node->dummy_buf_dma_addr,
+- GFP_ATOMIC);
+- if (!node->dummy_buf_cpu_addr) {
+- unicam_err(unicam, "Unable to allocate dummy buffer.\n");
+- return -ENOMEM;
+- }
+-
+- if (node->pad_id == METADATA_PAD) {
+- v4l2_disable_ioctl(vdev, VIDIOC_DQEVENT);
+- v4l2_disable_ioctl(vdev, VIDIOC_SUBSCRIBE_EVENT);
+- v4l2_disable_ioctl(vdev, VIDIOC_UNSUBSCRIBE_EVENT);
+- }
+- if (node->pad_id == METADATA_PAD ||
+- !v4l2_subdev_has_op(unicam->sensor, video, s_std)) {
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_STD);
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_STD);
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUMSTD);
+- }
+- if (node->pad_id == METADATA_PAD ||
+- !v4l2_subdev_has_op(unicam->sensor, video, querystd))
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_QUERYSTD);
+- if (node->pad_id == METADATA_PAD ||
+- !v4l2_subdev_has_op(unicam->sensor, video, s_dv_timings)) {
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_EDID);
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_EDID);
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_DV_TIMINGS_CAP);
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_DV_TIMINGS);
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_DV_TIMINGS);
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_DV_TIMINGS);
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_QUERY_DV_TIMINGS);
+- }
+- if (node->pad_id == METADATA_PAD ||
+- !v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_interval))
+- v4l2_disable_ioctl(&node->video_dev,
+- VIDIOC_ENUM_FRAMEINTERVALS);
+- if (node->pad_id == METADATA_PAD ||
+- !v4l2_subdev_has_op(unicam->sensor, video, g_frame_interval))
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_PARM);
+- if (node->pad_id == METADATA_PAD ||
+- !v4l2_subdev_has_op(unicam->sensor, video, s_frame_interval))
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_PARM);
+-
+- if (node->pad_id == METADATA_PAD ||
+- !v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_size))
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_FRAMESIZES);
+-
+- if (node->pad_id == METADATA_PAD ||
+- !v4l2_subdev_has_op(unicam->sensor, pad, set_selection))
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_SELECTION);
+-
+- if (node->pad_id == METADATA_PAD ||
+- !v4l2_subdev_has_op(unicam->sensor, pad, get_selection))
+- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_SELECTION);
+-
+- ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
+- if (ret) {
+- unicam_err(unicam, "Unable to register video device.\n");
+- return ret;
+- }
+- node->registered = 1;
+-
+- if (unicam->sensor_embedded_data) {
+- ret = media_create_pad_link(&unicam->sensor->entity, pad_id,
+- &node->video_dev.entity, 0,
+- MEDIA_LNK_FL_ENABLED |
+- MEDIA_LNK_FL_IMMUTABLE);
+- if (ret)
+- unicam_err(unicam, "Unable to create pad links.\n");
+- }
+-
+- return ret;
+-}
+-
+-static void unregister_nodes(struct unicam_device *unicam)
+-{
+- struct unicam_node *node;
+- int i;
+-
+- for (i = 0; i < MAX_NODES; i++) {
+- node = &unicam->node[i];
+- if (node->dummy_buf_cpu_addr) {
+- dma_free_coherent(&unicam->pdev->dev, DUMMY_BUF_SIZE,
+- node->dummy_buf_cpu_addr,
+- node->dummy_buf_dma_addr);
+- }
+- if (node->registered) {
+- video_unregister_device(&node->video_dev);
+- node->registered = 0;
+- }
+- }
+-}
+-
+-static int unicam_probe_complete(struct unicam_device *unicam)
+-{
+- int ret;
+-
+- v4l2_set_subdev_hostdata(unicam->sensor, unicam);
+-
+- unicam->v4l2_dev.notify = unicam_notify;
+-
+- unicam->sensor_config = v4l2_subdev_alloc_pad_config(unicam->sensor);
+- if (!unicam->sensor_config)
+- return -ENOMEM;
+-
+- unicam->sensor_embedded_data = (unicam->sensor->entity.num_pads >= 2);
+-
+- ret = register_node(unicam, &unicam->node[IMAGE_PAD],
+- V4L2_BUF_TYPE_VIDEO_CAPTURE, IMAGE_PAD);
+- if (ret) {
+- unicam_err(unicam, "Unable to register subdev node 0.\n");
+- goto unregister;
+- }
+-
+- ret = register_node(unicam, &unicam->node[METADATA_PAD],
+- V4L2_BUF_TYPE_META_CAPTURE, METADATA_PAD);
+- if (ret) {
+- unicam_err(unicam, "Unable to register subdev node 1.\n");
+- goto unregister;
+- }
+-
+- ret = v4l2_device_register_ro_subdev_nodes(&unicam->v4l2_dev);
+- if (ret) {
+- unicam_err(unicam, "Unable to register subdev nodes.\n");
+- goto unregister;
+- }
+-
+- return 0;
+-
+-unregister:
+- unregister_nodes(unicam);
+-
+- return ret;
+-}
+-
+-static int unicam_async_complete(struct v4l2_async_notifier *notifier)
+-{
+- struct unicam_device *unicam = container_of(notifier->v4l2_dev,
+- struct unicam_device, v4l2_dev);
+-
+- return unicam_probe_complete(unicam);
+-}
+-
+-static const struct v4l2_async_notifier_operations unicam_async_ops = {
+- .bound = unicam_async_bound,
+- .complete = unicam_async_complete,
+-};
+-
+-static int of_unicam_connect_subdevs(struct unicam_device *dev)
+-{
+- struct platform_device *pdev = dev->pdev;
+- struct device_node *parent, *ep_node = NULL, *remote_ep = NULL,
+- *sensor_node = NULL;
+- struct v4l2_fwnode_endpoint *ep;
+- struct v4l2_async_subdev *asd;
+- unsigned int peripheral_data_lanes;
+- int ret = -EINVAL;
+- unsigned int lane;
+-
+- parent = pdev->dev.of_node;
+-
+- asd = &dev->asd;
+- ep = &dev->endpoint;
+-
+- ep_node = of_graph_get_next_endpoint(parent, NULL);
+- if (!ep_node) {
+- unicam_dbg(3, dev, "can't get next endpoint\n");
+- goto cleanup_exit;
+- }
+-
+- unicam_dbg(3, dev, "ep_node is %s\n", ep_node->name);
+-
+- v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), ep);
+-
+- for (lane = 0; lane < ep->bus.mipi_csi2.num_data_lanes; lane++) {
+- if (ep->bus.mipi_csi2.data_lanes[lane] != lane + 1) {
+- unicam_err(dev, "Local endpoint - data lane reordering not supported\n");
+- goto cleanup_exit;
+- }
+- }
+-
+- peripheral_data_lanes = ep->bus.mipi_csi2.num_data_lanes;
+-
+- sensor_node = of_graph_get_remote_port_parent(ep_node);
+- if (!sensor_node) {
+- unicam_dbg(3, dev, "can't get remote parent\n");
+- goto cleanup_exit;
+- }
+- unicam_dbg(3, dev, "sensor_node is %s\n", sensor_node->name);
+- asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
+- asd->match.fwnode = of_fwnode_handle(sensor_node);
+-
+- remote_ep = of_graph_get_remote_endpoint(ep_node);
+- if (!remote_ep) {
+- unicam_dbg(3, dev, "can't get remote-endpoint\n");
+- goto cleanup_exit;
+- }
+- unicam_dbg(3, dev, "remote_ep is %s\n", remote_ep->name);
+- v4l2_fwnode_endpoint_parse(of_fwnode_handle(remote_ep), ep);
+- unicam_dbg(3, dev, "parsed remote_ep to endpoint. nr_of_link_frequencies %u, bus_type %u\n",
+- ep->nr_of_link_frequencies, ep->bus_type);
+-
+- switch (ep->bus_type) {
+- case V4L2_MBUS_CSI2_DPHY:
+- if (ep->bus.mipi_csi2.num_data_lanes >
+- peripheral_data_lanes) {
+- unicam_err(dev, "Subdevice %s wants too many data lanes (%u > %u)\n",
+- sensor_node->name,
+- ep->bus.mipi_csi2.num_data_lanes,
+- peripheral_data_lanes);
+- goto cleanup_exit;
+- }
+- for (lane = 0;
+- lane < ep->bus.mipi_csi2.num_data_lanes;
+- lane++) {
+- if (ep->bus.mipi_csi2.data_lanes[lane] != lane + 1) {
+- unicam_err(dev, "Subdevice %s - incompatible data lane config\n",
+- sensor_node->name);
+- goto cleanup_exit;
+- }
+- }
+- dev->max_data_lanes = ep->bus.mipi_csi2.num_data_lanes;
+- dev->bus_flags = ep->bus.mipi_csi2.flags;
+- break;
+- case V4L2_MBUS_CCP2:
+- if (ep->bus.mipi_csi1.clock_lane != 0 ||
+- ep->bus.mipi_csi1.data_lane != 1) {
+- unicam_err(dev, "Subdevice %s incompatible lane config\n",
+- sensor_node->name);
+- goto cleanup_exit;
+- }
+- dev->max_data_lanes = 1;
+- dev->bus_flags = ep->bus.mipi_csi1.strobe;
+- break;
+- default:
+- /* Unsupported bus type */
+- unicam_err(dev, "sub-device %s is not a CSI2 or CCP2 device %d\n",
+- sensor_node->name, ep->bus_type);
+- goto cleanup_exit;
+- }
+-
+- /* Store bus type - CSI2 or CCP2 */
+- dev->bus_type = ep->bus_type;
+- unicam_dbg(3, dev, "bus_type is %d\n", dev->bus_type);
+-
+- /* Store Virtual Channel number */
+- dev->virtual_channel = ep->base.id;
+-
+- unicam_dbg(3, dev, "v4l2-endpoint: %s\n",
+- dev->bus_type == V4L2_MBUS_CSI2_DPHY ? "CSI2" : "CCP2");
+- unicam_dbg(3, dev, "Virtual Channel=%d\n", dev->virtual_channel);
+- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY)
+- unicam_dbg(3, dev, "flags=0x%08x\n", ep->bus.mipi_csi2.flags);
+- unicam_dbg(3, dev, "num_data_lanes=%d\n", dev->max_data_lanes);
+-
+- unicam_dbg(1, dev, "found sub-device %s\n", sensor_node->name);
+-
+- v4l2_async_notifier_init(&dev->notifier);
+-
+- ret = v4l2_async_notifier_add_subdev(&dev->notifier, asd);
+- if (ret) {
+- unicam_err(dev, "Error adding subdevice - ret %d\n", ret);
+- goto cleanup_exit;
+- }
+-
+- dev->notifier.ops = &unicam_async_ops;
+- ret = v4l2_async_notifier_register(&dev->v4l2_dev,
+- &dev->notifier);
+- if (ret) {
+- unicam_err(dev, "Error registering async notifier - ret %d\n",
+- ret);
+- ret = -EINVAL;
+- }
+-
+-cleanup_exit:
+- if (remote_ep)
+- of_node_put(remote_ep);
+- if (sensor_node)
+- of_node_put(sensor_node);
+- if (ep_node)
+- of_node_put(ep_node);
+-
+- return ret;
+-}
+-
+-static int unicam_probe(struct platform_device *pdev)
+-{
+- struct unicam_cfg *unicam_cfg;
+- struct unicam_device *unicam;
+- struct v4l2_ctrl_handler *hdl;
+- struct resource *res;
+- int ret;
+-
+- unicam = devm_kzalloc(&pdev->dev, sizeof(*unicam), GFP_KERNEL);
+- if (!unicam)
+- return -ENOMEM;
+-
+- unicam->pdev = pdev;
+- unicam_cfg = &unicam->cfg;
+-
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- unicam_cfg->base = devm_ioremap_resource(&pdev->dev, res);
+- if (IS_ERR(unicam_cfg->base)) {
+- unicam_err(unicam, "Failed to get main io block\n");
+- return PTR_ERR(unicam_cfg->base);
+- }
+-
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+- unicam_cfg->clk_gate_base = devm_ioremap_resource(&pdev->dev, res);
+- if (IS_ERR(unicam_cfg->clk_gate_base)) {
+- unicam_err(unicam, "Failed to get 2nd io block\n");
+- return PTR_ERR(unicam_cfg->clk_gate_base);
+- }
+-
+- unicam->clock = devm_clk_get(&pdev->dev, "lp");
+- if (IS_ERR(unicam->clock)) {
+- unicam_err(unicam, "Failed to get clock\n");
+- return PTR_ERR(unicam->clock);
+- }
+-
+- ret = platform_get_irq(pdev, 0);
+- if (ret <= 0) {
+- dev_err(&pdev->dev, "No IRQ resource\n");
+- return -ENODEV;
+- }
+-
+- ret = devm_request_irq(&pdev->dev, ret, unicam_isr, 0,
+- "unicam_capture0", unicam);
+- if (ret) {
+- dev_err(&pdev->dev, "Unable to request interrupt\n");
+- return -EINVAL;
+- }
+-
+- unicam->mdev.dev = &pdev->dev;
+- strscpy(unicam->mdev.model, UNICAM_MODULE_NAME,
+- sizeof(unicam->mdev.model));
+- strscpy(unicam->mdev.serial, "", sizeof(unicam->mdev.serial));
+- snprintf(unicam->mdev.bus_info, sizeof(unicam->mdev.bus_info),
+- "platform:%s %s",
+- pdev->dev.driver->name, dev_name(&pdev->dev));
+- unicam->mdev.hw_revision = 1;
+-
+- media_entity_pads_init(&unicam->node[IMAGE_PAD].video_dev.entity, 1,
+- &unicam->node[IMAGE_PAD].pad);
+- media_entity_pads_init(&unicam->node[METADATA_PAD].video_dev.entity, 1,
+- &unicam->node[METADATA_PAD].pad);
+- media_device_init(&unicam->mdev);
+-
+- unicam->v4l2_dev.mdev = &unicam->mdev;
+-
+- ret = v4l2_device_register(&pdev->dev, &unicam->v4l2_dev);
+- if (ret) {
+- unicam_err(unicam,
+- "Unable to register v4l2 device.\n");
+- goto media_cleanup;
+- }
+-
+- ret = media_device_register(&unicam->mdev);
+- if (ret < 0) {
+- unicam_err(unicam,
+- "Unable to register media-controller device.\n");
+- goto probe_out_v4l2_unregister;
+- }
+-
+- /* Reserve space for the controls */
+- hdl = &unicam->node[IMAGE_PAD].ctrl_handler;
+- ret = v4l2_ctrl_handler_init(hdl, 16);
+- if (ret < 0)
+- goto media_unregister;
+-
+- /* set the driver data in platform device */
+- platform_set_drvdata(pdev, unicam);
+-
+- ret = of_unicam_connect_subdevs(unicam);
+- if (ret) {
+- dev_err(&pdev->dev, "Failed to connect subdevs\n");
+- goto free_hdl;
+- }
+-
+- /* Enable the block power domain */
+- pm_runtime_enable(&pdev->dev);
+-
+- return 0;
+-
+-free_hdl:
+- v4l2_ctrl_handler_free(hdl);
+-media_unregister:
+- media_device_unregister(&unicam->mdev);
+-probe_out_v4l2_unregister:
+- v4l2_device_unregister(&unicam->v4l2_dev);
+-media_cleanup:
+- media_device_cleanup(&unicam->mdev);
+-
+- return ret;
+-}
+-
+-static int unicam_remove(struct platform_device *pdev)
+-{
+- struct unicam_device *unicam = platform_get_drvdata(pdev);
+-
+- unicam_dbg(2, unicam, "%s\n", __func__);
+-
+- pm_runtime_disable(&pdev->dev);
+-
+- v4l2_async_notifier_unregister(&unicam->notifier);
+- v4l2_ctrl_handler_free(&unicam->node[IMAGE_PAD].ctrl_handler);
+- v4l2_device_unregister(&unicam->v4l2_dev);
+- unregister_nodes(unicam);
+- if (unicam->sensor_config)
+- v4l2_subdev_free_pad_config(unicam->sensor_config);
+- media_device_unregister(&unicam->mdev);
+- media_device_cleanup(&unicam->mdev);
+-
+- return 0;
+-}
+-
+-static const struct of_device_id unicam_of_match[] = {
+- { .compatible = "brcm,bcm2835-unicam", },
+- { /* sentinel */ },
+-};
+-MODULE_DEVICE_TABLE(of, unicam_of_match);
+-
+-static struct platform_driver unicam_driver = {
+- .probe = unicam_probe,
+- .remove = unicam_remove,
+- .driver = {
+- .name = UNICAM_MODULE_NAME,
+- .of_match_table = of_match_ptr(unicam_of_match),
+- },
+-};
+-
+-module_platform_driver(unicam_driver);
+-
+-MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.com>");
+-MODULE_DESCRIPTION("BCM2835 Unicam driver");
+-MODULE_LICENSE("GPL");
+-MODULE_VERSION(UNICAM_VERSION);
+--- a/drivers/media/platform/bcm2835/vc4-regs-unicam.h
++++ /dev/null
+@@ -1,253 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-only */
+-
+-/*
+- * Copyright (C) 2017-2020 Raspberry Pi Trading.
+- * Dave Stevenson <dave.stevenson@raspberrypi.com>
+- */
+-
+-#ifndef VC4_REGS_UNICAM_H
+-#define VC4_REGS_UNICAM_H
+-
+-/*
+- * The following values are taken from files found within the code drop
+- * made by Broadcom for the BCM21553 Graphics Driver, predominantly in
+- * brcm_usrlib/dag/vmcsx/vcinclude/hardware_vc4.h.
+- * They have been modified to be only the register offset.
+- */
+-#define UNICAM_CTRL 0x000
+-#define UNICAM_STA 0x004
+-#define UNICAM_ANA 0x008
+-#define UNICAM_PRI 0x00c
+-#define UNICAM_CLK 0x010
+-#define UNICAM_CLT 0x014
+-#define UNICAM_DAT0 0x018
+-#define UNICAM_DAT1 0x01c
+-#define UNICAM_DAT2 0x020
+-#define UNICAM_DAT3 0x024
+-#define UNICAM_DLT 0x028
+-#define UNICAM_CMP0 0x02c
+-#define UNICAM_CMP1 0x030
+-#define UNICAM_CAP0 0x034
+-#define UNICAM_CAP1 0x038
+-#define UNICAM_ICTL 0x100
+-#define UNICAM_ISTA 0x104
+-#define UNICAM_IDI0 0x108
+-#define UNICAM_IPIPE 0x10c
+-#define UNICAM_IBSA0 0x110
+-#define UNICAM_IBEA0 0x114
+-#define UNICAM_IBLS 0x118
+-#define UNICAM_IBWP 0x11c
+-#define UNICAM_IHWIN 0x120
+-#define UNICAM_IHSTA 0x124
+-#define UNICAM_IVWIN 0x128
+-#define UNICAM_IVSTA 0x12c
+-#define UNICAM_ICC 0x130
+-#define UNICAM_ICS 0x134
+-#define UNICAM_IDC 0x138
+-#define UNICAM_IDPO 0x13c
+-#define UNICAM_IDCA 0x140
+-#define UNICAM_IDCD 0x144
+-#define UNICAM_IDS 0x148
+-#define UNICAM_DCS 0x200
+-#define UNICAM_DBSA0 0x204
+-#define UNICAM_DBEA0 0x208
+-#define UNICAM_DBWP 0x20c
+-#define UNICAM_DBCTL 0x300
+-#define UNICAM_IBSA1 0x304
+-#define UNICAM_IBEA1 0x308
+-#define UNICAM_IDI1 0x30c
+-#define UNICAM_DBSA1 0x310
+-#define UNICAM_DBEA1 0x314
+-#define UNICAM_MISC 0x400
+-
+-/*
+- * The following bitmasks are from the kernel released by Broadcom
+- * for Android - https://android.googlesource.com/kernel/bcm/
+- * The Rhea, Hawaii, and Java chips all contain the same VideoCore4
+- * Unicam block as BCM2835, as defined in eg
+- * arch/arm/mach-rhea/include/mach/rdb_A0/brcm_rdb_cam.h and similar.
+- * Values reworked to use the kernel BIT and GENMASK macros.
+- *
+- * Some of the bit mnenomics have been amended to match the datasheet.
+- */
+-/* UNICAM_CTRL Register */
+-#define UNICAM_CPE BIT(0)
+-#define UNICAM_MEM BIT(1)
+-#define UNICAM_CPR BIT(2)
+-#define UNICAM_CPM_MASK GENMASK(3, 3)
+-#define UNICAM_CPM_CSI2 0
+-#define UNICAM_CPM_CCP2 1
+-#define UNICAM_SOE BIT(4)
+-#define UNICAM_DCM_MASK GENMASK(5, 5)
+-#define UNICAM_DCM_STROBE 0
+-#define UNICAM_DCM_DATA 1
+-#define UNICAM_SLS BIT(6)
+-#define UNICAM_PFT_MASK GENMASK(11, 8)
+-#define UNICAM_OET_MASK GENMASK(20, 12)
+-
+-/* UNICAM_STA Register */
+-#define UNICAM_SYN BIT(0)
+-#define UNICAM_CS BIT(1)
+-#define UNICAM_SBE BIT(2)
+-#define UNICAM_PBE BIT(3)
+-#define UNICAM_HOE BIT(4)
+-#define UNICAM_PLE BIT(5)
+-#define UNICAM_SSC BIT(6)
+-#define UNICAM_CRCE BIT(7)
+-#define UNICAM_OES BIT(8)
+-#define UNICAM_IFO BIT(9)
+-#define UNICAM_OFO BIT(10)
+-#define UNICAM_BFO BIT(11)
+-#define UNICAM_DL BIT(12)
+-#define UNICAM_PS BIT(13)
+-#define UNICAM_IS BIT(14)
+-#define UNICAM_PI0 BIT(15)
+-#define UNICAM_PI1 BIT(16)
+-#define UNICAM_FSI_S BIT(17)
+-#define UNICAM_FEI_S BIT(18)
+-#define UNICAM_LCI_S BIT(19)
+-#define UNICAM_BUF0_RDY BIT(20)
+-#define UNICAM_BUF0_NO BIT(21)
+-#define UNICAM_BUF1_RDY BIT(22)
+-#define UNICAM_BUF1_NO BIT(23)
+-#define UNICAM_DI BIT(24)
+-
+-#define UNICAM_STA_MASK_ALL \
+- (UNICAM_DL + \
+- UNICAM_SBE + \
+- UNICAM_PBE + \
+- UNICAM_HOE + \
+- UNICAM_PLE + \
+- UNICAM_SSC + \
+- UNICAM_CRCE + \
+- UNICAM_IFO + \
+- UNICAM_OFO + \
+- UNICAM_PS + \
+- UNICAM_PI0 + \
+- UNICAM_PI1)
+-
+-/* UNICAM_ANA Register */
+-#define UNICAM_APD BIT(0)
+-#define UNICAM_BPD BIT(1)
+-#define UNICAM_AR BIT(2)
+-#define UNICAM_DDL BIT(3)
+-#define UNICAM_CTATADJ_MASK GENMASK(7, 4)
+-#define UNICAM_PTATADJ_MASK GENMASK(11, 8)
+-
+-/* UNICAM_PRI Register */
+-#define UNICAM_PE BIT(0)
+-#define UNICAM_PT_MASK GENMASK(2, 1)
+-#define UNICAM_NP_MASK GENMASK(7, 4)
+-#define UNICAM_PP_MASK GENMASK(11, 8)
+-#define UNICAM_BS_MASK GENMASK(15, 12)
+-#define UNICAM_BL_MASK GENMASK(17, 16)
+-
+-/* UNICAM_CLK Register */
+-#define UNICAM_CLE BIT(0)
+-#define UNICAM_CLPD BIT(1)
+-#define UNICAM_CLLPE BIT(2)
+-#define UNICAM_CLHSE BIT(3)
+-#define UNICAM_CLTRE BIT(4)
+-#define UNICAM_CLAC_MASK GENMASK(8, 5)
+-#define UNICAM_CLSTE BIT(29)
+-
+-/* UNICAM_CLT Register */
+-#define UNICAM_CLT1_MASK GENMASK(7, 0)
+-#define UNICAM_CLT2_MASK GENMASK(15, 8)
+-
+-/* UNICAM_DATn Registers */
+-#define UNICAM_DLE BIT(0)
+-#define UNICAM_DLPD BIT(1)
+-#define UNICAM_DLLPE BIT(2)
+-#define UNICAM_DLHSE BIT(3)
+-#define UNICAM_DLTRE BIT(4)
+-#define UNICAM_DLSM BIT(5)
+-#define UNICAM_DLFO BIT(28)
+-#define UNICAM_DLSTE BIT(29)
+-
+-#define UNICAM_DAT_MASK_ALL (UNICAM_DLSTE + UNICAM_DLFO)
+-
+-/* UNICAM_DLT Register */
+-#define UNICAM_DLT1_MASK GENMASK(7, 0)
+-#define UNICAM_DLT2_MASK GENMASK(15, 8)
+-#define UNICAM_DLT3_MASK GENMASK(23, 16)
+-
+-/* UNICAM_ICTL Register */
+-#define UNICAM_FSIE BIT(0)
+-#define UNICAM_FEIE BIT(1)
+-#define UNICAM_IBOB BIT(2)
+-#define UNICAM_FCM BIT(3)
+-#define UNICAM_TFC BIT(4)
+-#define UNICAM_LIP_MASK GENMASK(6, 5)
+-#define UNICAM_LCIE_MASK GENMASK(28, 16)
+-
+-/* UNICAM_IDI0/1 Register */
+-#define UNICAM_ID0_MASK GENMASK(7, 0)
+-#define UNICAM_ID1_MASK GENMASK(15, 8)
+-#define UNICAM_ID2_MASK GENMASK(23, 16)
+-#define UNICAM_ID3_MASK GENMASK(31, 24)
+-
+-/* UNICAM_ISTA Register */
+-#define UNICAM_FSI BIT(0)
+-#define UNICAM_FEI BIT(1)
+-#define UNICAM_LCI BIT(2)
+-
+-#define UNICAM_ISTA_MASK_ALL (UNICAM_FSI + UNICAM_FEI + UNICAM_LCI)
+-
+-/* UNICAM_IPIPE Register */
+-#define UNICAM_PUM_MASK GENMASK(2, 0)
+- /* Unpacking modes */
+- #define UNICAM_PUM_NONE 0
+- #define UNICAM_PUM_UNPACK6 1
+- #define UNICAM_PUM_UNPACK7 2
+- #define UNICAM_PUM_UNPACK8 3
+- #define UNICAM_PUM_UNPACK10 4
+- #define UNICAM_PUM_UNPACK12 5
+- #define UNICAM_PUM_UNPACK14 6
+- #define UNICAM_PUM_UNPACK16 7
+-#define UNICAM_DDM_MASK GENMASK(6, 3)
+-#define UNICAM_PPM_MASK GENMASK(9, 7)
+- /* Packing modes */
+- #define UNICAM_PPM_NONE 0
+- #define UNICAM_PPM_PACK8 1
+- #define UNICAM_PPM_PACK10 2
+- #define UNICAM_PPM_PACK12 3
+- #define UNICAM_PPM_PACK14 4
+- #define UNICAM_PPM_PACK16 5
+-#define UNICAM_DEM_MASK GENMASK(11, 10)
+-#define UNICAM_DEBL_MASK GENMASK(14, 12)
+-#define UNICAM_ICM_MASK GENMASK(16, 15)
+-#define UNICAM_IDM_MASK GENMASK(17, 17)
+-
+-/* UNICAM_ICC Register */
+-#define UNICAM_ICFL_MASK GENMASK(4, 0)
+-#define UNICAM_ICFH_MASK GENMASK(9, 5)
+-#define UNICAM_ICST_MASK GENMASK(12, 10)
+-#define UNICAM_ICLT_MASK GENMASK(15, 13)
+-#define UNICAM_ICLL_MASK GENMASK(31, 16)
+-
+-/* UNICAM_DCS Register */
+-#define UNICAM_DIE BIT(0)
+-#define UNICAM_DIM BIT(1)
+-#define UNICAM_DBOB BIT(3)
+-#define UNICAM_FDE BIT(4)
+-#define UNICAM_LDP BIT(5)
+-#define UNICAM_EDL_MASK GENMASK(15, 8)
+-
+-/* UNICAM_DBCTL Register */
+-#define UNICAM_DBEN BIT(0)
+-#define UNICAM_BUF0_IE BIT(1)
+-#define UNICAM_BUF1_IE BIT(2)
+-
+-/* UNICAM_CMP[0,1] register */
+-#define UNICAM_PCE BIT(31)
+-#define UNICAM_GI BIT(9)
+-#define UNICAM_CPH BIT(8)
+-#define UNICAM_PCVC_MASK GENMASK(7, 6)
+-#define UNICAM_PCDT_MASK GENMASK(5, 0)
+-
+-/* UNICAM_MISC register */
+-#define UNICAM_FL0 BIT(6)
+-#define UNICAM_FL1 BIT(9)
+-
+-#endif
diff --git a/target/linux/bcm27xx/patches-5.4/950-0805-include-media-Add-vfl_devnode_type-of-VFL_TYPE_VIDEO.patch b/target/linux/bcm27xx/patches-5.4/950-0805-include-media-Add-vfl_devnode_type-of-VFL_TYPE_VIDEO.patch
new file mode 100644
index 0000000000..acd3034d21
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0805-include-media-Add-vfl_devnode_type-of-VFL_TYPE_VIDEO.patch
@@ -0,0 +1,25 @@
+From 7c74b86873fd5252becee33d092d8317ceff5f5b Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 23 Jun 2020 10:35:24 +0100
+Subject: [PATCH] include: media: Add vfl_devnode_type of
+ VFL_TYPE_VIDEO
+
+Upsstream are renaming VFL_TYPE_GRABBER to VFL_TYPE_VIDEO.
+To make backporting the upstream Unicam driver easier, add an
+extra enum entry (same as VFL_TYPE_GRABBER) to match that.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ include/media/v4l2-dev.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/media/v4l2-dev.h
++++ b/include/media/v4l2-dev.h
+@@ -34,6 +34,7 @@
+ */
+ enum vfl_devnode_type {
+ VFL_TYPE_GRABBER = 0,
++ VFL_TYPE_VIDEO = VFL_TYPE_GRABBER,
+ VFL_TYPE_VBI,
+ VFL_TYPE_RADIO,
+ VFL_TYPE_SUBDEV,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0806-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch b/target/linux/bcm27xx/patches-5.4/950-0806-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch
new file mode 100644
index 0000000000..561b1fda30
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0806-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch
@@ -0,0 +1,3150 @@
+From c339b677f34884fdbe0e6bcdda6d59b7ae30d118 Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Mon, 4 May 2020 12:25:41 +0300
+Subject: [PATCH] media: bcm2835-unicam: Driver for CCP2/CSI2 camera
+ interface
+
+Add a driver for the Unicam camera receiver block on BCM283x processors.
+Compared to the bcm2835-camera driver present in staging, this driver
+handles the Unicam block only (CSI-2 receiver), and doesn't depend on
+the VC4 firmware running on the VPU.
+
+The commit is made up of a series of changes cherry-picked from the
+rpi-5.4.y branch of https://github.com/raspberrypi/linux/ with
+additional enhancements, forward-ported to the mainline kernel.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reported-by: kbuild test robot <lkp@intel.com>
+---
+ MAINTAINERS | 2 +-
+ drivers/media/platform/bcm2835/Kconfig | 15 +
+ drivers/media/platform/bcm2835/Makefile | 3 +
+ .../media/platform/bcm2835/bcm2835-unicam.c | 2825 +++++++++++++++++
+ .../media/platform/bcm2835/vc4-regs-unicam.h | 253 ++
+ 5 files changed, 3097 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/media/platform/bcm2835/Kconfig
+ create mode 100644 drivers/media/platform/bcm2835/Makefile
+ create mode 100644 drivers/media/platform/bcm2835/bcm2835-unicam.c
+ create mode 100644 drivers/media/platform/bcm2835/vc4-regs-unicam.h
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -3210,7 +3210,7 @@ M: Raspberry Pi Kernel Maintenance <kern
+ L: linux-media@vger.kernel.org
+ S: Maintained
+ F: drivers/media/platform/bcm2835/
+-F: Documentation/devicetree/bindings/media/bcm2835-unicam.txt
++F: Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
+
+ BROADCOM BCM2835 ISP DRIVER
+ M: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
+--- /dev/null
++++ b/drivers/media/platform/bcm2835/Kconfig
+@@ -0,0 +1,15 @@
++# Broadcom VideoCore4 V4L2 camera support
++
++config VIDEO_BCM2835_UNICAM
++ tristate "Broadcom BCM2835 Unicam video capture driver"
++ depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER
++ depends on ARCH_BCM2835 || COMPILE_TEST
++ select VIDEOBUF2_DMA_CONTIG
++ select V4L2_FWNODE
++ help
++ Say Y here to enable support for the BCM2835 CSI-2 receiver. This is a
++ V4L2 driver that controls the CSI-2 receiver directly, independently
++ from the VC4 firmware.
++
++ To compile this driver as a module, choose M here. The module will be
++ called bcm2835-unicam.
+--- /dev/null
++++ b/drivers/media/platform/bcm2835/Makefile
+@@ -0,0 +1,3 @@
++# Makefile for BCM2835 Unicam driver
++
++obj-$(CONFIG_VIDEO_BCM2835_UNICAM) += bcm2835-unicam.o
+--- /dev/null
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -0,0 +1,2825 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * BCM2835 Unicam Capture Driver
++ *
++ * Copyright (C) 2017-2020 - Raspberry Pi (Trading) Ltd.
++ *
++ * Dave Stevenson <dave.stevenson@raspberrypi.com>
++ *
++ * Based on TI am437x driver by
++ * Benoit Parrot <bparrot@ti.com>
++ * Lad, Prabhakar <prabhakar.csengg@gmail.com>
++ *
++ * and TI CAL camera interface driver by
++ * Benoit Parrot <bparrot@ti.com>
++ *
++ *
++ * There are two camera drivers in the kernel for BCM283x - this one
++ * and bcm2835-camera (currently in staging).
++ *
++ * This driver directly controls the Unicam peripheral - there is no
++ * involvement with the VideoCore firmware. Unicam receives CSI-2 or
++ * CCP2 data and writes it into SDRAM.
++ * The only potential processing options are to repack Bayer data into an
++ * alternate format, and applying windowing.
++ * The repacking does not shift the data, so can repack V4L2_PIX_FMT_Sxxxx10P
++ * to V4L2_PIX_FMT_Sxxxx10, or V4L2_PIX_FMT_Sxxxx12P to V4L2_PIX_FMT_Sxxxx12,
++ * but not generically up to V4L2_PIX_FMT_Sxxxx16. The driver will add both
++ * formats where the relevant formats are defined, and will automatically
++ * configure the repacking as required.
++ * Support for windowing may be added later.
++ *
++ * It should be possible to connect this driver to any sensor with a
++ * suitable output interface and V4L2 subdevice driver.
++ *
++ * bcm2835-camera uses the VideoCore firmware to control the sensor,
++ * Unicam, ISP, and all tuner control loops. Fully processed frames are
++ * delivered to the driver by the firmware. It only has sensor drivers
++ * for Omnivision OV5647, and Sony IMX219 sensors.
++ *
++ * The two drivers are mutually exclusive for the same Unicam instance.
++ * The VideoCore firmware checks the device tree configuration during boot.
++ * If it finds device tree nodes called csi0 or csi1 it will block the
++ * firmware from accessing the peripheral, and bcm2835-camera will
++ * not be able to stream data.
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/dma-mapping.h>
++#include <linux/err.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/of_device.h>
++#include <linux/of_graph.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/slab.h>
++#include <linux/uaccess.h>
++#include <linux/videodev2.h>
++
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-dev.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-dv-timings.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-ioctl.h>
++#include <media/v4l2-fwnode.h>
++#include <media/videobuf2-dma-contig.h>
++
++#include "vc4-regs-unicam.h"
++
++#define UNICAM_MODULE_NAME "unicam"
++#define UNICAM_VERSION "0.1.0"
++
++static int debug;
++module_param(debug, int, 0644);
++MODULE_PARM_DESC(debug, "Debug level 0-3");
++
++#define unicam_dbg(level, dev, fmt, arg...) \
++ v4l2_dbg(level, debug, &(dev)->v4l2_dev, fmt, ##arg)
++#define unicam_info(dev, fmt, arg...) \
++ v4l2_info(&(dev)->v4l2_dev, fmt, ##arg)
++#define unicam_err(dev, fmt, arg...) \
++ v4l2_err(&(dev)->v4l2_dev, fmt, ##arg)
++
++/*
++ * To protect against a dodgy sensor driver never returning an error from
++ * enum_mbus_code, set a maximum index value to be used.
++ */
++#define MAX_ENUM_MBUS_CODE 128
++
++/*
++ * Stride is a 16 bit register, but also has to be a multiple of 32.
++ */
++#define BPL_ALIGNMENT 32
++#define MAX_BYTESPERLINE ((1 << 16) - BPL_ALIGNMENT)
++/*
++ * Max width is therefore determined by the max stride divided by
++ * the number of bits per pixel. Take 32bpp as a
++ * worst case.
++ * No imposed limit on the height, so adopt a square image for want
++ * of anything better.
++ */
++#define MAX_WIDTH (MAX_BYTESPERLINE / 4)
++#define MAX_HEIGHT MAX_WIDTH
++/* Define a nominal minimum image size */
++#define MIN_WIDTH 16
++#define MIN_HEIGHT 16
++/* Default size of the embedded buffer */
++#define UNICAM_EMBEDDED_SIZE 8192
++
++/*
++ * Size of the dummy buffer. Can be any size really, but the DMA
++ * allocation works in units of page sizes.
++ */
++#define DUMMY_BUF_SIZE (PAGE_SIZE)
++
++enum pad_types {
++ IMAGE_PAD,
++ METADATA_PAD,
++ MAX_NODES
++};
++
++/*
++ * struct unicam_fmt - Unicam media bus format information
++ * @pixelformat: V4L2 pixel format FCC identifier. 0 if n/a.
++ * @repacked_fourcc: V4L2 pixel format FCC identifier if the data is expanded
++ * out to 16bpp. 0 if n/a.
++ * @code: V4L2 media bus format code.
++ * @depth: Bits per pixel as delivered from the source.
++ * @csi_dt: CSI data type.
++ * @check_variants: Flag to denote that there are multiple mediabus formats
++ * still in the list that could match this V4L2 format.
++ */
++struct unicam_fmt {
++ u32 fourcc;
++ u32 repacked_fourcc;
++ u32 code;
++ u8 depth;
++ u8 csi_dt;
++ u8 check_variants;
++};
++
++static const struct unicam_fmt formats[] = {
++ /* YUV Formats */
++ {
++ .fourcc = V4L2_PIX_FMT_YUYV,
++ .code = MEDIA_BUS_FMT_YUYV8_2X8,
++ .depth = 16,
++ .csi_dt = 0x1e,
++ .check_variants = 1,
++ }, {
++ .fourcc = V4L2_PIX_FMT_UYVY,
++ .code = MEDIA_BUS_FMT_UYVY8_2X8,
++ .depth = 16,
++ .csi_dt = 0x1e,
++ .check_variants = 1,
++ }, {
++ .fourcc = V4L2_PIX_FMT_YVYU,
++ .code = MEDIA_BUS_FMT_YVYU8_2X8,
++ .depth = 16,
++ .csi_dt = 0x1e,
++ .check_variants = 1,
++ }, {
++ .fourcc = V4L2_PIX_FMT_VYUY,
++ .code = MEDIA_BUS_FMT_VYUY8_2X8,
++ .depth = 16,
++ .csi_dt = 0x1e,
++ .check_variants = 1,
++ }, {
++ .fourcc = V4L2_PIX_FMT_YUYV,
++ .code = MEDIA_BUS_FMT_YUYV8_1X16,
++ .depth = 16,
++ .csi_dt = 0x1e,
++ }, {
++ .fourcc = V4L2_PIX_FMT_UYVY,
++ .code = MEDIA_BUS_FMT_UYVY8_1X16,
++ .depth = 16,
++ .csi_dt = 0x1e,
++ }, {
++ .fourcc = V4L2_PIX_FMT_YVYU,
++ .code = MEDIA_BUS_FMT_YVYU8_1X16,
++ .depth = 16,
++ .csi_dt = 0x1e,
++ }, {
++ .fourcc = V4L2_PIX_FMT_VYUY,
++ .code = MEDIA_BUS_FMT_VYUY8_1X16,
++ .depth = 16,
++ .csi_dt = 0x1e,
++ }, {
++ /* RGB Formats */
++ .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
++ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
++ .depth = 16,
++ .csi_dt = 0x22,
++ }, {
++ .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
++ .code = MEDIA_BUS_FMT_RGB565_2X8_BE,
++ .depth = 16,
++ .csi_dt = 0x22
++ }, {
++ .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
++ .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
++ .depth = 16,
++ .csi_dt = 0x21,
++ }, {
++ .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
++ .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
++ .depth = 16,
++ .csi_dt = 0x21,
++ }, {
++ .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */
++ .code = MEDIA_BUS_FMT_RGB888_1X24,
++ .depth = 24,
++ .csi_dt = 0x24,
++ }, {
++ .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */
++ .code = MEDIA_BUS_FMT_BGR888_1X24,
++ .depth = 24,
++ .csi_dt = 0x24,
++ }, {
++ .fourcc = V4L2_PIX_FMT_RGB32, /* argb */
++ .code = MEDIA_BUS_FMT_ARGB8888_1X32,
++ .depth = 32,
++ .csi_dt = 0x0,
++ }, {
++ /* Bayer Formats */
++ .fourcc = V4L2_PIX_FMT_SBGGR8,
++ .code = MEDIA_BUS_FMT_SBGGR8_1X8,
++ .depth = 8,
++ .csi_dt = 0x2a,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SGBRG8,
++ .code = MEDIA_BUS_FMT_SGBRG8_1X8,
++ .depth = 8,
++ .csi_dt = 0x2a,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SGRBG8,
++ .code = MEDIA_BUS_FMT_SGRBG8_1X8,
++ .depth = 8,
++ .csi_dt = 0x2a,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SRGGB8,
++ .code = MEDIA_BUS_FMT_SRGGB8_1X8,
++ .depth = 8,
++ .csi_dt = 0x2a,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SBGGR10P,
++ .repacked_fourcc = V4L2_PIX_FMT_SBGGR10,
++ .code = MEDIA_BUS_FMT_SBGGR10_1X10,
++ .depth = 10,
++ .csi_dt = 0x2b,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SGBRG10P,
++ .repacked_fourcc = V4L2_PIX_FMT_SGBRG10,
++ .code = MEDIA_BUS_FMT_SGBRG10_1X10,
++ .depth = 10,
++ .csi_dt = 0x2b,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SGRBG10P,
++ .repacked_fourcc = V4L2_PIX_FMT_SGRBG10,
++ .code = MEDIA_BUS_FMT_SGRBG10_1X10,
++ .depth = 10,
++ .csi_dt = 0x2b,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SRGGB10P,
++ .repacked_fourcc = V4L2_PIX_FMT_SRGGB10,
++ .code = MEDIA_BUS_FMT_SRGGB10_1X10,
++ .depth = 10,
++ .csi_dt = 0x2b,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SBGGR12P,
++ .repacked_fourcc = V4L2_PIX_FMT_SBGGR12,
++ .code = MEDIA_BUS_FMT_SBGGR12_1X12,
++ .depth = 12,
++ .csi_dt = 0x2c,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SGBRG12P,
++ .repacked_fourcc = V4L2_PIX_FMT_SGBRG12,
++ .code = MEDIA_BUS_FMT_SGBRG12_1X12,
++ .depth = 12,
++ .csi_dt = 0x2c,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SGRBG12P,
++ .repacked_fourcc = V4L2_PIX_FMT_SGRBG12,
++ .code = MEDIA_BUS_FMT_SGRBG12_1X12,
++ .depth = 12,
++ .csi_dt = 0x2c,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SRGGB12P,
++ .repacked_fourcc = V4L2_PIX_FMT_SRGGB12,
++ .code = MEDIA_BUS_FMT_SRGGB12_1X12,
++ .depth = 12,
++ .csi_dt = 0x2c,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SBGGR14P,
++ .code = MEDIA_BUS_FMT_SBGGR14_1X14,
++ .depth = 14,
++ .csi_dt = 0x2d,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SGBRG14P,
++ .code = MEDIA_BUS_FMT_SGBRG14_1X14,
++ .depth = 14,
++ .csi_dt = 0x2d,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SGRBG14P,
++ .code = MEDIA_BUS_FMT_SGRBG14_1X14,
++ .depth = 14,
++ .csi_dt = 0x2d,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SRGGB14P,
++ .code = MEDIA_BUS_FMT_SRGGB14_1X14,
++ .depth = 14,
++ .csi_dt = 0x2d,
++ }, {
++ /*
++ * 16 bit Bayer formats could be supported, but there is no CSI2
++ * data_type defined for raw 16, and no sensors that produce it at
++ * present.
++ */
++
++ /* Greyscale formats */
++ .fourcc = V4L2_PIX_FMT_GREY,
++ .code = MEDIA_BUS_FMT_Y8_1X8,
++ .depth = 8,
++ .csi_dt = 0x2a,
++ }, {
++ .fourcc = V4L2_PIX_FMT_Y10P,
++ .repacked_fourcc = V4L2_PIX_FMT_Y10,
++ .code = MEDIA_BUS_FMT_Y10_1X10,
++ .depth = 10,
++ .csi_dt = 0x2b,
++ }, {
++ /* NB There is no packed V4L2 fourcc for this format. */
++ .repacked_fourcc = V4L2_PIX_FMT_Y12,
++ .code = MEDIA_BUS_FMT_Y12_1X12,
++ .depth = 12,
++ .csi_dt = 0x2c,
++ },
++ /* Embedded data format */
++ {
++ .fourcc = V4L2_META_FMT_SENSOR_DATA,
++ .code = MEDIA_BUS_FMT_SENSOR_DATA,
++ .depth = 8,
++ }
++};
++
++struct unicam_buffer {
++ struct vb2_v4l2_buffer vb;
++ struct list_head list;
++};
++
++static inline struct unicam_buffer *to_unicam_buffer(struct vb2_buffer *vb)
++{
++ return container_of(vb, struct unicam_buffer, vb.vb2_buf);
++}
++
++struct unicam_node {
++ bool registered;
++ int open;
++ bool streaming;
++ unsigned int pad_id;
++ /* Pointer pointing to current v4l2_buffer */
++ struct unicam_buffer *cur_frm;
++ /* Pointer pointing to next v4l2_buffer */
++ struct unicam_buffer *next_frm;
++ /* video capture */
++ const struct unicam_fmt *fmt;
++ /* Used to store current pixel format */
++ struct v4l2_format v_fmt;
++ /* Used to store current mbus frame format */
++ struct v4l2_mbus_framefmt m_fmt;
++ /* Buffer queue used in video-buf */
++ struct vb2_queue buffer_queue;
++ /* Queue of filled frames */
++ struct list_head dma_queue;
++ /* IRQ lock for DMA queue */
++ spinlock_t dma_queue_lock;
++ /* lock used to access this structure */
++ struct mutex lock;
++ /* Identifies video device for this channel */
++ struct video_device video_dev;
++ /* Pointer to the parent handle */
++ struct unicam_device *dev;
++ struct media_pad pad;
++ unsigned int embedded_lines;
++ /*
++ * Dummy buffer intended to be used by unicam
++ * if we have no other queued buffers to swap to.
++ */
++ void *dummy_buf_cpu_addr;
++ dma_addr_t dummy_buf_dma_addr;
++};
++
++struct unicam_device {
++ struct kref kref;
++
++ /* V4l2 specific parameters */
++ struct v4l2_async_subdev asd;
++
++ /* peripheral base address */
++ void __iomem *base;
++ /* clock gating base address */
++ void __iomem *clk_gate_base;
++ /* clock handle */
++ struct clk *clock;
++ /* V4l2 device */
++ struct v4l2_device v4l2_dev;
++ struct media_device mdev;
++
++ /* parent device */
++ struct platform_device *pdev;
++ /* subdevice async Notifier */
++ struct v4l2_async_notifier notifier;
++ unsigned int sequence;
++
++ /* ptr to sub device */
++ struct v4l2_subdev *sensor;
++ /* Pad config for the sensor */
++ struct v4l2_subdev_pad_config *sensor_config;
++
++ enum v4l2_mbus_type bus_type;
++ /*
++ * Stores bus.mipi_csi2.flags for CSI2 sensors, or
++ * bus.mipi_csi1.strobe for CCP2.
++ */
++ unsigned int bus_flags;
++ unsigned int max_data_lanes;
++ unsigned int active_data_lanes;
++ bool sensor_embedded_data;
++
++ struct unicam_node node[MAX_NODES];
++ struct v4l2_ctrl_handler ctrl_handler;
++};
++
++static inline struct unicam_device *
++to_unicam_device(struct v4l2_device *v4l2_dev)
++{
++ return container_of(v4l2_dev, struct unicam_device, v4l2_dev);
++}
++
++/* Hardware access */
++static inline void clk_write(struct unicam_device *dev, u32 val)
++{
++ writel(val | 0x5a000000, dev->clk_gate_base);
++}
++
++static inline u32 reg_read(struct unicam_device *dev, u32 offset)
++{
++ return readl(dev->base + offset);
++}
++
++static inline void reg_write(struct unicam_device *dev, u32 offset, u32 val)
++{
++ writel(val, dev->base + offset);
++}
++
++static inline int get_field(u32 value, u32 mask)
++{
++ return (value & mask) >> __ffs(mask);
++}
++
++static inline void set_field(u32 *valp, u32 field, u32 mask)
++{
++ u32 val = *valp;
++
++ val &= ~mask;
++ val |= (field << __ffs(mask)) & mask;
++ *valp = val;
++}
++
++static inline u32 reg_read_field(struct unicam_device *dev, u32 offset,
++ u32 mask)
++{
++ return get_field(reg_read(dev, offset), mask);
++}
++
++static inline void reg_write_field(struct unicam_device *dev, u32 offset,
++ u32 field, u32 mask)
++{
++ u32 val = reg_read(dev, offset);
++
++ set_field(&val, field, mask);
++ reg_write(dev, offset, val);
++}
++
++/* Power management functions */
++static inline int unicam_runtime_get(struct unicam_device *dev)
++{
++ return pm_runtime_get_sync(&dev->pdev->dev);
++}
++
++static inline void unicam_runtime_put(struct unicam_device *dev)
++{
++ pm_runtime_put_sync(&dev->pdev->dev);
++}
++
++/* Format setup functions */
++static const struct unicam_fmt *find_format_by_code(u32 code)
++{
++ unsigned int i;
++
++ for (i = 0; i < ARRAY_SIZE(formats); i++) {
++ if (formats[i].code == code)
++ return &formats[i];
++ }
++
++ return NULL;
++}
++
++static int check_mbus_format(struct unicam_device *dev,
++ const struct unicam_fmt *format)
++{
++ unsigned int i;
++ int ret = 0;
++
++ for (i = 0; !ret && i < MAX_ENUM_MBUS_CODE; i++) {
++ struct v4l2_subdev_mbus_code_enum mbus_code = {
++ .index = i,
++ .pad = IMAGE_PAD,
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++
++ ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code,
++ NULL, &mbus_code);
++
++ if (!ret && mbus_code.code == format->code)
++ return 1;
++ }
++
++ return 0;
++}
++
++static const struct unicam_fmt *find_format_by_pix(struct unicam_device *dev,
++ u32 pixelformat)
++{
++ unsigned int i;
++
++ for (i = 0; i < ARRAY_SIZE(formats); i++) {
++ if (formats[i].fourcc == pixelformat ||
++ formats[i].repacked_fourcc == pixelformat) {
++ if (formats[i].check_variants &&
++ !check_mbus_format(dev, &formats[i]))
++ continue;
++ return &formats[i];
++ }
++ }
++
++ return NULL;
++}
++
++static inline unsigned int bytes_per_line(u32 width,
++ const struct unicam_fmt *fmt,
++ u32 v4l2_fourcc)
++{
++ if (v4l2_fourcc == fmt->repacked_fourcc)
++ /* Repacking always goes to 16bpp */
++ return ALIGN(width << 1, BPL_ALIGNMENT);
++ else
++ return ALIGN((width * fmt->depth) >> 3, BPL_ALIGNMENT);
++}
++
++static int __subdev_get_format(struct unicam_device *dev,
++ struct v4l2_mbus_framefmt *fmt, int pad_id)
++{
++ struct v4l2_subdev_format sd_fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .pad = pad_id
++ };
++ int ret;
++
++ ret = v4l2_subdev_call(dev->sensor, pad, get_fmt, dev->sensor_config,
++ &sd_fmt);
++ if (ret < 0)
++ return ret;
++
++ *fmt = sd_fmt.format;
++
++ unicam_dbg(1, dev, "%s %dx%d code:%04x\n", __func__,
++ fmt->width, fmt->height, fmt->code);
++
++ return 0;
++}
++
++static int __subdev_set_format(struct unicam_device *dev,
++ struct v4l2_mbus_framefmt *fmt, int pad_id)
++{
++ struct v4l2_subdev_format sd_fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .pad = pad_id
++ };
++ int ret;
++
++ sd_fmt.format = *fmt;
++
++ ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_config,
++ &sd_fmt);
++ if (ret < 0)
++ return ret;
++
++ *fmt = sd_fmt.format;
++
++ if (pad_id == IMAGE_PAD)
++ unicam_dbg(1, dev, "%s %dx%d code:%04x\n", __func__, fmt->width,
++ fmt->height, fmt->code);
++ else
++ unicam_dbg(1, dev, "%s Embedded data code:%04x\n", __func__,
++ sd_fmt.format.code);
++
++ return 0;
++}
++
++static int unicam_calc_format_size_bpl(struct unicam_device *dev,
++ const struct unicam_fmt *fmt,
++ struct v4l2_format *f)
++{
++ unsigned int min_bytesperline;
++
++ v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 2,
++ &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 0,
++ 0);
++
++ min_bytesperline = bytes_per_line(f->fmt.pix.width, fmt,
++ f->fmt.pix.pixelformat);
++
++ if (f->fmt.pix.bytesperline > min_bytesperline &&
++ f->fmt.pix.bytesperline <= MAX_BYTESPERLINE)
++ f->fmt.pix.bytesperline = ALIGN(f->fmt.pix.bytesperline,
++ BPL_ALIGNMENT);
++ else
++ f->fmt.pix.bytesperline = min_bytesperline;
++
++ f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
++
++ unicam_dbg(3, dev, "%s: fourcc: %08X size: %dx%d bpl:%d img_size:%d\n",
++ __func__,
++ f->fmt.pix.pixelformat,
++ f->fmt.pix.width, f->fmt.pix.height,
++ f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
++
++ return 0;
++}
++
++static int unicam_reset_format(struct unicam_node *node)
++{
++ struct unicam_device *dev = node->dev;
++ struct v4l2_mbus_framefmt mbus_fmt;
++ int ret;
++
++ if (dev->sensor_embedded_data || node->pad_id != METADATA_PAD) {
++ ret = __subdev_get_format(dev, &mbus_fmt, node->pad_id);
++ if (ret) {
++ unicam_err(dev, "Failed to get_format - ret %d\n", ret);
++ return ret;
++ }
++
++ if (mbus_fmt.code != node->fmt->code) {
++ unicam_err(dev, "code mismatch - fmt->code %08x, mbus_fmt.code %08x\n",
++ node->fmt->code, mbus_fmt.code);
++ return ret;
++ }
++ }
++
++ if (node->pad_id == IMAGE_PAD) {
++ v4l2_fill_pix_format(&node->v_fmt.fmt.pix, &mbus_fmt);
++ node->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++ unicam_calc_format_size_bpl(dev, node->fmt, &node->v_fmt);
++ } else {
++ node->v_fmt.type = V4L2_BUF_TYPE_META_CAPTURE;
++ node->v_fmt.fmt.meta.dataformat = V4L2_META_FMT_SENSOR_DATA;
++ if (dev->sensor_embedded_data) {
++ node->v_fmt.fmt.meta.buffersize =
++ mbus_fmt.width * mbus_fmt.height;
++ node->embedded_lines = mbus_fmt.height;
++ } else {
++ node->v_fmt.fmt.meta.buffersize = UNICAM_EMBEDDED_SIZE;
++ node->embedded_lines = 1;
++ }
++ }
++
++ node->m_fmt = mbus_fmt;
++ return 0;
++}
++
++static void unicam_wr_dma_addr(struct unicam_device *dev, dma_addr_t dmaaddr,
++ unsigned int buffer_size, int pad_id)
++{
++ dma_addr_t endaddr = dmaaddr + buffer_size;
++
++ /*
++ * dmaaddr and endaddr should be a 32-bit address with the top two bits
++ * set to 0x3 to signify uncached access through the Videocore memory
++ * controller.
++ */
++ WARN_ON((dmaaddr >> 30) != 0x3 || (endaddr >> 30) != 0x3);
++
++ if (pad_id == IMAGE_PAD) {
++ reg_write(dev, UNICAM_IBSA0, dmaaddr);
++ reg_write(dev, UNICAM_IBEA0, endaddr);
++ } else {
++ reg_write(dev, UNICAM_DBSA0, dmaaddr);
++ reg_write(dev, UNICAM_DBEA0, endaddr);
++ }
++}
++
++static inline unsigned int unicam_get_lines_done(struct unicam_device *dev)
++{
++ dma_addr_t start_addr, cur_addr;
++ unsigned int stride = dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline;
++ struct unicam_buffer *frm = dev->node[IMAGE_PAD].cur_frm;
++
++ if (!frm)
++ return 0;
++
++ start_addr = vb2_dma_contig_plane_dma_addr(&frm->vb.vb2_buf, 0);
++ cur_addr = reg_read(dev, UNICAM_IBWP);
++ return (unsigned int)(cur_addr - start_addr) / stride;
++}
++
++static inline void unicam_schedule_next_buffer(struct unicam_node *node)
++{
++ struct unicam_device *dev = node->dev;
++ struct unicam_buffer *buf;
++ unsigned int size;
++ dma_addr_t addr;
++
++ buf = list_first_entry(&node->dma_queue, struct unicam_buffer, list);
++ node->next_frm = buf;
++ list_del(&buf->list);
++
++ addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
++ size = (node->pad_id == IMAGE_PAD) ?
++ node->v_fmt.fmt.pix.sizeimage :
++ node->v_fmt.fmt.meta.buffersize;
++
++ unicam_wr_dma_addr(dev, addr, size, node->pad_id);
++}
++
++static inline void unicam_schedule_dummy_buffer(struct unicam_node *node)
++{
++ struct unicam_device *dev = node->dev;
++
++ unicam_dbg(3, dev, "Scheduling dummy buffer for node %d\n",
++ node->pad_id);
++
++ unicam_wr_dma_addr(dev, node->dummy_buf_dma_addr, DUMMY_BUF_SIZE,
++ node->pad_id);
++ node->next_frm = NULL;
++}
++
++static inline void unicam_process_buffer_complete(struct unicam_node *node,
++ unsigned int sequence)
++{
++ node->cur_frm->vb.field = node->m_fmt.field;
++ node->cur_frm->vb.sequence = sequence;
++
++ vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
++}
++
++static bool unicam_all_nodes_streaming(struct unicam_device *dev)
++{
++ bool ret;
++
++ ret = dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming;
++ ret &= !dev->node[METADATA_PAD].open ||
++ dev->node[METADATA_PAD].streaming;
++ return ret;
++}
++
++static bool unicam_all_nodes_disabled(struct unicam_device *dev)
++{
++ return !dev->node[IMAGE_PAD].streaming &&
++ !dev->node[METADATA_PAD].streaming;
++}
++
++static void unicam_queue_event_sof(struct unicam_device *unicam)
++{
++ struct v4l2_event event = {
++ .type = V4L2_EVENT_FRAME_SYNC,
++ .u.frame_sync.frame_sequence = unicam->sequence,
++ };
++
++ v4l2_event_queue(&unicam->node[IMAGE_PAD].video_dev, &event);
++}
++
++/*
++ * unicam_isr : ISR handler for unicam capture
++ * @irq: irq number
++ * @dev_id: dev_id ptr
++ *
++ * It changes status of the captured buffer, takes next buffer from the queue
++ * and sets its address in unicam registers
++ */
++static irqreturn_t unicam_isr(int irq, void *dev)
++{
++ struct unicam_device *unicam = dev;
++ unsigned int lines_done = unicam_get_lines_done(dev);
++ unsigned int sequence = unicam->sequence;
++ unsigned int i;
++ u32 ista, sta;
++ u64 ts;
++
++ /*
++ * Don't service interrupts if not streaming.
++ * Avoids issues if the VPU should enable the
++ * peripheral without the kernel knowing (that
++ * shouldn't happen, but causes issues if it does).
++ */
++ if (unicam_all_nodes_disabled(unicam))
++ return IRQ_NONE;
++
++ sta = reg_read(unicam, UNICAM_STA);
++ /* Write value back to clear the interrupts */
++ reg_write(unicam, UNICAM_STA, sta);
++
++ ista = reg_read(unicam, UNICAM_ISTA);
++ /* Write value back to clear the interrupts */
++ reg_write(unicam, UNICAM_ISTA, ista);
++
++ unicam_dbg(3, unicam, "ISR: ISTA: 0x%X, STA: 0x%X, sequence %d, lines done %d",
++ ista, sta, sequence, lines_done);
++
++ if (!(sta & (UNICAM_IS | UNICAM_PI0)))
++ return IRQ_HANDLED;
++
++ /*
++ * We must run the frame end handler first. If we have a valid next_frm
++ * and we get a simultaneout FE + FS interrupt, running the FS handler
++ * first would null out the next_frm ptr and we would have lost the
++ * buffer forever.
++ */
++ if (ista & UNICAM_FEI || sta & UNICAM_PI0) {
++ /*
++ * Ensure we have swapped buffers already as we can't
++ * stop the peripheral. If no buffer is available, use a
++ * dummy buffer to dump out frames until we get a new buffer
++ * to use.
++ */
++ for (i = 0; i < ARRAY_SIZE(unicam->node); i++) {
++ if (!unicam->node[i].streaming)
++ continue;
++
++ if (unicam->node[i].cur_frm)
++ unicam_process_buffer_complete(&unicam->node[i],
++ sequence);
++ unicam->node[i].cur_frm = unicam->node[i].next_frm;
++ }
++ unicam->sequence++;
++ }
++
++ if (ista & UNICAM_FSI) {
++ /*
++ * Timestamp is to be when the first data byte was captured,
++ * aka frame start.
++ */
++ ts = ktime_get_ns();
++ for (i = 0; i < ARRAY_SIZE(unicam->node); i++) {
++ if (!unicam->node[i].streaming)
++ continue;
++
++ if (unicam->node[i].cur_frm)
++ unicam->node[i].cur_frm->vb.vb2_buf.timestamp =
++ ts;
++ /*
++ * Set the next frame output to go to a dummy frame
++ * if we have not managed to obtain another frame
++ * from the queue.
++ */
++ unicam_schedule_dummy_buffer(&unicam->node[i]);
++ }
++
++ unicam_queue_event_sof(unicam);
++ }
++
++ /*
++ * Cannot swap buffer at frame end, there may be a race condition
++ * where the HW does not actually swap it if the new frame has
++ * already started.
++ */
++ if (ista & (UNICAM_FSI | UNICAM_LCI) && !(ista & UNICAM_FEI)) {
++ for (i = 0; i < ARRAY_SIZE(unicam->node); i++) {
++ if (!unicam->node[i].streaming)
++ continue;
++
++ spin_lock(&unicam->node[i].dma_queue_lock);
++ if (!list_empty(&unicam->node[i].dma_queue) &&
++ !unicam->node[i].next_frm)
++ unicam_schedule_next_buffer(&unicam->node[i]);
++ spin_unlock(&unicam->node[i].dma_queue_lock);
++ }
++ }
++
++ if (reg_read(unicam, UNICAM_ICTL) & UNICAM_FCM) {
++ /* Switch out of trigger mode if selected */
++ reg_write_field(unicam, UNICAM_ICTL, 1, UNICAM_TFC);
++ reg_write_field(unicam, UNICAM_ICTL, 0, UNICAM_FCM);
++ }
++ return IRQ_HANDLED;
++}
++
++static int unicam_querycap(struct file *file, void *priv,
++ struct v4l2_capability *cap)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++
++ strlcpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver));
++ strlcpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card));
++
++ snprintf(cap->bus_info, sizeof(cap->bus_info),
++ "platform:%s", dev_name(&dev->pdev->dev));
++
++ cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_META_CAPTURE;
++
++ return 0;
++}
++
++static int unicam_enum_fmt_vid_cap(struct file *file, void *priv,
++ struct v4l2_fmtdesc *f)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++ unsigned int index = 0;
++ unsigned int i;
++ int ret = 0;
++
++ if (node->pad_id != IMAGE_PAD)
++ return -EINVAL;
++
++ for (i = 0; !ret && i < MAX_ENUM_MBUS_CODE; i++) {
++ struct v4l2_subdev_mbus_code_enum mbus_code = {
++ .index = i,
++ .pad = IMAGE_PAD,
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ const struct unicam_fmt *fmt;
++
++ ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code,
++ NULL, &mbus_code);
++ if (ret < 0) {
++ unicam_dbg(2, dev,
++ "subdev->enum_mbus_code idx %d returned %d - index invalid\n",
++ i, ret);
++ return -EINVAL;
++ }
++
++ fmt = find_format_by_code(mbus_code.code);
++ if (fmt) {
++ if (fmt->fourcc) {
++ if (index == f->index) {
++ f->pixelformat = fmt->fourcc;
++ break;
++ }
++ index++;
++ }
++ if (fmt->repacked_fourcc) {
++ if (index == f->index) {
++ f->pixelformat = fmt->repacked_fourcc;
++ break;
++ }
++ index++;
++ }
++ }
++ }
++
++ return 0;
++}
++
++static int unicam_g_fmt_vid_cap(struct file *file, void *priv,
++ struct v4l2_format *f)
++{
++ struct v4l2_mbus_framefmt mbus_fmt = {0};
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++ const struct unicam_fmt *fmt = NULL;
++ int ret;
++
++ if (node->pad_id != IMAGE_PAD)
++ return -EINVAL;
++
++ /*
++ * If a flip has occurred in the sensor, the fmt code might have
++ * changed. So we will need to re-fetch the format from the subdevice.
++ */
++ ret = __subdev_get_format(dev, &mbus_fmt, node->pad_id);
++ if (ret)
++ return -EINVAL;
++
++ /* Find the V4L2 format from mbus code. We must match a known format. */
++ fmt = find_format_by_code(mbus_fmt.code);
++ if (!fmt)
++ return -EINVAL;
++
++ node->fmt = fmt;
++ node->v_fmt.fmt.pix.pixelformat = fmt->fourcc;
++ *f = node->v_fmt;
++
++ return 0;
++}
++
++static
++const struct unicam_fmt *get_first_supported_format(struct unicam_device *dev)
++{
++ struct v4l2_subdev_mbus_code_enum mbus_code;
++ const struct unicam_fmt *fmt = NULL;
++ unsigned int i;
++ int ret;
++
++ for (i = 0; ret != -EINVAL && ret != -ENOIOCTLCMD; ++i) {
++ memset(&mbus_code, 0, sizeof(mbus_code));
++ mbus_code.index = i;
++ mbus_code.pad = IMAGE_PAD;
++ mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++
++ ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, NULL,
++ &mbus_code);
++ if (ret < 0) {
++ unicam_dbg(2, dev,
++ "subdev->enum_mbus_code idx %u returned %d - continue\n",
++ i, ret);
++ continue;
++ }
++
++ unicam_dbg(2, dev, "subdev %s: code: 0x%08x idx: %u\n",
++ dev->sensor->name, mbus_code.code, i);
++
++ fmt = find_format_by_code(mbus_code.code);
++ unicam_dbg(2, dev, "fmt 0x%08x returned as %p, V4L2 FOURCC 0x%08x, csi_dt 0x%02x\n",
++ mbus_code.code, fmt, fmt ? fmt->fourcc : 0,
++ fmt ? fmt->csi_dt : 0);
++ if (fmt)
++ return fmt;
++ }
++
++ return NULL;
++}
++
++static int unicam_try_fmt_vid_cap(struct file *file, void *priv,
++ struct v4l2_format *f)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++ struct v4l2_subdev_format sd_fmt = {
++ .which = V4L2_SUBDEV_FORMAT_TRY,
++ .pad = IMAGE_PAD
++ };
++ struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format;
++ const struct unicam_fmt *fmt;
++ int ret;
++
++ if (node->pad_id != IMAGE_PAD)
++ return -EINVAL;
++
++ fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat);
++ if (!fmt) {
++ /*
++ * Pixel format not supported by unicam. Choose the first
++ * supported format, and let the sensor choose something else.
++ */
++ unicam_dbg(3, dev, "Fourcc format (0x%08x) not found. Use first format.\n",
++ f->fmt.pix.pixelformat);
++
++ fmt = &formats[0];
++ f->fmt.pix.pixelformat = fmt->fourcc;
++ }
++
++ v4l2_fill_mbus_format(mbus_fmt, &f->fmt.pix, fmt->code);
++ /*
++ * No support for receiving interlaced video, so never
++ * request it from the sensor subdev.
++ */
++ mbus_fmt->field = V4L2_FIELD_NONE;
++
++ ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_config,
++ &sd_fmt);
++ if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)
++ return ret;
++
++ if (mbus_fmt->field != V4L2_FIELD_NONE)
++ unicam_info(dev, "Sensor trying to send interlaced video - results may be unpredictable\n");
++
++ v4l2_fill_pix_format(&f->fmt.pix, &sd_fmt.format);
++ if (mbus_fmt->code != fmt->code) {
++ /* Sensor has returned an alternate format */
++ fmt = find_format_by_code(mbus_fmt->code);
++ if (!fmt) {
++ /*
++ * The alternate format is one unicam can't support.
++ * Find the first format that is supported by both, and
++ * then set that.
++ */
++ fmt = get_first_supported_format(dev);
++ mbus_fmt->code = fmt->code;
++
++ ret = v4l2_subdev_call(dev->sensor, pad, set_fmt,
++ dev->sensor_config, &sd_fmt);
++ if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)
++ return ret;
++
++ if (mbus_fmt->field != V4L2_FIELD_NONE)
++ unicam_info(dev, "Sensor trying to send interlaced video - results may be unpredictable\n");
++
++ v4l2_fill_pix_format(&f->fmt.pix, &sd_fmt.format);
++
++ if (mbus_fmt->code != fmt->code) {
++ /*
++ * We've set a format that the sensor reports
++ * as being supported, but it refuses to set it.
++ * Not much else we can do.
++ * Assume that the sensor driver may accept the
++ * format when it is set (rather than tried).
++ */
++ unicam_err(dev, "Sensor won't accept default format, and Unicam can't support sensor default\n");
++ }
++ }
++
++ if (fmt->fourcc)
++ f->fmt.pix.pixelformat = fmt->fourcc;
++ else
++ f->fmt.pix.pixelformat = fmt->repacked_fourcc;
++ }
++
++ return unicam_calc_format_size_bpl(dev, fmt, f);
++}
++
++static int unicam_s_fmt_vid_cap(struct file *file, void *priv,
++ struct v4l2_format *f)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++ struct vb2_queue *q = &node->buffer_queue;
++ struct v4l2_mbus_framefmt mbus_fmt = {0};
++ const struct unicam_fmt *fmt;
++ int ret;
++
++ if (vb2_is_busy(q))
++ return -EBUSY;
++
++ ret = unicam_try_fmt_vid_cap(file, priv, f);
++ if (ret < 0)
++ return ret;
++
++ fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat);
++ if (!fmt) {
++ /*
++ * Unknown pixel format - adopt a default.
++ * This shouldn't happen as try_fmt should have resolved any
++ * issues first.
++ */
++ fmt = get_first_supported_format(dev);
++ if (!fmt)
++ /*
++ * It shouldn't be possible to get here with no
++ * supported formats
++ */
++ return -EINVAL;
++ f->fmt.pix.pixelformat = fmt->fourcc;
++ return -EINVAL;
++ }
++
++ v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, fmt->code);
++
++ ret = __subdev_set_format(dev, &mbus_fmt, node->pad_id);
++ if (ret) {
++ unicam_dbg(3, dev, "%s __subdev_set_format failed %d\n",
++ __func__, ret);
++ return ret;
++ }
++
++ /* Just double check nothing has gone wrong */
++ if (mbus_fmt.code != fmt->code) {
++ unicam_dbg(3, dev,
++ "%s subdev changed format on us, this should not happen\n",
++ __func__);
++ return -EINVAL;
++ }
++
++ node->fmt = fmt;
++ node->v_fmt.fmt.pix.pixelformat = f->fmt.pix.pixelformat;
++ node->v_fmt.fmt.pix.bytesperline = f->fmt.pix.bytesperline;
++ unicam_reset_format(node);
++
++ unicam_dbg(3, dev,
++ "%s %dx%d, mbus_fmt 0x%08X, V4L2 pix 0x%08X.\n",
++ __func__, node->v_fmt.fmt.pix.width,
++ node->v_fmt.fmt.pix.height, mbus_fmt.code,
++ node->v_fmt.fmt.pix.pixelformat);
++
++ *f = node->v_fmt;
++
++ return 0;
++}
++
++static int unicam_enum_fmt_meta_cap(struct file *file, void *priv,
++ struct v4l2_fmtdesc *f)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++ const struct unicam_fmt *fmt;
++ u32 code;
++ int ret = 0;
++
++ if (node->pad_id != METADATA_PAD || f->index != 0)
++ return -EINVAL;
++
++ if (dev->sensor_embedded_data) {
++ struct v4l2_subdev_mbus_code_enum mbus_code = {
++ .index = f->index,
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .pad = METADATA_PAD,
++ };
++
++ ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, NULL,
++ &mbus_code);
++ if (ret < 0) {
++ unicam_dbg(2, dev,
++ "subdev->enum_mbus_code idx 0 returned %d - index invalid\n",
++ ret);
++ return -EINVAL;
++ }
++
++ code = mbus_code.code;
++ } else {
++ code = MEDIA_BUS_FMT_SENSOR_DATA;
++ }
++
++ fmt = find_format_by_code(code);
++ if (fmt)
++ f->pixelformat = fmt->fourcc;
++
++ return 0;
++}
++
++static int unicam_g_fmt_meta_cap(struct file *file, void *priv,
++ struct v4l2_format *f)
++{
++ struct unicam_node *node = video_drvdata(file);
++
++ if (node->pad_id != METADATA_PAD)
++ return -EINVAL;
++
++ *f = node->v_fmt;
++
++ return 0;
++}
++
++static int unicam_queue_setup(struct vb2_queue *vq,
++ unsigned int *nbuffers,
++ unsigned int *nplanes,
++ unsigned int sizes[],
++ struct device *alloc_devs[])
++{
++ struct unicam_node *node = vb2_get_drv_priv(vq);
++ struct unicam_device *dev = node->dev;
++ unsigned int size = node->pad_id == IMAGE_PAD ?
++ node->v_fmt.fmt.pix.sizeimage :
++ node->v_fmt.fmt.meta.buffersize;
++
++ if (vq->num_buffers + *nbuffers < 3)
++ *nbuffers = 3 - vq->num_buffers;
++
++ if (*nplanes) {
++ if (sizes[0] < size) {
++ unicam_err(dev, "sizes[0] %i < size %u\n", sizes[0],
++ size);
++ return -EINVAL;
++ }
++ size = sizes[0];
++ }
++
++ *nplanes = 1;
++ sizes[0] = size;
++
++ return 0;
++}
++
++static int unicam_buffer_prepare(struct vb2_buffer *vb)
++{
++ struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue);
++ struct unicam_device *dev = node->dev;
++ struct unicam_buffer *buf = to_unicam_buffer(vb);
++ unsigned long size;
++
++ if (WARN_ON(!node->fmt))
++ return -EINVAL;
++
++ size = node->pad_id == IMAGE_PAD ? node->v_fmt.fmt.pix.sizeimage :
++ node->v_fmt.fmt.meta.buffersize;
++ if (vb2_plane_size(vb, 0) < size) {
++ unicam_err(dev, "data will not fit into plane (%lu < %lu)\n",
++ vb2_plane_size(vb, 0), size);
++ return -EINVAL;
++ }
++
++ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
++ return 0;
++}
++
++static void unicam_buffer_queue(struct vb2_buffer *vb)
++{
++ struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue);
++ struct unicam_buffer *buf = to_unicam_buffer(vb);
++ unsigned long flags;
++
++ spin_lock_irqsave(&node->dma_queue_lock, flags);
++ list_add_tail(&buf->list, &node->dma_queue);
++ spin_unlock_irqrestore(&node->dma_queue_lock, flags);
++}
++
++static void unicam_set_packing_config(struct unicam_device *dev)
++{
++ u32 pack, unpack;
++ u32 val;
++
++ if (dev->node[IMAGE_PAD].v_fmt.fmt.pix.pixelformat ==
++ dev->node[IMAGE_PAD].fmt->fourcc) {
++ unpack = UNICAM_PUM_NONE;
++ pack = UNICAM_PPM_NONE;
++ } else {
++ switch (dev->node[IMAGE_PAD].fmt->depth) {
++ case 8:
++ unpack = UNICAM_PUM_UNPACK8;
++ break;
++ case 10:
++ unpack = UNICAM_PUM_UNPACK10;
++ break;
++ case 12:
++ unpack = UNICAM_PUM_UNPACK12;
++ break;
++ case 14:
++ unpack = UNICAM_PUM_UNPACK14;
++ break;
++ case 16:
++ unpack = UNICAM_PUM_UNPACK16;
++ break;
++ default:
++ unpack = UNICAM_PUM_NONE;
++ break;
++ }
++
++ /* Repacking is always to 16bpp */
++ pack = UNICAM_PPM_PACK16;
++ }
++
++ val = 0;
++ set_field(&val, unpack, UNICAM_PUM_MASK);
++ set_field(&val, pack, UNICAM_PPM_MASK);
++ reg_write(dev, UNICAM_IPIPE, val);
++}
++
++static void unicam_cfg_image_id(struct unicam_device *dev)
++{
++ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
++ /* CSI2 mode, hardcode VC 0 for now. */
++ reg_write(dev, UNICAM_IDI0,
++ (0 << 6) | dev->node[IMAGE_PAD].fmt->csi_dt);
++ } else {
++ /* CCP2 mode */
++ reg_write(dev, UNICAM_IDI0,
++ 0x80 | dev->node[IMAGE_PAD].fmt->csi_dt);
++ }
++}
++
++static void unicam_enable_ed(struct unicam_device *dev)
++{
++ u32 val = reg_read(dev, UNICAM_DCS);
++
++ set_field(&val, 2, UNICAM_EDL_MASK);
++ /* Do not wrap at the end of the embedded data buffer */
++ set_field(&val, 0, UNICAM_DBOB);
++
++ reg_write(dev, UNICAM_DCS, val);
++}
++
++static void unicam_start_rx(struct unicam_device *dev, dma_addr_t *addr)
++{
++ int line_int_freq = dev->node[IMAGE_PAD].v_fmt.fmt.pix.height >> 2;
++ unsigned int size, i;
++ u32 val;
++
++ if (line_int_freq < 128)
++ line_int_freq = 128;
++
++ /* Enable lane clocks */
++ val = 1;
++ for (i = 0; i < dev->active_data_lanes; i++)
++ val = val << 2 | 1;
++ clk_write(dev, val);
++
++ /* Basic init */
++ reg_write(dev, UNICAM_CTRL, UNICAM_MEM);
++
++ /* Enable analogue control, and leave in reset. */
++ val = UNICAM_AR;
++ set_field(&val, 7, UNICAM_CTATADJ_MASK);
++ set_field(&val, 7, UNICAM_PTATADJ_MASK);
++ reg_write(dev, UNICAM_ANA, val);
++ usleep_range(1000, 2000);
++
++ /* Come out of reset */
++ reg_write_field(dev, UNICAM_ANA, 0, UNICAM_AR);
++
++ /* Peripheral reset */
++ reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_CPR);
++ reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPR);
++
++ reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPE);
++
++ /* Enable Rx control. */
++ val = reg_read(dev, UNICAM_CTRL);
++ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
++ set_field(&val, UNICAM_CPM_CSI2, UNICAM_CPM_MASK);
++ set_field(&val, UNICAM_DCM_STROBE, UNICAM_DCM_MASK);
++ } else {
++ set_field(&val, UNICAM_CPM_CCP2, UNICAM_CPM_MASK);
++ set_field(&val, dev->bus_flags, UNICAM_DCM_MASK);
++ }
++ /* Packet framer timeout */
++ set_field(&val, 0xf, UNICAM_PFT_MASK);
++ set_field(&val, 128, UNICAM_OET_MASK);
++ reg_write(dev, UNICAM_CTRL, val);
++
++ reg_write(dev, UNICAM_IHWIN, 0);
++ reg_write(dev, UNICAM_IVWIN, 0);
++
++ /* AXI bus access QoS setup */
++ val = reg_read(dev, UNICAM_PRI);
++ set_field(&val, 0, UNICAM_BL_MASK);
++ set_field(&val, 0, UNICAM_BS_MASK);
++ set_field(&val, 0xe, UNICAM_PP_MASK);
++ set_field(&val, 8, UNICAM_NP_MASK);
++ set_field(&val, 2, UNICAM_PT_MASK);
++ set_field(&val, 1, UNICAM_PE);
++ reg_write(dev, UNICAM_PRI, val);
++
++ reg_write_field(dev, UNICAM_ANA, 0, UNICAM_DDL);
++
++ /* Always start in trigger frame capture mode (UNICAM_FCM set) */
++ val = UNICAM_FSIE | UNICAM_FEIE | UNICAM_FCM | UNICAM_IBOB;
++ set_field(&val, line_int_freq, UNICAM_LCIE_MASK);
++ reg_write(dev, UNICAM_ICTL, val);
++ reg_write(dev, UNICAM_STA, UNICAM_STA_MASK_ALL);
++ reg_write(dev, UNICAM_ISTA, UNICAM_ISTA_MASK_ALL);
++
++ /* tclk_term_en */
++ reg_write_field(dev, UNICAM_CLT, 2, UNICAM_CLT1_MASK);
++ /* tclk_settle */
++ reg_write_field(dev, UNICAM_CLT, 6, UNICAM_CLT2_MASK);
++ /* td_term_en */
++ reg_write_field(dev, UNICAM_DLT, 2, UNICAM_DLT1_MASK);
++ /* ths_settle */
++ reg_write_field(dev, UNICAM_DLT, 6, UNICAM_DLT2_MASK);
++ /* trx_enable */
++ reg_write_field(dev, UNICAM_DLT, 0, UNICAM_DLT3_MASK);
++
++ reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_SOE);
++
++ /* Packet compare setup - required to avoid missing frame ends */
++ val = 0;
++ set_field(&val, 1, UNICAM_PCE);
++ set_field(&val, 1, UNICAM_GI);
++ set_field(&val, 1, UNICAM_CPH);
++ set_field(&val, 0, UNICAM_PCVC_MASK);
++ set_field(&val, 1, UNICAM_PCDT_MASK);
++ reg_write(dev, UNICAM_CMP0, val);
++
++ /* Enable clock lane and set up terminations */
++ val = 0;
++ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
++ /* CSI2 */
++ set_field(&val, 1, UNICAM_CLE);
++ set_field(&val, 1, UNICAM_CLLPE);
++ if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) {
++ set_field(&val, 1, UNICAM_CLTRE);
++ set_field(&val, 1, UNICAM_CLHSE);
++ }
++ } else {
++ /* CCP2 */
++ set_field(&val, 1, UNICAM_CLE);
++ set_field(&val, 1, UNICAM_CLHSE);
++ set_field(&val, 1, UNICAM_CLTRE);
++ }
++ reg_write(dev, UNICAM_CLK, val);
++
++ /*
++ * Enable required data lanes with appropriate terminations.
++ * The same value needs to be written to UNICAM_DATn registers for
++ * the active lanes, and 0 for inactive ones.
++ */
++ val = 0;
++ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
++ /* CSI2 */
++ set_field(&val, 1, UNICAM_DLE);
++ set_field(&val, 1, UNICAM_DLLPE);
++ if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) {
++ set_field(&val, 1, UNICAM_DLTRE);
++ set_field(&val, 1, UNICAM_DLHSE);
++ }
++ } else {
++ /* CCP2 */
++ set_field(&val, 1, UNICAM_DLE);
++ set_field(&val, 1, UNICAM_DLHSE);
++ set_field(&val, 1, UNICAM_DLTRE);
++ }
++ reg_write(dev, UNICAM_DAT0, val);
++
++ if (dev->active_data_lanes == 1)
++ val = 0;
++ reg_write(dev, UNICAM_DAT1, val);
++
++ if (dev->max_data_lanes > 2) {
++ /*
++ * Registers UNICAM_DAT2 and UNICAM_DAT3 only valid if the
++ * instance supports more than 2 data lanes.
++ */
++ if (dev->active_data_lanes == 2)
++ val = 0;
++ reg_write(dev, UNICAM_DAT2, val);
++
++ if (dev->active_data_lanes == 3)
++ val = 0;
++ reg_write(dev, UNICAM_DAT3, val);
++ }
++
++ reg_write(dev, UNICAM_IBLS,
++ dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline);
++ size = dev->node[IMAGE_PAD].v_fmt.fmt.pix.sizeimage;
++ unicam_wr_dma_addr(dev, addr[IMAGE_PAD], size, IMAGE_PAD);
++ unicam_set_packing_config(dev);
++ unicam_cfg_image_id(dev);
++
++ val = reg_read(dev, UNICAM_MISC);
++ set_field(&val, 1, UNICAM_FL0);
++ set_field(&val, 1, UNICAM_FL1);
++ reg_write(dev, UNICAM_MISC, val);
++
++ if (dev->node[METADATA_PAD].streaming && dev->sensor_embedded_data) {
++ size = dev->node[METADATA_PAD].v_fmt.fmt.meta.buffersize;
++ unicam_enable_ed(dev);
++ unicam_wr_dma_addr(dev, addr[METADATA_PAD], size, METADATA_PAD);
++ }
++
++ /* Enable peripheral */
++ reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_CPE);
++
++ /* Load image pointers */
++ reg_write_field(dev, UNICAM_ICTL, 1, UNICAM_LIP_MASK);
++
++ /* Load embedded data buffer pointers if needed */
++ if (dev->node[METADATA_PAD].streaming && dev->sensor_embedded_data)
++ reg_write_field(dev, UNICAM_DCS, 1, UNICAM_LDP);
++
++ /*
++ * Enable trigger only for the first frame to
++ * sync correctly to the FS from the source.
++ */
++ reg_write_field(dev, UNICAM_ICTL, 1, UNICAM_TFC);
++}
++
++static void unicam_disable(struct unicam_device *dev)
++{
++ /* Analogue lane control disable */
++ reg_write_field(dev, UNICAM_ANA, 1, UNICAM_DDL);
++
++ /* Stop the output engine */
++ reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_SOE);
++
++ /* Disable the data lanes. */
++ reg_write(dev, UNICAM_DAT0, 0);
++ reg_write(dev, UNICAM_DAT1, 0);
++
++ if (dev->max_data_lanes > 2) {
++ reg_write(dev, UNICAM_DAT2, 0);
++ reg_write(dev, UNICAM_DAT3, 0);
++ }
++
++ /* Peripheral reset */
++ reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_CPR);
++ usleep_range(50, 100);
++ reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPR);
++
++ /* Disable peripheral */
++ reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPE);
++
++ /* Clear ED setup */
++ reg_write(dev, UNICAM_DCS, 0);
++
++ /* Disable all lane clocks */
++ clk_write(dev, 0);
++}
++
++static void unicam_return_buffers(struct unicam_node *node)
++{
++ struct unicam_buffer *buf, *tmp;
++ unsigned long flags;
++
++ spin_lock_irqsave(&node->dma_queue_lock, flags);
++ list_for_each_entry_safe(buf, tmp, &node->dma_queue, list) {
++ list_del(&buf->list);
++ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
++ }
++
++ if (node->cur_frm)
++ vb2_buffer_done(&node->cur_frm->vb.vb2_buf,
++ VB2_BUF_STATE_ERROR);
++ if (node->next_frm && node->cur_frm != node->next_frm)
++ vb2_buffer_done(&node->next_frm->vb.vb2_buf,
++ VB2_BUF_STATE_ERROR);
++
++ node->cur_frm = NULL;
++ node->next_frm = NULL;
++ spin_unlock_irqrestore(&node->dma_queue_lock, flags);
++}
++
++static int unicam_start_streaming(struct vb2_queue *vq, unsigned int count)
++{
++ struct unicam_node *node = vb2_get_drv_priv(vq);
++ struct unicam_device *dev = node->dev;
++ dma_addr_t buffer_addr[MAX_NODES] = { 0 };
++ unsigned long flags;
++ unsigned int i;
++ int ret;
++
++ node->streaming = true;
++ if (!unicam_all_nodes_streaming(dev)) {
++ unicam_dbg(3, dev, "Not all nodes are streaming yet.");
++ return 0;
++ }
++
++ dev->sequence = 0;
++ ret = unicam_runtime_get(dev);
++ if (ret < 0) {
++ unicam_dbg(3, dev, "unicam_runtime_get failed\n");
++ goto err_streaming;
++ }
++
++ /*
++ * TODO: Retrieve the number of active data lanes from the connected
++ * subdevice.
++ */
++ dev->active_data_lanes = dev->max_data_lanes;
++
++ ret = clk_set_rate(dev->clock, 100 * 1000 * 1000);
++ if (ret) {
++ unicam_err(dev, "failed to set up clock\n");
++ goto err_pm_put;
++ }
++
++ ret = clk_prepare_enable(dev->clock);
++ if (ret) {
++ unicam_err(dev, "Failed to enable CSI clock: %d\n", ret);
++ goto err_pm_put;
++ }
++
++ for (i = 0; i < ARRAY_SIZE(dev->node); i++) {
++ struct unicam_buffer *buf;
++
++ if (!dev->node[i].streaming)
++ continue;
++
++ spin_lock_irqsave(&dev->node[i].dma_queue_lock, flags);
++ buf = list_first_entry(&dev->node[i].dma_queue,
++ struct unicam_buffer, list);
++ dev->node[i].cur_frm = buf;
++ dev->node[i].next_frm = buf;
++ list_del(&buf->list);
++ spin_unlock_irqrestore(&dev->node[i].dma_queue_lock, flags);
++
++ buffer_addr[i] =
++ vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
++ }
++
++ unicam_start_rx(dev, buffer_addr);
++
++ ret = v4l2_subdev_call(dev->sensor, video, s_stream, 1);
++ if (ret < 0) {
++ unicam_err(dev, "stream on failed in subdev\n");
++ goto err_disable_unicam;
++ }
++
++ return 0;
++
++err_disable_unicam:
++ unicam_disable(dev);
++ clk_disable_unprepare(dev->clock);
++err_pm_put:
++ unicam_runtime_put(dev);
++err_streaming:
++ unicam_return_buffers(node);
++ node->streaming = false;
++
++ return ret;
++}
++
++static void unicam_stop_streaming(struct vb2_queue *vq)
++{
++ struct unicam_node *node = vb2_get_drv_priv(vq);
++ struct unicam_device *dev = node->dev;
++
++ node->streaming = false;
++
++ if (node->pad_id == IMAGE_PAD) {
++ /*
++ * Stop streaming the sensor and disable the peripheral.
++ * We cannot continue streaming embedded data with the
++ * image pad disabled.
++ */
++ if (v4l2_subdev_call(dev->sensor, video, s_stream, 0) < 0)
++ unicam_err(dev, "stream off failed in subdev\n");
++
++ unicam_disable(dev);
++ clk_disable_unprepare(dev->clock);
++ unicam_runtime_put(dev);
++
++ } else if (node->pad_id == METADATA_PAD) {
++ /*
++ * Allow the hardware to spin in the dummy buffer.
++ * This is only really needed if the embedded data pad is
++ * disabled before the image pad.
++ */
++ unicam_wr_dma_addr(dev, node->dummy_buf_dma_addr,
++ DUMMY_BUF_SIZE, METADATA_PAD);
++ }
++
++ /* Clear all queued buffers for the node */
++ unicam_return_buffers(node);
++}
++
++static int unicam_enum_input(struct file *file, void *priv,
++ struct v4l2_input *inp)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++
++ if (inp->index != 0)
++ return -EINVAL;
++
++ inp->type = V4L2_INPUT_TYPE_CAMERA;
++ if (v4l2_subdev_has_op(dev->sensor, video, s_dv_timings)) {
++ inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;
++ inp->std = 0;
++ } else if (v4l2_subdev_has_op(dev->sensor, video, s_std)) {
++ inp->capabilities = V4L2_IN_CAP_STD;
++ if (v4l2_subdev_call(dev->sensor, video, g_tvnorms, &inp->std)
++ < 0)
++ inp->std = V4L2_STD_ALL;
++ } else {
++ inp->capabilities = 0;
++ inp->std = 0;
++ }
++ sprintf(inp->name, "Camera 0");
++ return 0;
++}
++
++static int unicam_g_input(struct file *file, void *priv, unsigned int *i)
++{
++ *i = 0;
++
++ return 0;
++}
++
++static int unicam_s_input(struct file *file, void *priv, unsigned int i)
++{
++ /*
++ * FIXME: Ideally we would like to be able to query the source
++ * subdevice for information over the input connectors it supports,
++ * and map that through in to a call to video_ops->s_routing.
++ * There is no infrastructure support for defining that within
++ * devicetree at present. Until that is implemented we can't
++ * map a user physical connector number to s_routing input number.
++ */
++ if (i > 0)
++ return -EINVAL;
++
++ return 0;
++}
++
++static int unicam_querystd(struct file *file, void *priv,
++ v4l2_std_id *std)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++
++ return v4l2_subdev_call(dev->sensor, video, querystd, std);
++}
++
++static int unicam_g_std(struct file *file, void *priv, v4l2_std_id *std)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++
++ return v4l2_subdev_call(dev->sensor, video, g_std, std);
++}
++
++static int unicam_s_std(struct file *file, void *priv, v4l2_std_id std)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++ int ret;
++ v4l2_std_id current_std;
++
++ ret = v4l2_subdev_call(dev->sensor, video, g_std, &current_std);
++ if (ret)
++ return ret;
++
++ if (std == current_std)
++ return 0;
++
++ if (vb2_is_busy(&node->buffer_queue))
++ return -EBUSY;
++
++ ret = v4l2_subdev_call(dev->sensor, video, s_std, std);
++
++ /* Force recomputation of bytesperline */
++ node->v_fmt.fmt.pix.bytesperline = 0;
++
++ unicam_reset_format(node);
++
++ return ret;
++}
++
++static int unicam_s_edid(struct file *file, void *priv, struct v4l2_edid *edid)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++
++ return v4l2_subdev_call(dev->sensor, pad, set_edid, edid);
++}
++
++static int unicam_g_edid(struct file *file, void *priv, struct v4l2_edid *edid)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++
++ return v4l2_subdev_call(dev->sensor, pad, get_edid, edid);
++}
++
++static int unicam_s_selection(struct file *file, void *priv,
++ struct v4l2_selection *sel)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++ struct v4l2_subdev_selection sdsel = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .target = sel->target,
++ .flags = sel->flags,
++ .r = sel->r,
++ };
++
++ return v4l2_subdev_call(dev->sensor, pad, set_selection, NULL, &sdsel);
++}
++
++static int unicam_g_selection(struct file *file, void *priv,
++ struct v4l2_selection *sel)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++ struct v4l2_subdev_selection sdsel = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .target = sel->target,
++ };
++ int ret;
++
++ ret = v4l2_subdev_call(dev->sensor, pad, get_selection, NULL, &sdsel);
++ if (!ret)
++ sel->r = sdsel.r;
++
++ return ret;
++}
++
++static int unicam_enum_framesizes(struct file *file, void *priv,
++ struct v4l2_frmsizeenum *fsize)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++ const struct unicam_fmt *fmt;
++ struct v4l2_subdev_frame_size_enum fse;
++ int ret;
++
++ /* check for valid format */
++ fmt = find_format_by_pix(dev, fsize->pixel_format);
++ if (!fmt) {
++ unicam_dbg(3, dev, "Invalid pixel code: %x\n",
++ fsize->pixel_format);
++ return -EINVAL;
++ }
++ fse.code = fmt->code;
++
++ fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++ fse.index = fsize->index;
++ fse.pad = node->pad_id;
++
++ ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_size, NULL, &fse);
++ if (ret)
++ return ret;
++
++ unicam_dbg(1, dev, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n",
++ __func__, fse.index, fse.code, fse.min_width, fse.max_width,
++ fse.min_height, fse.max_height);
++
++ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
++ fsize->discrete.width = fse.max_width;
++ fsize->discrete.height = fse.max_height;
++
++ return 0;
++}
++
++static int unicam_enum_frameintervals(struct file *file, void *priv,
++ struct v4l2_frmivalenum *fival)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++ const struct unicam_fmt *fmt;
++ struct v4l2_subdev_frame_interval_enum fie = {
++ .index = fival->index,
++ .width = fival->width,
++ .height = fival->height,
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ int ret;
++
++ fmt = find_format_by_pix(dev, fival->pixel_format);
++ if (!fmt)
++ return -EINVAL;
++
++ fie.code = fmt->code;
++ ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_interval,
++ NULL, &fie);
++ if (ret)
++ return ret;
++
++ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
++ fival->discrete = fie.interval;
++
++ return 0;
++}
++
++static int unicam_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++
++ return v4l2_g_parm_cap(video_devdata(file), dev->sensor, a);
++}
++
++static int unicam_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++
++ return v4l2_s_parm_cap(video_devdata(file), dev->sensor, a);
++}
++
++static int unicam_g_dv_timings(struct file *file, void *priv,
++ struct v4l2_dv_timings *timings)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++
++ return v4l2_subdev_call(dev->sensor, video, g_dv_timings, timings);
++}
++
++static int unicam_s_dv_timings(struct file *file, void *priv,
++ struct v4l2_dv_timings *timings)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++ struct v4l2_dv_timings current_timings;
++ int ret;
++
++ ret = v4l2_subdev_call(dev->sensor, video, g_dv_timings,
++ &current_timings);
++
++ if (v4l2_match_dv_timings(timings, &current_timings, 0, false))
++ return 0;
++
++ if (vb2_is_busy(&node->buffer_queue))
++ return -EBUSY;
++
++ ret = v4l2_subdev_call(dev->sensor, video, s_dv_timings, timings);
++
++ /* Force recomputation of bytesperline */
++ node->v_fmt.fmt.pix.bytesperline = 0;
++
++ unicam_reset_format(node);
++
++ return ret;
++}
++
++static int unicam_query_dv_timings(struct file *file, void *priv,
++ struct v4l2_dv_timings *timings)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++
++ return v4l2_subdev_call(dev->sensor, video, query_dv_timings, timings);
++}
++
++static int unicam_enum_dv_timings(struct file *file, void *priv,
++ struct v4l2_enum_dv_timings *timings)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++
++ return v4l2_subdev_call(dev->sensor, pad, enum_dv_timings, timings);
++}
++
++static int unicam_dv_timings_cap(struct file *file, void *priv,
++ struct v4l2_dv_timings_cap *cap)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++
++ return v4l2_subdev_call(dev->sensor, pad, dv_timings_cap, cap);
++}
++
++static int unicam_subscribe_event(struct v4l2_fh *fh,
++ const struct v4l2_event_subscription *sub)
++{
++ switch (sub->type) {
++ case V4L2_EVENT_FRAME_SYNC:
++ return v4l2_event_subscribe(fh, sub, 2, NULL);
++ case V4L2_EVENT_SOURCE_CHANGE:
++ return v4l2_event_subscribe(fh, sub, 4, NULL);
++ }
++
++ return v4l2_ctrl_subscribe_event(fh, sub);
++}
++
++static int unicam_log_status(struct file *file, void *fh)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++ u32 reg;
++
++ /* status for sub devices */
++ v4l2_device_call_all(&dev->v4l2_dev, 0, core, log_status);
++
++ unicam_info(dev, "-----Receiver status-----\n");
++ unicam_info(dev, "V4L2 width/height: %ux%u\n",
++ node->v_fmt.fmt.pix.width, node->v_fmt.fmt.pix.height);
++ unicam_info(dev, "Mediabus format: %08x\n", node->fmt->code);
++ unicam_info(dev, "V4L2 format: %08x\n",
++ node->v_fmt.fmt.pix.pixelformat);
++ reg = reg_read(dev, UNICAM_IPIPE);
++ unicam_info(dev, "Unpacking/packing: %u / %u\n",
++ get_field(reg, UNICAM_PUM_MASK),
++ get_field(reg, UNICAM_PPM_MASK));
++ unicam_info(dev, "----Live data----\n");
++ unicam_info(dev, "Programmed stride: %4u\n",
++ reg_read(dev, UNICAM_IBLS));
++ unicam_info(dev, "Detected resolution: %ux%u\n",
++ reg_read(dev, UNICAM_IHSTA),
++ reg_read(dev, UNICAM_IVSTA));
++ unicam_info(dev, "Write pointer: %08x\n",
++ reg_read(dev, UNICAM_IBWP));
++
++ return 0;
++}
++
++static void unicam_notify(struct v4l2_subdev *sd,
++ unsigned int notification, void *arg)
++{
++ struct unicam_device *dev = to_unicam_device(sd->v4l2_dev);
++
++ switch (notification) {
++ case V4L2_DEVICE_NOTIFY_EVENT:
++ v4l2_event_queue(&dev->node[IMAGE_PAD].video_dev, arg);
++ break;
++ default:
++ break;
++ }
++}
++
++static const struct vb2_ops unicam_video_qops = {
++ .wait_prepare = vb2_ops_wait_prepare,
++ .wait_finish = vb2_ops_wait_finish,
++ .queue_setup = unicam_queue_setup,
++ .buf_prepare = unicam_buffer_prepare,
++ .buf_queue = unicam_buffer_queue,
++ .start_streaming = unicam_start_streaming,
++ .stop_streaming = unicam_stop_streaming,
++};
++
++/*
++ * unicam_v4l2_open : This function is based on the v4l2_fh_open helper
++ * function. It has been augmented to handle sensor subdevice power management,
++ */
++static int unicam_v4l2_open(struct file *file)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++ int ret;
++
++ mutex_lock(&node->lock);
++
++ ret = v4l2_fh_open(file);
++ if (ret) {
++ unicam_err(dev, "v4l2_fh_open failed\n");
++ goto unlock;
++ }
++
++ node->open++;
++
++ if (!v4l2_fh_is_singular_file(file))
++ goto unlock;
++
++ ret = v4l2_subdev_call(dev->sensor, core, s_power, 1);
++ if (ret < 0 && ret != -ENOIOCTLCMD) {
++ v4l2_fh_release(file);
++ node->open--;
++ goto unlock;
++ }
++
++ ret = 0;
++
++unlock:
++ mutex_unlock(&node->lock);
++ return ret;
++}
++
++static int unicam_v4l2_release(struct file *file)
++{
++ struct unicam_node *node = video_drvdata(file);
++ struct unicam_device *dev = node->dev;
++ struct v4l2_subdev *sd = dev->sensor;
++ bool fh_singular;
++ int ret;
++
++ mutex_lock(&node->lock);
++
++ fh_singular = v4l2_fh_is_singular_file(file);
++
++ ret = _vb2_fop_release(file, NULL);
++
++ if (fh_singular)
++ v4l2_subdev_call(sd, core, s_power, 0);
++
++ node->open--;
++ mutex_unlock(&node->lock);
++
++ return ret;
++}
++
++/* unicam capture driver file operations */
++static const struct v4l2_file_operations unicam_fops = {
++ .owner = THIS_MODULE,
++ .open = unicam_v4l2_open,
++ .release = unicam_v4l2_release,
++ .read = vb2_fop_read,
++ .poll = vb2_fop_poll,
++ .unlocked_ioctl = video_ioctl2,
++ .mmap = vb2_fop_mmap,
++};
++
++/* unicam capture ioctl operations */
++static const struct v4l2_ioctl_ops unicam_ioctl_ops = {
++ .vidioc_querycap = unicam_querycap,
++ .vidioc_enum_fmt_vid_cap = unicam_enum_fmt_vid_cap,
++ .vidioc_g_fmt_vid_cap = unicam_g_fmt_vid_cap,
++ .vidioc_s_fmt_vid_cap = unicam_s_fmt_vid_cap,
++ .vidioc_try_fmt_vid_cap = unicam_try_fmt_vid_cap,
++
++ .vidioc_enum_fmt_meta_cap = unicam_enum_fmt_meta_cap,
++ .vidioc_g_fmt_meta_cap = unicam_g_fmt_meta_cap,
++ .vidioc_s_fmt_meta_cap = unicam_g_fmt_meta_cap,
++ .vidioc_try_fmt_meta_cap = unicam_g_fmt_meta_cap,
++
++ .vidioc_enum_input = unicam_enum_input,
++ .vidioc_g_input = unicam_g_input,
++ .vidioc_s_input = unicam_s_input,
++
++ .vidioc_querystd = unicam_querystd,
++ .vidioc_s_std = unicam_s_std,
++ .vidioc_g_std = unicam_g_std,
++
++ .vidioc_g_edid = unicam_g_edid,
++ .vidioc_s_edid = unicam_s_edid,
++
++ .vidioc_enum_framesizes = unicam_enum_framesizes,
++ .vidioc_enum_frameintervals = unicam_enum_frameintervals,
++
++ .vidioc_g_selection = unicam_g_selection,
++ .vidioc_s_selection = unicam_s_selection,
++
++ .vidioc_g_parm = unicam_g_parm,
++ .vidioc_s_parm = unicam_s_parm,
++
++ .vidioc_s_dv_timings = unicam_s_dv_timings,
++ .vidioc_g_dv_timings = unicam_g_dv_timings,
++ .vidioc_query_dv_timings = unicam_query_dv_timings,
++ .vidioc_enum_dv_timings = unicam_enum_dv_timings,
++ .vidioc_dv_timings_cap = unicam_dv_timings_cap,
++
++ .vidioc_reqbufs = vb2_ioctl_reqbufs,
++ .vidioc_create_bufs = vb2_ioctl_create_bufs,
++ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
++ .vidioc_querybuf = vb2_ioctl_querybuf,
++ .vidioc_qbuf = vb2_ioctl_qbuf,
++ .vidioc_dqbuf = vb2_ioctl_dqbuf,
++ .vidioc_expbuf = vb2_ioctl_expbuf,
++ .vidioc_streamon = vb2_ioctl_streamon,
++ .vidioc_streamoff = vb2_ioctl_streamoff,
++
++ .vidioc_log_status = unicam_log_status,
++ .vidioc_subscribe_event = unicam_subscribe_event,
++ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
++};
++
++static int
++unicam_async_bound(struct v4l2_async_notifier *notifier,
++ struct v4l2_subdev *subdev,
++ struct v4l2_async_subdev *asd)
++{
++ struct unicam_device *unicam = to_unicam_device(notifier->v4l2_dev);
++
++ if (unicam->sensor) {
++ unicam_info(unicam, "Rejecting subdev %s (Already set!!)",
++ subdev->name);
++ return 0;
++ }
++
++ unicam->sensor = subdev;
++ unicam_dbg(1, unicam, "Using sensor %s for capture\n", subdev->name);
++
++ return 0;
++}
++
++static void unicam_release(struct kref *kref)
++{
++ struct unicam_device *unicam =
++ container_of(kref, struct unicam_device, kref);
++
++ v4l2_ctrl_handler_free(&unicam->ctrl_handler);
++ media_device_cleanup(&unicam->mdev);
++
++ if (unicam->sensor_config)
++ v4l2_subdev_free_pad_config(unicam->sensor_config);
++
++ kfree(unicam);
++}
++
++static void unicam_put(struct unicam_device *unicam)
++{
++ kref_put(&unicam->kref, unicam_release);
++}
++
++static void unicam_get(struct unicam_device *unicam)
++{
++ kref_get(&unicam->kref);
++}
++
++static void unicam_node_release(struct video_device *vdev)
++{
++ struct unicam_node *node = video_get_drvdata(vdev);
++
++ unicam_put(node->dev);
++}
++
++static int register_node(struct unicam_device *unicam, struct unicam_node *node,
++ enum v4l2_buf_type type, int pad_id)
++{
++ struct video_device *vdev;
++ struct vb2_queue *q;
++ struct v4l2_mbus_framefmt mbus_fmt = {0};
++ const struct unicam_fmt *fmt;
++ int ret;
++
++ if (pad_id == IMAGE_PAD) {
++ ret = __subdev_get_format(unicam, &mbus_fmt, pad_id);
++ if (ret) {
++ unicam_err(unicam, "Failed to get_format - ret %d\n",
++ ret);
++ return ret;
++ }
++
++ fmt = find_format_by_code(mbus_fmt.code);
++ if (!fmt) {
++ /*
++ * Find the first format that the sensor and unicam both
++ * support
++ */
++ fmt = get_first_supported_format(unicam);
++
++ if (!fmt)
++ /* No compatible formats */
++ return -EINVAL;
++
++ mbus_fmt.code = fmt->code;
++ ret = __subdev_set_format(unicam, &mbus_fmt, pad_id);
++ if (ret)
++ return -EINVAL;
++ }
++ if (mbus_fmt.field != V4L2_FIELD_NONE) {
++ /* Interlaced not supported - disable it now. */
++ mbus_fmt.field = V4L2_FIELD_NONE;
++ ret = __subdev_set_format(unicam, &mbus_fmt, pad_id);
++ if (ret)
++ return -EINVAL;
++ }
++
++ node->v_fmt.fmt.pix.pixelformat = fmt->fourcc ? fmt->fourcc
++ : fmt->repacked_fourcc;
++ } else {
++ /* Fix this node format as embedded data. */
++ fmt = find_format_by_code(MEDIA_BUS_FMT_SENSOR_DATA);
++ node->v_fmt.fmt.meta.dataformat = fmt->fourcc;
++ }
++
++ node->dev = unicam;
++ node->pad_id = pad_id;
++ node->fmt = fmt;
++
++ /* Read current subdev format */
++ unicam_reset_format(node);
++
++ if (v4l2_subdev_has_op(unicam->sensor, video, s_std)) {
++ v4l2_std_id tvnorms;
++
++ if (WARN_ON(!v4l2_subdev_has_op(unicam->sensor, video,
++ g_tvnorms)))
++ /*
++ * Subdevice should not advertise s_std but not
++ * g_tvnorms
++ */
++ return -EINVAL;
++
++ ret = v4l2_subdev_call(unicam->sensor, video,
++ g_tvnorms, &tvnorms);
++ if (WARN_ON(ret))
++ return -EINVAL;
++ node->video_dev.tvnorms |= tvnorms;
++ }
++
++ spin_lock_init(&node->dma_queue_lock);
++ mutex_init(&node->lock);
++
++ vdev = &node->video_dev;
++ if (pad_id == IMAGE_PAD) {
++ /* Add controls from the subdevice */
++ ret = v4l2_ctrl_add_handler(&unicam->ctrl_handler,
++ unicam->sensor->ctrl_handler, NULL,
++ true);
++ if (ret < 0)
++ return ret;
++
++ /*
++ * If the sensor subdevice has any controls, associate the node
++ * with the ctrl handler to allow access from userland.
++ */
++ if (!list_empty(&unicam->ctrl_handler.ctrls))
++ vdev->ctrl_handler = &unicam->ctrl_handler;
++ }
++
++ q = &node->buffer_queue;
++ q->type = type;
++ q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
++ q->drv_priv = node;
++ q->ops = &unicam_video_qops;
++ q->mem_ops = &vb2_dma_contig_memops;
++ q->buf_struct_size = sizeof(struct unicam_buffer);
++ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
++ q->lock = &node->lock;
++ q->min_buffers_needed = 2;
++ q->dev = &unicam->pdev->dev;
++
++ ret = vb2_queue_init(q);
++ if (ret) {
++ unicam_err(unicam, "vb2_queue_init() failed\n");
++ return ret;
++ }
++
++ INIT_LIST_HEAD(&node->dma_queue);
++
++ vdev->release = unicam_node_release;
++ vdev->fops = &unicam_fops;
++ vdev->ioctl_ops = &unicam_ioctl_ops;
++ vdev->v4l2_dev = &unicam->v4l2_dev;
++ vdev->vfl_dir = VFL_DIR_RX;
++ vdev->queue = q;
++ vdev->lock = &node->lock;
++ vdev->device_caps = (pad_id == IMAGE_PAD) ?
++ (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING) :
++ (V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING);
++
++ /* Define the device names */
++ snprintf(vdev->name, sizeof(vdev->name), "%s-%s", UNICAM_MODULE_NAME,
++ pad_id == IMAGE_PAD ? "image" : "embedded");
++
++ video_set_drvdata(vdev, node);
++ if (pad_id == IMAGE_PAD)
++ vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
++ node->pad.flags = MEDIA_PAD_FL_SINK;
++ media_entity_pads_init(&vdev->entity, 1, &node->pad);
++
++ node->dummy_buf_cpu_addr = dma_alloc_coherent(&unicam->pdev->dev,
++ DUMMY_BUF_SIZE,
++ &node->dummy_buf_dma_addr,
++ GFP_KERNEL);
++ if (!node->dummy_buf_cpu_addr) {
++ unicam_err(unicam, "Unable to allocate dummy buffer.\n");
++ return -ENOMEM;
++ }
++
++ if (pad_id == METADATA_PAD) {
++ v4l2_disable_ioctl(vdev, VIDIOC_DQEVENT);
++ v4l2_disable_ioctl(vdev, VIDIOC_SUBSCRIBE_EVENT);
++ v4l2_disable_ioctl(vdev, VIDIOC_UNSUBSCRIBE_EVENT);
++ }
++ if (pad_id == METADATA_PAD ||
++ !v4l2_subdev_has_op(unicam->sensor, video, s_std)) {
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_STD);
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_STD);
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUMSTD);
++ }
++ if (pad_id == METADATA_PAD ||
++ !v4l2_subdev_has_op(unicam->sensor, video, querystd))
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_QUERYSTD);
++ if (pad_id == METADATA_PAD ||
++ !v4l2_subdev_has_op(unicam->sensor, video, s_dv_timings)) {
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_EDID);
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_EDID);
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_DV_TIMINGS_CAP);
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_DV_TIMINGS);
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_DV_TIMINGS);
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_DV_TIMINGS);
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_QUERY_DV_TIMINGS);
++ }
++ if (pad_id == METADATA_PAD ||
++ !v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_interval))
++ v4l2_disable_ioctl(&node->video_dev,
++ VIDIOC_ENUM_FRAMEINTERVALS);
++ if (pad_id == METADATA_PAD ||
++ !v4l2_subdev_has_op(unicam->sensor, video, g_frame_interval))
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_PARM);
++ if (pad_id == METADATA_PAD ||
++ !v4l2_subdev_has_op(unicam->sensor, video, s_frame_interval))
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_PARM);
++
++ if (pad_id == METADATA_PAD ||
++ !v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_size))
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_FRAMESIZES);
++
++ if (node->pad_id == METADATA_PAD ||
++ !v4l2_subdev_has_op(unicam->sensor, pad, set_selection))
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_SELECTION);
++
++ if (node->pad_id == METADATA_PAD ||
++ !v4l2_subdev_has_op(unicam->sensor, pad, get_selection))
++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_SELECTION);
++
++ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
++ if (ret) {
++ unicam_err(unicam, "Unable to register video device %s\n",
++ vdev->name);
++ return ret;
++ }
++
++ /*
++ * Acquire a reference to unicam, which will be released when the video
++ * device will be unregistered and userspace will have closed all open
++ * file handles.
++ */
++ unicam_get(unicam);
++ node->registered = true;
++
++ if (pad_id != METADATA_PAD || unicam->sensor_embedded_data) {
++ ret = media_create_pad_link(&unicam->sensor->entity, pad_id,
++ &node->video_dev.entity, 0,
++ MEDIA_LNK_FL_ENABLED |
++ MEDIA_LNK_FL_IMMUTABLE);
++ if (ret)
++ unicam_err(unicam, "Unable to create pad link for %s\n",
++ vdev->name);
++ }
++
++ return ret;
++}
++
++static void unregister_nodes(struct unicam_device *unicam)
++{
++ unsigned int i;
++
++ for (i = 0; i < ARRAY_SIZE(unicam->node); i++) {
++ struct unicam_node *node = &unicam->node[i];
++
++ if (node->dummy_buf_cpu_addr) {
++ dma_free_coherent(&unicam->pdev->dev, DUMMY_BUF_SIZE,
++ node->dummy_buf_cpu_addr,
++ node->dummy_buf_dma_addr);
++ }
++
++ if (node->registered) {
++ node->registered = false;
++ video_unregister_device(&node->video_dev);
++ }
++ }
++}
++
++static int unicam_probe_complete(struct unicam_device *unicam)
++{
++ int ret;
++
++ unicam->v4l2_dev.notify = unicam_notify;
++
++ unicam->sensor_config = v4l2_subdev_alloc_pad_config(unicam->sensor);
++ if (!unicam->sensor_config)
++ return -ENOMEM;
++
++ unicam->sensor_embedded_data = (unicam->sensor->entity.num_pads >= 2);
++
++ ret = register_node(unicam, &unicam->node[IMAGE_PAD],
++ V4L2_BUF_TYPE_VIDEO_CAPTURE, IMAGE_PAD);
++ if (ret) {
++ unicam_err(unicam, "Unable to register image video device.\n");
++ goto unregister;
++ }
++
++ ret = register_node(unicam, &unicam->node[METADATA_PAD],
++ V4L2_BUF_TYPE_META_CAPTURE, METADATA_PAD);
++ if (ret) {
++ unicam_err(unicam, "Unable to register metadata video device.\n");
++ goto unregister;
++ }
++
++ ret = v4l2_device_register_ro_subdev_nodes(&unicam->v4l2_dev);
++ if (ret) {
++ unicam_err(unicam, "Unable to register subdev nodes.\n");
++ goto unregister;
++ }
++
++ /*
++ * Release the initial reference, all references are now owned by the
++ * video devices.
++ */
++ unicam_put(unicam);
++ return 0;
++
++unregister:
++ unregister_nodes(unicam);
++ unicam_put(unicam);
++
++ return ret;
++}
++
++static int unicam_async_complete(struct v4l2_async_notifier *notifier)
++{
++ struct unicam_device *unicam = to_unicam_device(notifier->v4l2_dev);
++
++ return unicam_probe_complete(unicam);
++}
++
++static const struct v4l2_async_notifier_operations unicam_async_ops = {
++ .bound = unicam_async_bound,
++ .complete = unicam_async_complete,
++};
++
++static int of_unicam_connect_subdevs(struct unicam_device *dev)
++{
++ struct platform_device *pdev = dev->pdev;
++ struct v4l2_fwnode_endpoint ep = { 0 };
++ struct device_node *ep_node;
++ struct device_node *sensor_node;
++ unsigned int lane;
++ int ret = -EINVAL;
++
++ if (of_property_read_u32(pdev->dev.of_node, "brcm,num-data-lanes",
++ &dev->max_data_lanes) < 0) {
++ unicam_err(dev, "number of data lanes not set\n");
++ return -EINVAL;
++ }
++
++ /* Get the local endpoint and remote device. */
++ ep_node = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
++ if (!ep_node) {
++ unicam_dbg(3, dev, "can't get next endpoint\n");
++ return -EINVAL;
++ }
++
++ unicam_dbg(3, dev, "ep_node is %pOF\n", ep_node);
++
++ sensor_node = of_graph_get_remote_port_parent(ep_node);
++ if (!sensor_node) {
++ unicam_dbg(3, dev, "can't get remote parent\n");
++ goto cleanup_exit;
++ }
++
++ unicam_dbg(1, dev, "found subdevice %pOF\n", sensor_node);
++
++ /* Parse the local endpoint and validate its configuration. */
++ v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), &ep);
++
++ unicam_dbg(3, dev, "parsed local endpoint, bus_type %u\n",
++ ep.bus_type);
++
++ dev->bus_type = ep.bus_type;
++
++ switch (ep.bus_type) {
++ case V4L2_MBUS_CSI2_DPHY:
++ switch (ep.bus.mipi_csi2.num_data_lanes) {
++ case 1:
++ case 2:
++ case 4:
++ break;
++
++ default:
++ unicam_err(dev, "subdevice %pOF: %u data lanes not supported\n",
++ sensor_node,
++ ep.bus.mipi_csi2.num_data_lanes);
++ goto cleanup_exit;
++ }
++
++ for (lane = 0; lane < ep.bus.mipi_csi2.num_data_lanes; lane++) {
++ if (ep.bus.mipi_csi2.data_lanes[lane] != lane + 1) {
++ unicam_err(dev, "subdevice %pOF: data lanes reordering not supported\n",
++ sensor_node);
++ goto cleanup_exit;
++ }
++ }
++
++ if (ep.bus.mipi_csi2.num_data_lanes > dev->max_data_lanes) {
++ unicam_err(dev, "subdevice requires %u data lanes when %u are supported\n",
++ ep.bus.mipi_csi2.num_data_lanes,
++ dev->max_data_lanes);
++ }
++
++ dev->max_data_lanes = ep.bus.mipi_csi2.num_data_lanes;
++ dev->bus_flags = ep.bus.mipi_csi2.flags;
++
++ break;
++
++ case V4L2_MBUS_CCP2:
++ if (ep.bus.mipi_csi1.clock_lane != 0 ||
++ ep.bus.mipi_csi1.data_lane != 1) {
++ unicam_err(dev, "subdevice %pOF: unsupported lanes configuration\n",
++ sensor_node);
++ goto cleanup_exit;
++ }
++
++ dev->max_data_lanes = 1;
++ dev->bus_flags = ep.bus.mipi_csi1.strobe;
++ break;
++
++ default:
++ /* Unsupported bus type */
++ unicam_err(dev, "subdevice %pOF: unsupported bus type %u\n",
++ sensor_node, ep.bus_type);
++ goto cleanup_exit;
++ }
++
++ unicam_dbg(3, dev, "subdevice %pOF: %s bus, %u data lanes, flags=0x%08x\n",
++ sensor_node,
++ dev->bus_type == V4L2_MBUS_CSI2_DPHY ? "CSI-2" : "CCP2",
++ dev->max_data_lanes, dev->bus_flags);
++
++ /* Initialize and register the async notifier. */
++ v4l2_async_notifier_init(&dev->notifier);
++ dev->notifier.ops = &unicam_async_ops;
++
++ dev->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
++ dev->asd.match.fwnode = of_fwnode_handle(sensor_node);
++ ret = v4l2_async_notifier_add_subdev(&dev->notifier, &dev->asd);
++ if (ret) {
++ unicam_err(dev, "Error adding subdevice: %d\n", ret);
++ goto cleanup_exit;
++ }
++
++ ret = v4l2_async_notifier_register(&dev->v4l2_dev, &dev->notifier);
++ if (ret) {
++ unicam_err(dev, "Error registering async notifier: %d\n", ret);
++ ret = -EINVAL;
++ }
++
++cleanup_exit:
++ of_node_put(sensor_node);
++ of_node_put(ep_node);
++
++ return ret;
++}
++
++static int unicam_probe(struct platform_device *pdev)
++{
++ struct unicam_device *unicam;
++ int ret;
++
++ unicam = kzalloc(sizeof(*unicam), GFP_KERNEL);
++ if (!unicam)
++ return -ENOMEM;
++
++ kref_init(&unicam->kref);
++ unicam->pdev = pdev;
++
++ unicam->base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(unicam->base)) {
++ unicam_err(unicam, "Failed to get main io block\n");
++ ret = PTR_ERR(unicam->base);
++ goto err_unicam_put;
++ }
++
++ unicam->clk_gate_base = devm_platform_ioremap_resource(pdev, 1);
++ if (IS_ERR(unicam->clk_gate_base)) {
++ unicam_err(unicam, "Failed to get 2nd io block\n");
++ ret = PTR_ERR(unicam->clk_gate_base);
++ goto err_unicam_put;
++ }
++
++ unicam->clock = devm_clk_get(&pdev->dev, "lp");
++ if (IS_ERR(unicam->clock)) {
++ unicam_err(unicam, "Failed to get clock\n");
++ ret = PTR_ERR(unicam->clock);
++ goto err_unicam_put;
++ }
++
++ ret = platform_get_irq(pdev, 0);
++ if (ret <= 0) {
++ dev_err(&pdev->dev, "No IRQ resource\n");
++ ret = -EINVAL;
++ goto err_unicam_put;
++ }
++
++ ret = devm_request_irq(&pdev->dev, ret, unicam_isr, 0,
++ "unicam_capture0", unicam);
++ if (ret) {
++ dev_err(&pdev->dev, "Unable to request interrupt\n");
++ ret = -EINVAL;
++ goto err_unicam_put;
++ }
++
++ unicam->mdev.dev = &pdev->dev;
++ strscpy(unicam->mdev.model, UNICAM_MODULE_NAME,
++ sizeof(unicam->mdev.model));
++ strscpy(unicam->mdev.serial, "", sizeof(unicam->mdev.serial));
++ snprintf(unicam->mdev.bus_info, sizeof(unicam->mdev.bus_info),
++ "platform:%s", dev_name(&pdev->dev));
++ unicam->mdev.hw_revision = 0;
++
++ media_device_init(&unicam->mdev);
++
++ unicam->v4l2_dev.mdev = &unicam->mdev;
++
++ ret = v4l2_device_register(&pdev->dev, &unicam->v4l2_dev);
++ if (ret) {
++ unicam_err(unicam,
++ "Unable to register v4l2 device.\n");
++ goto err_unicam_put;
++ }
++
++ ret = media_device_register(&unicam->mdev);
++ if (ret < 0) {
++ unicam_err(unicam,
++ "Unable to register media-controller device.\n");
++ goto err_v4l2_unregister;
++ }
++
++ /* Reserve space for the controls */
++ ret = v4l2_ctrl_handler_init(&unicam->ctrl_handler, 16);
++ if (ret < 0)
++ goto err_media_unregister;
++
++ /* set the driver data in platform device */
++ platform_set_drvdata(pdev, unicam);
++
++ ret = of_unicam_connect_subdevs(unicam);
++ if (ret) {
++ dev_err(&pdev->dev, "Failed to connect subdevs\n");
++ goto err_media_unregister;
++ }
++
++ /* Enable the block power domain */
++ pm_runtime_enable(&pdev->dev);
++
++ return 0;
++
++err_media_unregister:
++ media_device_unregister(&unicam->mdev);
++err_v4l2_unregister:
++ v4l2_device_unregister(&unicam->v4l2_dev);
++err_unicam_put:
++ unicam_put(unicam);
++
++ return ret;
++}
++
++static int unicam_remove(struct platform_device *pdev)
++{
++ struct unicam_device *unicam = platform_get_drvdata(pdev);
++
++ unicam_dbg(2, unicam, "%s\n", __func__);
++
++ v4l2_async_notifier_unregister(&unicam->notifier);
++ v4l2_device_unregister(&unicam->v4l2_dev);
++ media_device_unregister(&unicam->mdev);
++ unregister_nodes(unicam);
++
++ pm_runtime_disable(&pdev->dev);
++
++ return 0;
++}
++
++static const struct of_device_id unicam_of_match[] = {
++ { .compatible = "brcm,bcm2835-unicam", },
++ { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, unicam_of_match);
++
++static struct platform_driver unicam_driver = {
++ .probe = unicam_probe,
++ .remove = unicam_remove,
++ .driver = {
++ .name = UNICAM_MODULE_NAME,
++ .of_match_table = of_match_ptr(unicam_of_match),
++ },
++};
++
++module_platform_driver(unicam_driver);
++
++MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.com>");
++MODULE_DESCRIPTION("BCM2835 Unicam driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(UNICAM_VERSION);
+--- /dev/null
++++ b/drivers/media/platform/bcm2835/vc4-regs-unicam.h
+@@ -0,0 +1,253 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++/*
++ * Copyright (C) 2017-2020 Raspberry Pi Trading.
++ * Dave Stevenson <dave.stevenson@raspberrypi.com>
++ */
++
++#ifndef VC4_REGS_UNICAM_H
++#define VC4_REGS_UNICAM_H
++
++/*
++ * The following values are taken from files found within the code drop
++ * made by Broadcom for the BCM21553 Graphics Driver, predominantly in
++ * brcm_usrlib/dag/vmcsx/vcinclude/hardware_vc4.h.
++ * They have been modified to be only the register offset.
++ */
++#define UNICAM_CTRL 0x000
++#define UNICAM_STA 0x004
++#define UNICAM_ANA 0x008
++#define UNICAM_PRI 0x00c
++#define UNICAM_CLK 0x010
++#define UNICAM_CLT 0x014
++#define UNICAM_DAT0 0x018
++#define UNICAM_DAT1 0x01c
++#define UNICAM_DAT2 0x020
++#define UNICAM_DAT3 0x024
++#define UNICAM_DLT 0x028
++#define UNICAM_CMP0 0x02c
++#define UNICAM_CMP1 0x030
++#define UNICAM_CAP0 0x034
++#define UNICAM_CAP1 0x038
++#define UNICAM_ICTL 0x100
++#define UNICAM_ISTA 0x104
++#define UNICAM_IDI0 0x108
++#define UNICAM_IPIPE 0x10c
++#define UNICAM_IBSA0 0x110
++#define UNICAM_IBEA0 0x114
++#define UNICAM_IBLS 0x118
++#define UNICAM_IBWP 0x11c
++#define UNICAM_IHWIN 0x120
++#define UNICAM_IHSTA 0x124
++#define UNICAM_IVWIN 0x128
++#define UNICAM_IVSTA 0x12c
++#define UNICAM_ICC 0x130
++#define UNICAM_ICS 0x134
++#define UNICAM_IDC 0x138
++#define UNICAM_IDPO 0x13c
++#define UNICAM_IDCA 0x140
++#define UNICAM_IDCD 0x144
++#define UNICAM_IDS 0x148
++#define UNICAM_DCS 0x200
++#define UNICAM_DBSA0 0x204
++#define UNICAM_DBEA0 0x208
++#define UNICAM_DBWP 0x20c
++#define UNICAM_DBCTL 0x300
++#define UNICAM_IBSA1 0x304
++#define UNICAM_IBEA1 0x308
++#define UNICAM_IDI1 0x30c
++#define UNICAM_DBSA1 0x310
++#define UNICAM_DBEA1 0x314
++#define UNICAM_MISC 0x400
++
++/*
++ * The following bitmasks are from the kernel released by Broadcom
++ * for Android - https://android.googlesource.com/kernel/bcm/
++ * The Rhea, Hawaii, and Java chips all contain the same VideoCore4
++ * Unicam block as BCM2835, as defined in eg
++ * arch/arm/mach-rhea/include/mach/rdb_A0/brcm_rdb_cam.h and similar.
++ * Values reworked to use the kernel BIT and GENMASK macros.
++ *
++ * Some of the bit mnenomics have been amended to match the datasheet.
++ */
++/* UNICAM_CTRL Register */
++#define UNICAM_CPE BIT(0)
++#define UNICAM_MEM BIT(1)
++#define UNICAM_CPR BIT(2)
++#define UNICAM_CPM_MASK GENMASK(3, 3)
++#define UNICAM_CPM_CSI2 0
++#define UNICAM_CPM_CCP2 1
++#define UNICAM_SOE BIT(4)
++#define UNICAM_DCM_MASK GENMASK(5, 5)
++#define UNICAM_DCM_STROBE 0
++#define UNICAM_DCM_DATA 1
++#define UNICAM_SLS BIT(6)
++#define UNICAM_PFT_MASK GENMASK(11, 8)
++#define UNICAM_OET_MASK GENMASK(20, 12)
++
++/* UNICAM_STA Register */
++#define UNICAM_SYN BIT(0)
++#define UNICAM_CS BIT(1)
++#define UNICAM_SBE BIT(2)
++#define UNICAM_PBE BIT(3)
++#define UNICAM_HOE BIT(4)
++#define UNICAM_PLE BIT(5)
++#define UNICAM_SSC BIT(6)
++#define UNICAM_CRCE BIT(7)
++#define UNICAM_OES BIT(8)
++#define UNICAM_IFO BIT(9)
++#define UNICAM_OFO BIT(10)
++#define UNICAM_BFO BIT(11)
++#define UNICAM_DL BIT(12)
++#define UNICAM_PS BIT(13)
++#define UNICAM_IS BIT(14)
++#define UNICAM_PI0 BIT(15)
++#define UNICAM_PI1 BIT(16)
++#define UNICAM_FSI_S BIT(17)
++#define UNICAM_FEI_S BIT(18)
++#define UNICAM_LCI_S BIT(19)
++#define UNICAM_BUF0_RDY BIT(20)
++#define UNICAM_BUF0_NO BIT(21)
++#define UNICAM_BUF1_RDY BIT(22)
++#define UNICAM_BUF1_NO BIT(23)
++#define UNICAM_DI BIT(24)
++
++#define UNICAM_STA_MASK_ALL \
++ (UNICAM_DL + \
++ UNICAM_SBE + \
++ UNICAM_PBE + \
++ UNICAM_HOE + \
++ UNICAM_PLE + \
++ UNICAM_SSC + \
++ UNICAM_CRCE + \
++ UNICAM_IFO + \
++ UNICAM_OFO + \
++ UNICAM_PS + \
++ UNICAM_PI0 + \
++ UNICAM_PI1)
++
++/* UNICAM_ANA Register */
++#define UNICAM_APD BIT(0)
++#define UNICAM_BPD BIT(1)
++#define UNICAM_AR BIT(2)
++#define UNICAM_DDL BIT(3)
++#define UNICAM_CTATADJ_MASK GENMASK(7, 4)
++#define UNICAM_PTATADJ_MASK GENMASK(11, 8)
++
++/* UNICAM_PRI Register */
++#define UNICAM_PE BIT(0)
++#define UNICAM_PT_MASK GENMASK(2, 1)
++#define UNICAM_NP_MASK GENMASK(7, 4)
++#define UNICAM_PP_MASK GENMASK(11, 8)
++#define UNICAM_BS_MASK GENMASK(15, 12)
++#define UNICAM_BL_MASK GENMASK(17, 16)
++
++/* UNICAM_CLK Register */
++#define UNICAM_CLE BIT(0)
++#define UNICAM_CLPD BIT(1)
++#define UNICAM_CLLPE BIT(2)
++#define UNICAM_CLHSE BIT(3)
++#define UNICAM_CLTRE BIT(4)
++#define UNICAM_CLAC_MASK GENMASK(8, 5)
++#define UNICAM_CLSTE BIT(29)
++
++/* UNICAM_CLT Register */
++#define UNICAM_CLT1_MASK GENMASK(7, 0)
++#define UNICAM_CLT2_MASK GENMASK(15, 8)
++
++/* UNICAM_DATn Registers */
++#define UNICAM_DLE BIT(0)
++#define UNICAM_DLPD BIT(1)
++#define UNICAM_DLLPE BIT(2)
++#define UNICAM_DLHSE BIT(3)
++#define UNICAM_DLTRE BIT(4)
++#define UNICAM_DLSM BIT(5)
++#define UNICAM_DLFO BIT(28)
++#define UNICAM_DLSTE BIT(29)
++
++#define UNICAM_DAT_MASK_ALL (UNICAM_DLSTE + UNICAM_DLFO)
++
++/* UNICAM_DLT Register */
++#define UNICAM_DLT1_MASK GENMASK(7, 0)
++#define UNICAM_DLT2_MASK GENMASK(15, 8)
++#define UNICAM_DLT3_MASK GENMASK(23, 16)
++
++/* UNICAM_ICTL Register */
++#define UNICAM_FSIE BIT(0)
++#define UNICAM_FEIE BIT(1)
++#define UNICAM_IBOB BIT(2)
++#define UNICAM_FCM BIT(3)
++#define UNICAM_TFC BIT(4)
++#define UNICAM_LIP_MASK GENMASK(6, 5)
++#define UNICAM_LCIE_MASK GENMASK(28, 16)
++
++/* UNICAM_IDI0/1 Register */
++#define UNICAM_ID0_MASK GENMASK(7, 0)
++#define UNICAM_ID1_MASK GENMASK(15, 8)
++#define UNICAM_ID2_MASK GENMASK(23, 16)
++#define UNICAM_ID3_MASK GENMASK(31, 24)
++
++/* UNICAM_ISTA Register */
++#define UNICAM_FSI BIT(0)
++#define UNICAM_FEI BIT(1)
++#define UNICAM_LCI BIT(2)
++
++#define UNICAM_ISTA_MASK_ALL (UNICAM_FSI + UNICAM_FEI + UNICAM_LCI)
++
++/* UNICAM_IPIPE Register */
++#define UNICAM_PUM_MASK GENMASK(2, 0)
++ /* Unpacking modes */
++ #define UNICAM_PUM_NONE 0
++ #define UNICAM_PUM_UNPACK6 1
++ #define UNICAM_PUM_UNPACK7 2
++ #define UNICAM_PUM_UNPACK8 3
++ #define UNICAM_PUM_UNPACK10 4
++ #define UNICAM_PUM_UNPACK12 5
++ #define UNICAM_PUM_UNPACK14 6
++ #define UNICAM_PUM_UNPACK16 7
++#define UNICAM_DDM_MASK GENMASK(6, 3)
++#define UNICAM_PPM_MASK GENMASK(9, 7)
++ /* Packing modes */
++ #define UNICAM_PPM_NONE 0
++ #define UNICAM_PPM_PACK8 1
++ #define UNICAM_PPM_PACK10 2
++ #define UNICAM_PPM_PACK12 3
++ #define UNICAM_PPM_PACK14 4
++ #define UNICAM_PPM_PACK16 5
++#define UNICAM_DEM_MASK GENMASK(11, 10)
++#define UNICAM_DEBL_MASK GENMASK(14, 12)
++#define UNICAM_ICM_MASK GENMASK(16, 15)
++#define UNICAM_IDM_MASK GENMASK(17, 17)
++
++/* UNICAM_ICC Register */
++#define UNICAM_ICFL_MASK GENMASK(4, 0)
++#define UNICAM_ICFH_MASK GENMASK(9, 5)
++#define UNICAM_ICST_MASK GENMASK(12, 10)
++#define UNICAM_ICLT_MASK GENMASK(15, 13)
++#define UNICAM_ICLL_MASK GENMASK(31, 16)
++
++/* UNICAM_DCS Register */
++#define UNICAM_DIE BIT(0)
++#define UNICAM_DIM BIT(1)
++#define UNICAM_DBOB BIT(3)
++#define UNICAM_FDE BIT(4)
++#define UNICAM_LDP BIT(5)
++#define UNICAM_EDL_MASK GENMASK(15, 8)
++
++/* UNICAM_DBCTL Register */
++#define UNICAM_DBEN BIT(0)
++#define UNICAM_BUF0_IE BIT(1)
++#define UNICAM_BUF1_IE BIT(2)
++
++/* UNICAM_CMP[0,1] register */
++#define UNICAM_PCE BIT(31)
++#define UNICAM_GI BIT(9)
++#define UNICAM_CPH BIT(8)
++#define UNICAM_PCVC_MASK GENMASK(7, 6)
++#define UNICAM_PCDT_MASK GENMASK(5, 0)
++
++/* UNICAM_MISC register */
++#define UNICAM_FL0 BIT(6)
++#define UNICAM_FL1 BIT(9)
++
++#endif
diff --git a/target/linux/bcm27xx/patches-5.4/950-0807-media-bcm2835-unicam-Add-support-for-get_mbus_config.patch b/target/linux/bcm27xx/patches-5.4/950-0807-media-bcm2835-unicam-Add-support-for-get_mbus_config.patch
new file mode 100644
index 0000000000..8e3cef06d4
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0807-media-bcm2835-unicam-Add-support-for-get_mbus_config.patch
@@ -0,0 +1,56 @@
+From f1ab20a9584c97eddf07d4f8937f0aff42bd1038 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 23 Jun 2020 14:32:51 +0100
+Subject: [PATCH] media: bcm2835-unicam: Add support for
+ get_mbus_config to set num lanes
+
+Use the get_mbus_config pad subdev call to allow a source to use
+fewer than the number of CSI2 lanes defined in device tree.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../media/platform/bcm2835/bcm2835-unicam.c | 31 ++++++++++++++++---
+ 1 file changed, 27 insertions(+), 4 deletions(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -1639,12 +1639,35 @@ static int unicam_start_streaming(struct
+ goto err_streaming;
+ }
+
+- /*
+- * TODO: Retrieve the number of active data lanes from the connected
+- * subdevice.
+- */
+ dev->active_data_lanes = dev->max_data_lanes;
+
++ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
++ struct v4l2_mbus_config mbus_config = { 0 };
++
++ ret = v4l2_subdev_call(dev->sensor, pad, get_mbus_config,
++ 0, &mbus_config);
++ if (ret < 0 && ret != -ENOIOCTLCMD) {
++ unicam_dbg(3, dev, "g_mbus_config failed\n");
++ goto err_pm_put;
++ }
++
++ dev->active_data_lanes =
++ (mbus_config.flags & V4L2_MBUS_CSI2_LANE_MASK) >>
++ __ffs(V4L2_MBUS_CSI2_LANE_MASK);
++ if (!dev->active_data_lanes)
++ dev->active_data_lanes = dev->max_data_lanes;
++ if (dev->active_data_lanes > dev->max_data_lanes) {
++ unicam_err(dev, "Device has requested %u data lanes, which is >%u configured in DT\n",
++ dev->active_data_lanes,
++ dev->max_data_lanes);
++ ret = -EINVAL;
++ goto err_pm_put;
++ }
++ }
++
++ unicam_dbg(1, dev, "Running with %u data lanes\n",
++ dev->active_data_lanes);
++
+ ret = clk_set_rate(dev->clock, 100 * 1000 * 1000);
+ if (ret) {
+ unicam_err(dev, "failed to set up clock\n");
diff --git a/target/linux/bcm27xx/patches-5.4/950-0808-media-bcm2835-unicam-Always-service-interrupts.patch b/target/linux/bcm27xx/patches-5.4/950-0808-media-bcm2835-unicam-Always-service-interrupts.patch
new file mode 100644
index 0000000000..371013fe60
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0808-media-bcm2835-unicam-Always-service-interrupts.patch
@@ -0,0 +1,51 @@
+From b493e2a03c1780ae1ba09a9de58474c17a33310d Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 13 May 2020 18:28:27 +0100
+Subject: [PATCH] media: bcm2835-unicam: Always service interrupts
+
+From when bringing up the driver, there was a check in the isr
+to ignore interrupts (claiming them handled) should the driver
+not be streaming.
+
+The VPU now will not register a camera driver if it finds a
+CSI2 node enabled in device tree, therefore this flawed check is
+redundant.
+
+https://github.com/raspberrypi/linux/issues/3602
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/platform/bcm2835/bcm2835-unicam.c | 15 ---------------
+ 1 file changed, 15 deletions(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -772,12 +772,6 @@ static bool unicam_all_nodes_streaming(s
+ return ret;
+ }
+
+-static bool unicam_all_nodes_disabled(struct unicam_device *dev)
+-{
+- return !dev->node[IMAGE_PAD].streaming &&
+- !dev->node[METADATA_PAD].streaming;
+-}
+-
+ static void unicam_queue_event_sof(struct unicam_device *unicam)
+ {
+ struct v4l2_event event = {
+@@ -805,15 +799,6 @@ static irqreturn_t unicam_isr(int irq, v
+ u32 ista, sta;
+ u64 ts;
+
+- /*
+- * Don't service interrupts if not streaming.
+- * Avoids issues if the VPU should enable the
+- * peripheral without the kernel knowing (that
+- * shouldn't happen, but causes issues if it does).
+- */
+- if (unicam_all_nodes_disabled(unicam))
+- return IRQ_NONE;
+-
+ sta = reg_read(unicam, UNICAM_STA);
+ /* Write value back to clear the interrupts */
+ reg_write(unicam, UNICAM_STA, sta);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0809-media-bcm2835-unicam-Fix-uninitialized-warning.patch b/target/linux/bcm27xx/patches-5.4/950-0809-media-bcm2835-unicam-Fix-uninitialized-warning.patch
new file mode 100644
index 0000000000..1935c6b78f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0809-media-bcm2835-unicam-Fix-uninitialized-warning.patch
@@ -0,0 +1,21 @@
+From bea7aa3af93ab5eb9b0f993230a802e65023081e Mon Sep 17 00:00:00 2001
+From: Jacko Dirks <jdirks.linuxdev@gmail.com>
+Date: Tue, 5 May 2020 14:33:31 +0200
+Subject: [PATCH] media: bcm2835: unicam: Fix uninitialized warning
+
+Signed-off-by: Jacko Dirks <jdirks.linuxdev@gmail.com>
+---
+ drivers/media/platform/bcm2835/bcm2835-unicam.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -994,7 +994,7 @@ const struct unicam_fmt *get_first_suppo
+ struct v4l2_subdev_mbus_code_enum mbus_code;
+ const struct unicam_fmt *fmt = NULL;
+ unsigned int i;
+- int ret;
++ int ret = 0;
+
+ for (i = 0; ret != -EINVAL && ret != -ENOIOCTLCMD; ++i) {
+ memset(&mbus_code, 0, sizeof(mbus_code));
diff --git a/target/linux/bcm27xx/patches-5.4/950-0810-media-bcm2835-unicam-Fixup-review-comments-from-Hans.patch b/target/linux/bcm27xx/patches-5.4/950-0810-media-bcm2835-unicam-Fixup-review-comments-from-Hans.patch
new file mode 100644
index 0000000000..18565a7933
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0810-media-bcm2835-unicam-Fixup-review-comments-from-Hans.patch
@@ -0,0 +1,242 @@
+From 30351afb528e439a48960443c028b6b9c236c55a Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 23 Jun 2020 15:14:05 +0100
+Subject: [PATCH] media: bcm2835-unicam: Fixup review comments from
+ Hans.
+
+Updates the driver based on the upstream review comments from
+Hans Verkuil at https://patchwork.linuxtv.org/patch/63531/
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/platform/bcm2835/Kconfig | 12 ++--
+ .../media/platform/bcm2835/bcm2835-unicam.c | 70 ++++++++-----------
+ 2 files changed, 39 insertions(+), 43 deletions(-)
+
+--- a/drivers/media/platform/bcm2835/Kconfig
++++ b/drivers/media/platform/bcm2835/Kconfig
+@@ -1,15 +1,19 @@
+ # Broadcom VideoCore4 V4L2 camera support
+
+ config VIDEO_BCM2835_UNICAM
+- tristate "Broadcom BCM2835 Unicam video capture driver"
++ tristate "Broadcom BCM283x/BCM271x Unicam video capture driver"
+ depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER
+ depends on ARCH_BCM2835 || COMPILE_TEST
+ select VIDEOBUF2_DMA_CONTIG
+ select V4L2_FWNODE
+ help
+- Say Y here to enable support for the BCM2835 CSI-2 receiver. This is a
+- V4L2 driver that controls the CSI-2 receiver directly, independently
+- from the VC4 firmware.
++ Say Y here to enable support for the BCM283x/BCM271x CSI-2 receiver.
++ This is a V4L2 driver that controls the CSI-2 receiver directly,
++ independently from the VC4 firmware.
++ This driver is mutually exclusive with the use of bcm2835-camera. The
++ firmware will disable all access to the peripheral from within the
++ firmware if it finds a DT node using it, and bcm2835-camera will
++ therefore fail to probe.
+
+ To compile this driver as a module, choose M here. The module will be
+ called bcm2835-unicam.
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ /*
+- * BCM2835 Unicam Capture Driver
++ * BCM283x / BCM271x Unicam Capture Driver
+ *
+ * Copyright (C) 2017-2020 - Raspberry Pi (Trading) Ltd.
+ *
+@@ -554,9 +554,8 @@ static const struct unicam_fmt *find_for
+ return NULL;
+ }
+
+-static inline unsigned int bytes_per_line(u32 width,
+- const struct unicam_fmt *fmt,
+- u32 v4l2_fourcc)
++static unsigned int bytes_per_line(u32 width, const struct unicam_fmt *fmt,
++ u32 v4l2_fourcc)
+ {
+ if (v4l2_fourcc == fmt->repacked_fourcc)
+ /* Repacking always goes to 16bpp */
+@@ -708,7 +707,7 @@ static void unicam_wr_dma_addr(struct un
+ }
+ }
+
+-static inline unsigned int unicam_get_lines_done(struct unicam_device *dev)
++static unsigned int unicam_get_lines_done(struct unicam_device *dev)
+ {
+ dma_addr_t start_addr, cur_addr;
+ unsigned int stride = dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline;
+@@ -722,7 +721,7 @@ static inline unsigned int unicam_get_li
+ return (unsigned int)(cur_addr - start_addr) / stride;
+ }
+
+-static inline void unicam_schedule_next_buffer(struct unicam_node *node)
++static void unicam_schedule_next_buffer(struct unicam_node *node)
+ {
+ struct unicam_device *dev = node->dev;
+ struct unicam_buffer *buf;
+@@ -741,7 +740,7 @@ static inline void unicam_schedule_next_
+ unicam_wr_dma_addr(dev, addr, size, node->pad_id);
+ }
+
+-static inline void unicam_schedule_dummy_buffer(struct unicam_node *node)
++static void unicam_schedule_dummy_buffer(struct unicam_node *node)
+ {
+ struct unicam_device *dev = node->dev;
+
+@@ -753,8 +752,8 @@ static inline void unicam_schedule_dummy
+ node->next_frm = NULL;
+ }
+
+-static inline void unicam_process_buffer_complete(struct unicam_node *node,
+- unsigned int sequence)
++static void unicam_process_buffer_complete(struct unicam_node *node,
++ unsigned int sequence)
+ {
+ node->cur_frm->vb.field = node->m_fmt.field;
+ node->cur_frm->vb.sequence = sequence;
+@@ -762,16 +761,6 @@ static inline void unicam_process_buffer
+ vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
+ }
+
+-static bool unicam_all_nodes_streaming(struct unicam_device *dev)
+-{
+- bool ret;
+-
+- ret = dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming;
+- ret &= !dev->node[METADATA_PAD].open ||
+- dev->node[METADATA_PAD].streaming;
+- return ret;
+-}
+-
+ static void unicam_queue_event_sof(struct unicam_device *unicam)
+ {
+ struct v4l2_event event = {
+@@ -894,8 +883,8 @@ static int unicam_querycap(struct file *
+ struct unicam_node *node = video_drvdata(file);
+ struct unicam_device *dev = node->dev;
+
+- strlcpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver));
+- strlcpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card));
++ strscpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver));
++ strscpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card));
+
+ snprintf(cap->bus_info, sizeof(cap->bus_info),
+ "platform:%s", dev_name(&dev->pdev->dev));
+@@ -988,8 +977,8 @@ static int unicam_g_fmt_vid_cap(struct f
+ return 0;
+ }
+
+-static
+-const struct unicam_fmt *get_first_supported_format(struct unicam_device *dev)
++static const struct unicam_fmt *
++get_first_supported_format(struct unicam_device *dev)
+ {
+ struct v4l2_subdev_mbus_code_enum mbus_code;
+ const struct unicam_fmt *fmt = NULL;
+@@ -1579,7 +1568,8 @@ static void unicam_disable(struct unicam
+ clk_write(dev, 0);
+ }
+
+-static void unicam_return_buffers(struct unicam_node *node)
++static void unicam_return_buffers(struct unicam_node *node,
++ enum vb2_buffer_state state)
+ {
+ struct unicam_buffer *buf, *tmp;
+ unsigned long flags;
+@@ -1587,15 +1577,15 @@ static void unicam_return_buffers(struct
+ spin_lock_irqsave(&node->dma_queue_lock, flags);
+ list_for_each_entry_safe(buf, tmp, &node->dma_queue, list) {
+ list_del(&buf->list);
+- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
++ vb2_buffer_done(&buf->vb.vb2_buf, state);
+ }
+
+ if (node->cur_frm)
+ vb2_buffer_done(&node->cur_frm->vb.vb2_buf,
+- VB2_BUF_STATE_ERROR);
++ state);
+ if (node->next_frm && node->cur_frm != node->next_frm)
+ vb2_buffer_done(&node->next_frm->vb.vb2_buf,
+- VB2_BUF_STATE_ERROR);
++ state);
+
+ node->cur_frm = NULL;
+ node->next_frm = NULL;
+@@ -1612,7 +1602,13 @@ static int unicam_start_streaming(struct
+ int ret;
+
+ node->streaming = true;
+- if (!unicam_all_nodes_streaming(dev)) {
++ if (!(dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming &&
++ (!dev->node[METADATA_PAD].open ||
++ dev->node[METADATA_PAD].streaming))) {
++ /*
++ * Metadata pad must be enabled before image pad if it is
++ * wanted.
++ */
+ unicam_dbg(3, dev, "Not all nodes are streaming yet.");
+ return 0;
+ }
+@@ -1699,7 +1695,7 @@ err_disable_unicam:
+ err_pm_put:
+ unicam_runtime_put(dev);
+ err_streaming:
+- unicam_return_buffers(node);
++ unicam_return_buffers(node, VB2_BUF_STATE_QUEUED);
+ node->streaming = false;
+
+ return ret;
+@@ -1736,7 +1732,7 @@ static void unicam_stop_streaming(struct
+ }
+
+ /* Clear all queued buffers for the node */
+- unicam_return_buffers(node);
++ unicam_return_buffers(node, VB2_BUF_STATE_ERROR);
+ }
+
+ static int unicam_enum_input(struct file *file, void *priv,
+@@ -1754,14 +1750,13 @@ static int unicam_enum_input(struct file
+ inp->std = 0;
+ } else if (v4l2_subdev_has_op(dev->sensor, video, s_std)) {
+ inp->capabilities = V4L2_IN_CAP_STD;
+- if (v4l2_subdev_call(dev->sensor, video, g_tvnorms, &inp->std)
+- < 0)
++ if (v4l2_subdev_call(dev->sensor, video, g_tvnorms, &inp->std) < 0)
+ inp->std = V4L2_STD_ALL;
+ } else {
+ inp->capabilities = 0;
+ inp->std = 0;
+ }
+- sprintf(inp->name, "Camera 0");
++ snprintf(inp->name, sizeof(inp->name), "Camera 0");
+ return 0;
+ }
+
+@@ -1984,6 +1979,9 @@ static int unicam_s_dv_timings(struct fi
+ ret = v4l2_subdev_call(dev->sensor, video, g_dv_timings,
+ &current_timings);
+
++ if (ret < 0)
++ return ret;
++
+ if (v4l2_match_dv_timings(timings, &current_timings, 0, false))
+ return 0;
+
+@@ -2414,12 +2412,6 @@ static int register_node(struct unicam_d
+ unicam_err(unicam, "Unable to allocate dummy buffer.\n");
+ return -ENOMEM;
+ }
+-
+- if (pad_id == METADATA_PAD) {
+- v4l2_disable_ioctl(vdev, VIDIOC_DQEVENT);
+- v4l2_disable_ioctl(vdev, VIDIOC_SUBSCRIBE_EVENT);
+- v4l2_disable_ioctl(vdev, VIDIOC_UNSUBSCRIBE_EVENT);
+- }
+ if (pad_id == METADATA_PAD ||
+ !v4l2_subdev_has_op(unicam->sensor, video, s_std)) {
+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_STD);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0811-media-bcm2835-unicam-Retain-packing-information-on-G.patch b/target/linux/bcm27xx/patches-5.4/950-0811-media-bcm2835-unicam-Retain-packing-information-on-G.patch
new file mode 100644
index 0000000000..8d2b9d8ea3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0811-media-bcm2835-unicam-Retain-packing-information-on-G.patch
@@ -0,0 +1,48 @@
+From bf722c887dd9d0d24493edd20c61b2fcde5f66dd Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 19 May 2020 11:46:47 +0100
+Subject: [PATCH] media: bcm2835-unicam: Retain packing information
+ on G_FMT
+
+The change to retrieve the pixel format always on g_fmt didn't
+check whether the native or unpacked version of the format
+had been requested, and always returned the packed one.
+Correct this so that the packing setting is retained whereever
+possible.
+
+Fixes "9d59e89 media: bcm2835-unicam: Re-fetch mbus code from subdev
+on a g_fmt call"
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../media/platform/bcm2835/bcm2835-unicam.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -970,8 +970,23 @@ static int unicam_g_fmt_vid_cap(struct f
+ if (!fmt)
+ return -EINVAL;
+
+- node->fmt = fmt;
+- node->v_fmt.fmt.pix.pixelformat = fmt->fourcc;
++ if (node->fmt != fmt) {
++ /*
++ * The sensor format has changed so the pixelformat needs to
++ * be updated. Try and retain the packed/unpacked choice if
++ * at all possible.
++ */
++ if (node->fmt->repacked_fourcc ==
++ node->v_fmt.fmt.pix.pixelformat)
++ /* Using the repacked format */
++ node->v_fmt.fmt.pix.pixelformat = fmt->repacked_fourcc;
++ else
++ /* Using the native format */
++ node->v_fmt.fmt.pix.pixelformat = fmt->fourcc;
++
++ node->fmt = fmt;
++ }
++
+ *f = node->v_fmt;
+
+ return 0;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0812-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch b/target/linux/bcm27xx/patches-5.4/950-0812-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch
new file mode 100644
index 0000000000..770b00b88a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0812-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch
@@ -0,0 +1,28 @@
+From 4f745137c92902f4f541ebe5e458dd2c4e89a42d Mon Sep 17 00:00:00 2001
+From: David Plowman <david.plowman@raspberrypi.com>
+Date: Thu, 28 May 2020 11:09:48 +0100
+Subject: [PATCH] media: bcm2835-unicam: change minimum number of
+ vb2_queue buffers to 1
+
+Since the unicam driver was modified to write to a dummy buffer when no
+user-supplied buffer is available, it can now write to and return a
+buffer even when there's only a single one. Enable this by changing the
+min_buffers_needed in the vb2_queue; it will be useful for enabling
+still captures without allocating more memory than absolutely necessary.
+
+Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
+---
+ drivers/media/platform/bcm2835/bcm2835-unicam.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -2387,7 +2387,7 @@ static int register_node(struct unicam_d
+ q->buf_struct_size = sizeof(struct unicam_buffer);
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &node->lock;
+- q->min_buffers_needed = 2;
++ q->min_buffers_needed = 1;
+ q->dev = &unicam->pdev->dev;
+
+ ret = vb2_queue_init(q);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0813-dt-dtoverlays-Fix-up-base-DT-and-overlays-for-update.patch b/target/linux/bcm27xx/patches-5.4/950-0813-dt-dtoverlays-Fix-up-base-DT-and-overlays-for-update.patch
new file mode 100644
index 0000000000..edfca1ed67
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0813-dt-dtoverlays-Fix-up-base-DT-and-overlays-for-update.patch
@@ -0,0 +1,144 @@
+From 7a1905f969cfa2e303f5e74efee56dbd0523e5bb Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 23 Jun 2020 15:41:42 +0100
+Subject: [PATCH] dt/dtoverlays: Fix up base DT and overlays for
+ updated Unicam driver
+
+The upstreamed Unicam driver uses a dt property to denote how many
+lanes are supported by the receiver peripheral, independent of
+the number of lanes that the sensor wants to use. It also doesn't
+check the remote endpoint config for the number of lanes as that
+isn't the accepted way of doing things.
+
+Update the base DT for the brcm,num-data-lanes property, and the
+overlays to define the desired number of lanes at both ends of
+the link.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 3 ++-
+ arch/arm/boot/dts/bcm283x-rpi-csi0-2lane.dtsi | 6 +-----
+ arch/arm/boot/dts/bcm283x-rpi-csi1-2lane.dtsi | 6 +-----
+ arch/arm/boot/dts/bcm283x-rpi-csi1-4lane.dtsi | 6 +-----
+ arch/arm/boot/dts/overlays/adv7282m-overlay.dts | 1 +
+ arch/arm/boot/dts/overlays/imx477-overlay.dts | 1 +
+ arch/arm/boot/dts/overlays/irs1125-overlay.dts | 2 ++
+ arch/arm/boot/dts/overlays/ov5647-overlay.dts | 1 +
+ arch/arm/boot/dts/overlays/tc358743-overlay.dts | 16 +++++++++++++++-
+ 9 files changed, 25 insertions(+), 17 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
+@@ -203,7 +203,8 @@
+ };
+
+ #include "bcm2711-rpi.dtsi"
+-#include "bcm283x-rpi-csi1-2lane.dtsi"
++#include "bcm283x-rpi-csi0-2lane.dtsi"
++#include "bcm283x-rpi-csi1-4lane.dtsi"
+ #include "bcm283x-rpi-i2c0mux_0_44.dtsi"
+
+ /delete-node/ &emmc2;
+--- a/arch/arm/boot/dts/bcm283x-rpi-csi0-2lane.dtsi
++++ b/arch/arm/boot/dts/bcm283x-rpi-csi0-2lane.dtsi
+@@ -1,8 +1,4 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ &csi0 {
+- port {
+- endpoint {
+- data-lanes = <1 2>;
+- };
+- };
++ brcm,num-data-lanes = <2>;
+ };
+--- a/arch/arm/boot/dts/bcm283x-rpi-csi1-2lane.dtsi
++++ b/arch/arm/boot/dts/bcm283x-rpi-csi1-2lane.dtsi
+@@ -1,8 +1,4 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ &csi1 {
+- port {
+- endpoint {
+- data-lanes = <1 2>;
+- };
+- };
++ brcm,num-data-lanes = <2>;
+ };
+--- a/arch/arm/boot/dts/bcm283x-rpi-csi1-4lane.dtsi
++++ b/arch/arm/boot/dts/bcm283x-rpi-csi1-4lane.dtsi
+@@ -1,8 +1,4 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ &csi1 {
+- port {
+- endpoint {
+- data-lanes = <1 2 3 4>;
+- };
+- };
++ brcm,num-data-lanes = <4>;
+ };
+--- a/arch/arm/boot/dts/overlays/adv7282m-overlay.dts
++++ b/arch/arm/boot/dts/overlays/adv7282m-overlay.dts
+@@ -40,6 +40,7 @@
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&adv728x_0>;
++ data-lanes = <1>;
+ };
+ };
+ };
+--- a/arch/arm/boot/dts/overlays/imx477-overlay.dts
++++ b/arch/arm/boot/dts/overlays/imx477-overlay.dts
+@@ -49,6 +49,7 @@
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&imx477_0>;
++ data-lanes = <1 2>;
+ };
+ };
+ };
+--- a/arch/arm/boot/dts/overlays/irs1125-overlay.dts
++++ b/arch/arm/boot/dts/overlays/irs1125-overlay.dts
+@@ -43,6 +43,8 @@
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&irs1125_0>;
++ data-lanes = <1 2>;
++ clock-noncontinuous;
+ };
+ };
+ };
+--- a/arch/arm/boot/dts/overlays/ov5647-overlay.dts
++++ b/arch/arm/boot/dts/overlays/ov5647-overlay.dts
+@@ -43,6 +43,7 @@
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&ov5647_0>;
++ data-lanes = <1 2>;
+ };
+ };
+ };
+--- a/arch/arm/boot/dts/overlays/tc358743-overlay.dts
++++ b/arch/arm/boot/dts/overlays/tc358743-overlay.dts
+@@ -86,8 +86,22 @@
+ };
+ };
+
++ fragment@7 {
++ target = <&csi1_ep>;
++ __overlay__ {
++ data-lanes = <1 2>;
++ };
++ };
++
++ fragment@8 {
++ target = <&csi1_ep>;
++ __dormant__ {
++ data-lanes = <1 2 3 4>;
++ };
++ };
++
+ __overrides__ {
+- 4lane = <0>, "-2+3";
++ 4lane = <0>, "-2+3-7+8";
+ link-frequency = <&tc358743>,"link-frequencies#0";
+ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0814-media-bcm2835-unicam-Avoid-gcc-warning-over-0-on-end.patch b/target/linux/bcm27xx/patches-5.4/950-0814-media-bcm2835-unicam-Avoid-gcc-warning-over-0-on-end.patch
new file mode 100644
index 0000000000..f70dba77c0
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0814-media-bcm2835-unicam-Avoid-gcc-warning-over-0-on-end.patch
@@ -0,0 +1,27 @@
+From 3f8d0137a1fc1cb0333cb99624213fe4622a92b6 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 26 Jun 2020 15:53:44 +0100
+Subject: [PATCH] media: bcm2835-unicam: Avoid gcc warning over {0}
+ on endpoint
+
+Older gcc versions object to = { 0 } initialisation if the first
+elemtn in the structure is a substructure.
+
+Use = { } to avoid this compiler warning.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/platform/bcm2835/bcm2835-unicam.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -2578,7 +2578,7 @@ static const struct v4l2_async_notifier_
+ static int of_unicam_connect_subdevs(struct unicam_device *dev)
+ {
+ struct platform_device *pdev = dev->pdev;
+- struct v4l2_fwnode_endpoint ep = { 0 };
++ struct v4l2_fwnode_endpoint ep = { };
+ struct device_node *ep_node;
+ struct device_node *sensor_node;
+ unsigned int lane;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0815-media-dt-bindings-media-i2c-Add-IMX290-CMOS-sensor-b.patch b/target/linux/bcm27xx/patches-5.4/950-0815-media-dt-bindings-media-i2c-Add-IMX290-CMOS-sensor-b.patch
new file mode 100644
index 0000000000..120ad34dc2
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0815-media-dt-bindings-media-i2c-Add-IMX290-CMOS-sensor-b.patch
@@ -0,0 +1,98 @@
+From 6bbb873c79b9bb0b3ca95fa4a4fe6cfd0ebe9d2c Mon Sep 17 00:00:00 2001
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Date: Fri, 4 Oct 2019 13:05:24 -0300
+Subject: [PATCH] media: dt-bindings: media: i2c: Add IMX290 CMOS
+ sensor binding
+
+Commit 8a97a4676f8b1badcd9cfbed2b081342847bb1b1 upstream.
+
+Add devicetree binding for IMX290 CMOS image sensor. Let's also
+add MAINTAINERS entry for the binding and driver.
+
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+---
+ .../devicetree/bindings/media/i2c/imx290.txt | 57 +++++++++++++++++++
+ MAINTAINERS | 8 +++
+ 2 files changed, 65 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/media/i2c/imx290.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/media/i2c/imx290.txt
+@@ -0,0 +1,57 @@
++* Sony IMX290 1/2.8-Inch CMOS Image Sensor
++
++The Sony IMX290 is a 1/2.8-Inch CMOS Solid-state image sensor with
++Square Pixel for Color Cameras. It is programmable through I2C and 4-wire
++interfaces. The sensor output is available via CMOS logic parallel SDR output,
++Low voltage LVDS DDR output and CSI-2 serial data output. The CSI-2 bus is the
++default. No bindings have been defined for the other busses.
++
++Required Properties:
++- compatible: Should be "sony,imx290"
++- reg: I2C bus address of the device
++- clocks: Reference to the xclk clock.
++- clock-names: Should be "xclk".
++- clock-frequency: Frequency of the xclk clock in Hz.
++- vdddo-supply: Sensor digital IO regulator.
++- vdda-supply: Sensor analog regulator.
++- vddd-supply: Sensor digital core regulator.
++
++Optional Properties:
++- reset-gpios: Sensor reset GPIO
++
++The imx290 device node should contain one 'port' child node with
++an 'endpoint' subnode. For further reading on port node refer to
++Documentation/devicetree/bindings/media/video-interfaces.txt.
++
++Required Properties on endpoint:
++- data-lanes: check ../video-interfaces.txt
++- link-frequencies: check ../video-interfaces.txt
++- remote-endpoint: check ../video-interfaces.txt
++
++Example:
++ &i2c1 {
++ ...
++ imx290: camera-sensor@1a {
++ compatible = "sony,imx290";
++ reg = <0x1a>;
++
++ reset-gpios = <&msmgpio 35 GPIO_ACTIVE_LOW>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&camera_rear_default>;
++
++ clocks = <&gcc GCC_CAMSS_MCLK0_CLK>;
++ clock-names = "xclk";
++ clock-frequency = <37125000>;
++
++ vdddo-supply = <&camera_vdddo_1v8>;
++ vdda-supply = <&camera_vdda_2v8>;
++ vddd-supply = <&camera_vddd_1v5>;
++
++ port {
++ imx290_ep: endpoint {
++ data-lanes = <1 2 3 4>;
++ link-frequencies = /bits/ 64 <445500000>;
++ remote-endpoint = <&csiphy0_ep>;
++ };
++ };
++ };
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -15200,6 +15200,14 @@ S: Maintained
+ F: drivers/media/i2c/imx274.c
+ F: Documentation/devicetree/bindings/media/i2c/imx274.txt
+
++SONY IMX290 SENSOR DRIVER
++M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
++L: linux-media@vger.kernel.org
++T: git git://linuxtv.org/media_tree.git
++S: Maintained
++F: drivers/media/i2c/imx290.c
++F: Documentation/devicetree/bindings/media/i2c/imx290.txt
++
+ SONY IMX319 SENSOR DRIVER
+ M: Bingbu Cao <bingbu.cao@intel.com>
+ L: linux-media@vger.kernel.org
diff --git a/target/linux/bcm27xx/patches-5.4/950-0816-media-i2c-Add-IMX290-CMOS-image-sensor-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0816-media-i2c-Add-IMX290-CMOS-image-sensor-driver.patch
new file mode 100644
index 0000000000..a44aa767bd
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0816-media-i2c-Add-IMX290-CMOS-image-sensor-driver.patch
@@ -0,0 +1,939 @@
+From d13c94482be9ca356df8a04f8fd5f3738dc31ab1 Mon Sep 17 00:00:00 2001
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Date: Fri, 4 Oct 2019 13:05:25 -0300
+Subject: [PATCH] media: i2c: Add IMX290 CMOS image sensor driver
+
+Commit 828dbc299278065b634e913d2700d254a3224853 upstream.
+
+Add driver for Sony IMX290 CMOS image sensor driver. The driver only
+supports I2C interface for programming and MIPI CSI-2 for sensor output.
+
+[Sakari Ailus: Rewrapped a few lines over 80 chars a little.]
+
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+---
+ drivers/media/i2c/Kconfig | 11 +
+ drivers/media/i2c/Makefile | 1 +
+ drivers/media/i2c/imx290.c | 884 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 896 insertions(+)
+ create mode 100644 drivers/media/i2c/imx290.c
+
+--- a/drivers/media/i2c/Kconfig
++++ b/drivers/media/i2c/Kconfig
+@@ -609,6 +609,17 @@ config VIDEO_IMX274
+ This is a V4L2 sensor driver for the Sony IMX274
+ CMOS image sensor.
+
++config VIDEO_IMX290
++ tristate "Sony IMX290 sensor support"
++ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
++ select V4L2_FWNODE
++ help
++ This is a Video4Linux2 sensor driver for the Sony
++ IMX290 camera sensor.
++
++ To compile this driver as a module, choose M here: the
++ module will be called imx290.
++
+ config VIDEO_IMX477
+ tristate "Sony IMX477 sensor support"
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+--- a/drivers/media/i2c/Makefile
++++ b/drivers/media/i2c/Makefile
+@@ -114,6 +114,7 @@ obj-$(CONFIG_VIDEO_IMX214) += imx214.o
+ obj-$(CONFIG_VIDEO_IMX219) += imx219.o
+ obj-$(CONFIG_VIDEO_IMX258) += imx258.o
+ obj-$(CONFIG_VIDEO_IMX274) += imx274.o
++obj-$(CONFIG_VIDEO_IMX290) += imx290.o
+ obj-$(CONFIG_VIDEO_IMX477) += imx477.o
+ obj-$(CONFIG_VIDEO_IMX319) += imx319.o
+ obj-$(CONFIG_VIDEO_IMX355) += imx355.o
+--- /dev/null
++++ b/drivers/media/i2c/imx290.c
+@@ -0,0 +1,884 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Sony IMX290 CMOS Image Sensor Driver
++ *
++ * Copyright (C) 2019 FRAMOS GmbH.
++ *
++ * Copyright (C) 2019 Linaro Ltd.
++ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/regmap.h>
++#include <linux/regulator/consumer.h>
++#include <media/media-entity.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++
++#define IMX290_STANDBY 0x3000
++#define IMX290_REGHOLD 0x3001
++#define IMX290_XMSTA 0x3002
++#define IMX290_GAIN 0x3014
++
++#define IMX290_DEFAULT_LINK_FREQ 445500000
++
++static const char * const imx290_supply_name[] = {
++ "vdda",
++ "vddd",
++ "vdddo",
++};
++
++#define IMX290_NUM_SUPPLIES ARRAY_SIZE(imx290_supply_name)
++
++struct imx290_regval {
++ u16 reg;
++ u8 val;
++};
++
++struct imx290_mode {
++ u32 width;
++ u32 height;
++ u32 pixel_rate;
++ u32 link_freq_index;
++
++ const struct imx290_regval *data;
++ u32 data_size;
++};
++
++struct imx290 {
++ struct device *dev;
++ struct clk *xclk;
++ struct regmap *regmap;
++
++ struct v4l2_subdev sd;
++ struct v4l2_fwnode_endpoint ep;
++ struct media_pad pad;
++ struct v4l2_mbus_framefmt current_format;
++ const struct imx290_mode *current_mode;
++
++ struct regulator_bulk_data supplies[IMX290_NUM_SUPPLIES];
++ struct gpio_desc *rst_gpio;
++
++ struct v4l2_ctrl_handler ctrls;
++ struct v4l2_ctrl *link_freq;
++ struct v4l2_ctrl *pixel_rate;
++
++ struct mutex lock;
++};
++
++struct imx290_pixfmt {
++ u32 code;
++};
++
++static const struct imx290_pixfmt imx290_formats[] = {
++ { MEDIA_BUS_FMT_SRGGB10_1X10 },
++};
++
++static const struct regmap_config imx290_regmap_config = {
++ .reg_bits = 16,
++ .val_bits = 8,
++ .cache_type = REGCACHE_RBTREE,
++};
++
++static const struct imx290_regval imx290_global_init_settings[] = {
++ { 0x3007, 0x00 },
++ { 0x3009, 0x00 },
++ { 0x3018, 0x65 },
++ { 0x3019, 0x04 },
++ { 0x301a, 0x00 },
++ { 0x3443, 0x03 },
++ { 0x3444, 0x20 },
++ { 0x3445, 0x25 },
++ { 0x3407, 0x03 },
++ { 0x303a, 0x0c },
++ { 0x3040, 0x00 },
++ { 0x3041, 0x00 },
++ { 0x303c, 0x00 },
++ { 0x303d, 0x00 },
++ { 0x3042, 0x9c },
++ { 0x3043, 0x07 },
++ { 0x303e, 0x49 },
++ { 0x303f, 0x04 },
++ { 0x304b, 0x0a },
++ { 0x300f, 0x00 },
++ { 0x3010, 0x21 },
++ { 0x3012, 0x64 },
++ { 0x3016, 0x09 },
++ { 0x3070, 0x02 },
++ { 0x3071, 0x11 },
++ { 0x309b, 0x10 },
++ { 0x309c, 0x22 },
++ { 0x30a2, 0x02 },
++ { 0x30a6, 0x20 },
++ { 0x30a8, 0x20 },
++ { 0x30aa, 0x20 },
++ { 0x30ac, 0x20 },
++ { 0x30b0, 0x43 },
++ { 0x3119, 0x9e },
++ { 0x311c, 0x1e },
++ { 0x311e, 0x08 },
++ { 0x3128, 0x05 },
++ { 0x313d, 0x83 },
++ { 0x3150, 0x03 },
++ { 0x317e, 0x00 },
++ { 0x32b8, 0x50 },
++ { 0x32b9, 0x10 },
++ { 0x32ba, 0x00 },
++ { 0x32bb, 0x04 },
++ { 0x32c8, 0x50 },
++ { 0x32c9, 0x10 },
++ { 0x32ca, 0x00 },
++ { 0x32cb, 0x04 },
++ { 0x332c, 0xd3 },
++ { 0x332d, 0x10 },
++ { 0x332e, 0x0d },
++ { 0x3358, 0x06 },
++ { 0x3359, 0xe1 },
++ { 0x335a, 0x11 },
++ { 0x3360, 0x1e },
++ { 0x3361, 0x61 },
++ { 0x3362, 0x10 },
++ { 0x33b0, 0x50 },
++ { 0x33b2, 0x1a },
++ { 0x33b3, 0x04 },
++};
++
++static const struct imx290_regval imx290_1080p_settings[] = {
++ /* mode settings */
++ { 0x3007, 0x00 },
++ { 0x303a, 0x0c },
++ { 0x3414, 0x0a },
++ { 0x3472, 0x80 },
++ { 0x3473, 0x07 },
++ { 0x3418, 0x38 },
++ { 0x3419, 0x04 },
++ { 0x3012, 0x64 },
++ { 0x3013, 0x00 },
++ { 0x305c, 0x18 },
++ { 0x305d, 0x03 },
++ { 0x305e, 0x20 },
++ { 0x305f, 0x01 },
++ { 0x315e, 0x1a },
++ { 0x3164, 0x1a },
++ { 0x3480, 0x49 },
++ /* data rate settings */
++ { 0x3009, 0x01 },
++ { 0x3405, 0x10 },
++ { 0x3446, 0x57 },
++ { 0x3447, 0x00 },
++ { 0x3448, 0x37 },
++ { 0x3449, 0x00 },
++ { 0x344a, 0x1f },
++ { 0x344b, 0x00 },
++ { 0x344c, 0x1f },
++ { 0x344d, 0x00 },
++ { 0x344e, 0x1f },
++ { 0x344f, 0x00 },
++ { 0x3450, 0x77 },
++ { 0x3451, 0x00 },
++ { 0x3452, 0x1f },
++ { 0x3453, 0x00 },
++ { 0x3454, 0x17 },
++ { 0x3455, 0x00 },
++ { 0x301c, 0x98 },
++ { 0x301d, 0x08 },
++};
++
++static const struct imx290_regval imx290_720p_settings[] = {
++ /* mode settings */
++ { 0x3007, 0x10 },
++ { 0x303a, 0x06 },
++ { 0x3414, 0x04 },
++ { 0x3472, 0x00 },
++ { 0x3473, 0x05 },
++ { 0x3418, 0xd0 },
++ { 0x3419, 0x02 },
++ { 0x3012, 0x64 },
++ { 0x3013, 0x00 },
++ { 0x305c, 0x20 },
++ { 0x305d, 0x00 },
++ { 0x305e, 0x20 },
++ { 0x305f, 0x01 },
++ { 0x315e, 0x1a },
++ { 0x3164, 0x1a },
++ { 0x3480, 0x49 },
++ /* data rate settings */
++ { 0x3009, 0x01 },
++ { 0x3405, 0x10 },
++ { 0x3446, 0x4f },
++ { 0x3447, 0x00 },
++ { 0x3448, 0x2f },
++ { 0x3449, 0x00 },
++ { 0x344a, 0x17 },
++ { 0x344b, 0x00 },
++ { 0x344c, 0x17 },
++ { 0x344d, 0x00 },
++ { 0x344e, 0x17 },
++ { 0x344f, 0x00 },
++ { 0x3450, 0x57 },
++ { 0x3451, 0x00 },
++ { 0x3452, 0x17 },
++ { 0x3453, 0x00 },
++ { 0x3454, 0x17 },
++ { 0x3455, 0x00 },
++ { 0x301c, 0xe4 },
++ { 0x301d, 0x0c },
++};
++
++static const struct imx290_regval imx290_10bit_settings[] = {
++ { 0x3005, 0x00},
++ { 0x3046, 0x00},
++ { 0x3129, 0x1d},
++ { 0x317c, 0x12},
++ { 0x31ec, 0x37},
++ { 0x3441, 0x0a},
++ { 0x3442, 0x0a},
++ { 0x300a, 0x3c},
++ { 0x300b, 0x00},
++};
++
++/* supported link frequencies */
++static const s64 imx290_link_freq[] = {
++ IMX290_DEFAULT_LINK_FREQ,
++};
++
++/* Mode configs */
++static const struct imx290_mode imx290_modes[] = {
++ {
++ .width = 1920,
++ .height = 1080,
++ .data = imx290_1080p_settings,
++ .data_size = ARRAY_SIZE(imx290_1080p_settings),
++ .pixel_rate = 178200000,
++ .link_freq_index = 0,
++ },
++ {
++ .width = 1280,
++ .height = 720,
++ .data = imx290_720p_settings,
++ .data_size = ARRAY_SIZE(imx290_720p_settings),
++ .pixel_rate = 178200000,
++ .link_freq_index = 0,
++ },
++};
++
++static inline struct imx290 *to_imx290(struct v4l2_subdev *_sd)
++{
++ return container_of(_sd, struct imx290, sd);
++}
++
++static inline int imx290_read_reg(struct imx290 *imx290, u16 addr, u8 *value)
++{
++ unsigned int regval;
++ int ret;
++
++ ret = regmap_read(imx290->regmap, addr, &regval);
++ if (ret) {
++ dev_err(imx290->dev, "I2C read failed for addr: %x\n", addr);
++ return ret;
++ }
++
++ *value = regval & 0xff;
++
++ return 0;
++}
++
++static int imx290_write_reg(struct imx290 *imx290, u16 addr, u8 value)
++{
++ int ret;
++
++ ret = regmap_write(imx290->regmap, addr, value);
++ if (ret) {
++ dev_err(imx290->dev, "I2C write failed for addr: %x\n", addr);
++ return ret;
++ }
++
++ return ret;
++}
++
++static int imx290_set_register_array(struct imx290 *imx290,
++ const struct imx290_regval *settings,
++ unsigned int num_settings)
++{
++ unsigned int i;
++ int ret;
++
++ for (i = 0; i < num_settings; ++i, ++settings) {
++ ret = imx290_write_reg(imx290, settings->reg, settings->val);
++ if (ret < 0)
++ return ret;
++
++ /* Settle time is 10ms for all registers */
++ msleep(10);
++ }
++
++ return 0;
++}
++
++static int imx290_write_buffered_reg(struct imx290 *imx290, u16 address_low,
++ u8 nr_regs, u32 value)
++{
++ unsigned int i;
++ int ret;
++
++ ret = imx290_write_reg(imx290, IMX290_REGHOLD, 0x01);
++ if (ret) {
++ dev_err(imx290->dev, "Error setting hold register\n");
++ return ret;
++ }
++
++ for (i = 0; i < nr_regs; i++) {
++ ret = imx290_write_reg(imx290, address_low + i,
++ (u8)(value >> (i * 8)));
++ if (ret) {
++ dev_err(imx290->dev, "Error writing buffered registers\n");
++ return ret;
++ }
++ }
++
++ ret = imx290_write_reg(imx290, IMX290_REGHOLD, 0x00);
++ if (ret) {
++ dev_err(imx290->dev, "Error setting hold register\n");
++ return ret;
++ }
++
++ return ret;
++}
++
++static int imx290_set_gain(struct imx290 *imx290, u32 value)
++{
++ int ret;
++
++ ret = imx290_write_buffered_reg(imx290, IMX290_GAIN, 1, value);
++ if (ret)
++ dev_err(imx290->dev, "Unable to write gain\n");
++
++ return ret;
++}
++
++/* Stop streaming */
++static int imx290_stop_streaming(struct imx290 *imx290)
++{
++ int ret;
++
++ ret = imx290_write_reg(imx290, IMX290_STANDBY, 0x01);
++ if (ret < 0)
++ return ret;
++
++ msleep(30);
++
++ return imx290_write_reg(imx290, IMX290_XMSTA, 0x01);
++}
++
++static int imx290_set_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct imx290 *imx290 = container_of(ctrl->handler,
++ struct imx290, ctrls);
++ int ret = 0;
++
++ /* V4L2 controls values will be applied only when power is already up */
++ if (!pm_runtime_get_if_in_use(imx290->dev))
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_GAIN:
++ ret = imx290_set_gain(imx290, ctrl->val);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ pm_runtime_put(imx290->dev);
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops imx290_ctrl_ops = {
++ .s_ctrl = imx290_set_ctrl,
++};
++
++static int imx290_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->index >= ARRAY_SIZE(imx290_formats))
++ return -EINVAL;
++
++ code->code = imx290_formats[code->index].code;
++
++ return 0;
++}
++
++static int imx290_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *fmt)
++{
++ struct imx290 *imx290 = to_imx290(sd);
++ struct v4l2_mbus_framefmt *framefmt;
++
++ mutex_lock(&imx290->lock);
++
++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
++ framefmt = v4l2_subdev_get_try_format(&imx290->sd, cfg,
++ fmt->pad);
++ else
++ framefmt = &imx290->current_format;
++
++ fmt->format = *framefmt;
++
++ mutex_unlock(&imx290->lock);
++
++ return 0;
++}
++
++static int imx290_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *fmt)
++{
++ struct imx290 *imx290 = to_imx290(sd);
++ const struct imx290_mode *mode;
++ struct v4l2_mbus_framefmt *format;
++ unsigned int i;
++
++ mutex_lock(&imx290->lock);
++
++ mode = v4l2_find_nearest_size(imx290_modes,
++ ARRAY_SIZE(imx290_modes),
++ width, height,
++ fmt->format.width, fmt->format.height);
++
++ fmt->format.width = mode->width;
++ fmt->format.height = mode->height;
++
++ for (i = 0; i < ARRAY_SIZE(imx290_formats); i++)
++ if (imx290_formats[i].code == fmt->format.code)
++ break;
++
++ if (i >= ARRAY_SIZE(imx290_formats))
++ i = 0;
++
++ fmt->format.code = imx290_formats[i].code;
++ fmt->format.field = V4L2_FIELD_NONE;
++
++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++ format = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
++ } else {
++ format = &imx290->current_format;
++ __v4l2_ctrl_s_ctrl(imx290->link_freq, mode->link_freq_index);
++ __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate, mode->pixel_rate);
++
++ imx290->current_mode = mode;
++ }
++
++ *format = fmt->format;
++
++ mutex_unlock(&imx290->lock);
++
++ return 0;
++}
++
++static int imx290_entity_init_cfg(struct v4l2_subdev *subdev,
++ struct v4l2_subdev_pad_config *cfg)
++{
++ struct v4l2_subdev_format fmt = { 0 };
++
++ fmt.which = cfg ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
++ fmt.format.width = 1920;
++ fmt.format.height = 1080;
++
++ imx290_set_fmt(subdev, cfg, &fmt);
++
++ return 0;
++}
++
++static int imx290_write_current_format(struct imx290 *imx290,
++ struct v4l2_mbus_framefmt *format)
++{
++ int ret;
++
++ switch (format->code) {
++ case MEDIA_BUS_FMT_SRGGB10_1X10:
++ ret = imx290_set_register_array(imx290, imx290_10bit_settings,
++ ARRAY_SIZE(
++ imx290_10bit_settings));
++ if (ret < 0) {
++ dev_err(imx290->dev, "Could not set format registers\n");
++ return ret;
++ }
++ break;
++ default:
++ dev_err(imx290->dev, "Unknown pixel format\n");
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++/* Start streaming */
++static int imx290_start_streaming(struct imx290 *imx290)
++{
++ int ret;
++
++ /* Set init register settings */
++ ret = imx290_set_register_array(imx290, imx290_global_init_settings,
++ ARRAY_SIZE(
++ imx290_global_init_settings));
++ if (ret < 0) {
++ dev_err(imx290->dev, "Could not set init registers\n");
++ return ret;
++ }
++
++ /* Set current frame format */
++ ret = imx290_write_current_format(imx290, &imx290->current_format);
++ if (ret < 0) {
++ dev_err(imx290->dev, "Could not set frame format\n");
++ return ret;
++ }
++
++ /* Apply default values of current mode */
++ ret = imx290_set_register_array(imx290, imx290->current_mode->data,
++ imx290->current_mode->data_size);
++ if (ret < 0) {
++ dev_err(imx290->dev, "Could not set current mode\n");
++ return ret;
++ }
++
++ /* Apply customized values from user */
++ ret = v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler);
++ if (ret) {
++ dev_err(imx290->dev, "Could not sync v4l2 controls\n");
++ return ret;
++ }
++
++ ret = imx290_write_reg(imx290, IMX290_STANDBY, 0x00);
++ if (ret < 0)
++ return ret;
++
++ msleep(30);
++
++ /* Start streaming */
++ return imx290_write_reg(imx290, IMX290_XMSTA, 0x00);
++}
++
++static int imx290_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct imx290 *imx290 = to_imx290(sd);
++ int ret = 0;
++
++ if (enable) {
++ ret = pm_runtime_get_sync(imx290->dev);
++ if (ret < 0) {
++ pm_runtime_put_noidle(imx290->dev);
++ goto unlock_and_return;
++ }
++
++ ret = imx290_start_streaming(imx290);
++ if (ret) {
++ dev_err(imx290->dev, "Start stream failed\n");
++ pm_runtime_put(imx290->dev);
++ goto unlock_and_return;
++ }
++ } else {
++ imx290_stop_streaming(imx290);
++ pm_runtime_put(imx290->dev);
++ }
++
++unlock_and_return:
++
++ return ret;
++}
++
++static int imx290_get_regulators(struct device *dev, struct imx290 *imx290)
++{
++ unsigned int i;
++
++ for (i = 0; i < IMX290_NUM_SUPPLIES; i++)
++ imx290->supplies[i].supply = imx290_supply_name[i];
++
++ return devm_regulator_bulk_get(dev, IMX290_NUM_SUPPLIES,
++ imx290->supplies);
++}
++
++static int imx290_power_on(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx290 *imx290 = to_imx290(sd);
++ int ret;
++
++ ret = clk_prepare_enable(imx290->xclk);
++ if (ret) {
++ dev_err(imx290->dev, "Failed to enable clock\n");
++ return ret;
++ }
++
++ ret = regulator_bulk_enable(IMX290_NUM_SUPPLIES, imx290->supplies);
++ if (ret) {
++ dev_err(imx290->dev, "Failed to enable regulators\n");
++ clk_disable_unprepare(imx290->xclk);
++ return ret;
++ }
++
++ usleep_range(1, 2);
++ gpiod_set_value_cansleep(imx290->rst_gpio, 1);
++ usleep_range(30000, 31000);
++
++ return 0;
++}
++
++static int imx290_power_off(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx290 *imx290 = to_imx290(sd);
++
++ clk_disable_unprepare(imx290->xclk);
++ gpiod_set_value_cansleep(imx290->rst_gpio, 0);
++ regulator_bulk_disable(IMX290_NUM_SUPPLIES, imx290->supplies);
++
++ return 0;
++}
++
++static const struct dev_pm_ops imx290_pm_ops = {
++ SET_RUNTIME_PM_OPS(imx290_power_on, imx290_power_off, NULL)
++};
++
++static const struct v4l2_subdev_video_ops imx290_video_ops = {
++ .s_stream = imx290_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops imx290_pad_ops = {
++ .init_cfg = imx290_entity_init_cfg,
++ .enum_mbus_code = imx290_enum_mbus_code,
++ .get_fmt = imx290_get_fmt,
++ .set_fmt = imx290_set_fmt,
++};
++
++static const struct v4l2_subdev_ops imx290_subdev_ops = {
++ .video = &imx290_video_ops,
++ .pad = &imx290_pad_ops,
++};
++
++static const struct media_entity_operations imx290_subdev_entity_ops = {
++ .link_validate = v4l2_subdev_link_validate,
++};
++
++static int imx290_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct fwnode_handle *endpoint;
++ struct imx290 *imx290;
++ u32 xclk_freq;
++ int ret;
++
++ imx290 = devm_kzalloc(dev, sizeof(*imx290), GFP_KERNEL);
++ if (!imx290)
++ return -ENOMEM;
++
++ imx290->dev = dev;
++ imx290->regmap = devm_regmap_init_i2c(client, &imx290_regmap_config);
++ if (IS_ERR(imx290->regmap)) {
++ dev_err(dev, "Unable to initialize I2C\n");
++ return -ENODEV;
++ }
++
++ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
++ if (!endpoint) {
++ dev_err(dev, "Endpoint node not found\n");
++ return -EINVAL;
++ }
++
++ ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &imx290->ep);
++ fwnode_handle_put(endpoint);
++ if (ret) {
++ dev_err(dev, "Parsing endpoint node failed\n");
++ goto free_err;
++ }
++
++ if (!imx290->ep.nr_of_link_frequencies) {
++ dev_err(dev, "link-frequency property not found in DT\n");
++ ret = -EINVAL;
++ goto free_err;
++ }
++
++ if (imx290->ep.link_frequencies[0] != IMX290_DEFAULT_LINK_FREQ) {
++ dev_err(dev, "Unsupported link frequency\n");
++ ret = -EINVAL;
++ goto free_err;
++ }
++
++ /* Only CSI2 is supported for now */
++ if (imx290->ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
++ dev_err(dev, "Unsupported bus type, should be CSI2\n");
++ ret = -EINVAL;
++ goto free_err;
++ }
++
++ /* Set default mode to max resolution */
++ imx290->current_mode = &imx290_modes[0];
++
++ /* get system clock (xclk) */
++ imx290->xclk = devm_clk_get(dev, "xclk");
++ if (IS_ERR(imx290->xclk)) {
++ dev_err(dev, "Could not get xclk");
++ ret = PTR_ERR(imx290->xclk);
++ goto free_err;
++ }
++
++ ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
++ &xclk_freq);
++ if (ret) {
++ dev_err(dev, "Could not get xclk frequency\n");
++ goto free_err;
++ }
++
++ /* external clock must be 37.125 MHz */
++ if (xclk_freq != 37125000) {
++ dev_err(dev, "External clock frequency %u is not supported\n",
++ xclk_freq);
++ ret = -EINVAL;
++ goto free_err;
++ }
++
++ ret = clk_set_rate(imx290->xclk, xclk_freq);
++ if (ret) {
++ dev_err(dev, "Could not set xclk frequency\n");
++ goto free_err;
++ }
++
++ ret = imx290_get_regulators(dev, imx290);
++ if (ret < 0) {
++ dev_err(dev, "Cannot get regulators\n");
++ goto free_err;
++ }
++
++ imx290->rst_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);
++ if (IS_ERR(imx290->rst_gpio)) {
++ dev_err(dev, "Cannot get reset gpio\n");
++ ret = PTR_ERR(imx290->rst_gpio);
++ goto free_err;
++ }
++
++ mutex_init(&imx290->lock);
++
++ v4l2_ctrl_handler_init(&imx290->ctrls, 3);
++
++ v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
++ V4L2_CID_GAIN, 0, 72, 1, 0);
++ imx290->link_freq =
++ v4l2_ctrl_new_int_menu(&imx290->ctrls,
++ &imx290_ctrl_ops,
++ V4L2_CID_LINK_FREQ,
++ ARRAY_SIZE(imx290_link_freq) - 1,
++ 0, imx290_link_freq);
++ if (imx290->link_freq)
++ imx290->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++
++ imx290->pixel_rate = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
++ V4L2_CID_PIXEL_RATE, 1,
++ INT_MAX, 1,
++ imx290_modes[0].pixel_rate);
++
++ imx290->sd.ctrl_handler = &imx290->ctrls;
++
++ if (imx290->ctrls.error) {
++ dev_err(dev, "Control initialization error %d\n",
++ imx290->ctrls.error);
++ ret = imx290->ctrls.error;
++ goto free_ctrl;
++ }
++
++ v4l2_i2c_subdev_init(&imx290->sd, client, &imx290_subdev_ops);
++ imx290->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++ imx290->sd.dev = &client->dev;
++ imx290->sd.entity.ops = &imx290_subdev_entity_ops;
++ imx290->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
++
++ imx290->pad.flags = MEDIA_PAD_FL_SOURCE;
++ ret = media_entity_pads_init(&imx290->sd.entity, 1, &imx290->pad);
++ if (ret < 0) {
++ dev_err(dev, "Could not register media entity\n");
++ goto free_ctrl;
++ }
++
++ ret = v4l2_async_register_subdev(&imx290->sd);
++ if (ret < 0) {
++ dev_err(dev, "Could not register v4l2 device\n");
++ goto free_entity;
++ }
++
++ /* Power on the device to match runtime PM state below */
++ ret = imx290_power_on(dev);
++ if (ret < 0) {
++ dev_err(dev, "Could not power on the device\n");
++ goto free_entity;
++ }
++
++ pm_runtime_set_active(dev);
++ pm_runtime_enable(dev);
++ pm_runtime_idle(dev);
++
++ v4l2_fwnode_endpoint_free(&imx290->ep);
++
++ return 0;
++
++free_entity:
++ media_entity_cleanup(&imx290->sd.entity);
++free_ctrl:
++ v4l2_ctrl_handler_free(&imx290->ctrls);
++ mutex_destroy(&imx290->lock);
++free_err:
++ v4l2_fwnode_endpoint_free(&imx290->ep);
++
++ return ret;
++}
++
++static int imx290_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx290 *imx290 = to_imx290(sd);
++
++ v4l2_async_unregister_subdev(sd);
++ media_entity_cleanup(&sd->entity);
++ v4l2_ctrl_handler_free(sd->ctrl_handler);
++
++ mutex_destroy(&imx290->lock);
++
++ pm_runtime_disable(imx290->dev);
++ if (!pm_runtime_status_suspended(imx290->dev))
++ imx290_power_off(imx290->dev);
++ pm_runtime_set_suspended(imx290->dev);
++
++ return 0;
++}
++
++static const struct of_device_id imx290_of_match[] = {
++ { .compatible = "sony,imx290" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, imx290_of_match);
++
++static struct i2c_driver imx290_i2c_driver = {
++ .probe_new = imx290_probe,
++ .remove = imx290_remove,
++ .driver = {
++ .name = "imx290",
++ .pm = &imx290_pm_ops,
++ .of_match_table = of_match_ptr(imx290_of_match),
++ },
++};
++
++module_i2c_driver(imx290_i2c_driver);
++
++MODULE_DESCRIPTION("Sony IMX290 CMOS Image Sensor Driver");
++MODULE_AUTHOR("FRAMOS GmbH");
++MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/bcm27xx/patches-5.4/950-0817-media-i2c-imx290-set-the-format-before-VIDIOC_SUBDEV.patch b/target/linux/bcm27xx/patches-5.4/950-0817-media-i2c-imx290-set-the-format-before-VIDIOC_SUBDEV.patch
new file mode 100644
index 0000000000..68f8fcfd34
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0817-media-i2c-imx290-set-the-format-before-VIDIOC_SUBDEV.patch
@@ -0,0 +1,50 @@
+From 2beb8ff8039f3ee8262f05d7f3d91c44826e5df9 Mon Sep 17 00:00:00 2001
+From: Andrey Konovalov <andrey.konovalov@linaro.org>
+Date: Fri, 12 Jun 2020 15:53:46 +0200
+Subject: [PATCH] media: i2c: imx290: set the format before
+ VIDIOC_SUBDEV_G_FMT is called
+
+Commit d46cfdc86c30d5ec768924f0b1e2683c8d20b671 upstream.
+
+With the current driver 'media-ctl -p' issued right after the imx290 driver
+is loaded prints:
+pad0: Source
+ [fmt:unknown/0x0]
+
+The format value of zero is due to the current_format field of the imx290
+struct not being initialized yet.
+
+As imx290_entity_init_cfg() calls imx290_set_fmt(), the current_mode field
+is also initialized, so the line which set current_mode to a default value
+in driver's probe() function is no longer needed.
+
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+---
+ drivers/media/i2c/imx290.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -722,9 +722,6 @@ static int imx290_probe(struct i2c_clien
+ goto free_err;
+ }
+
+- /* Set default mode to max resolution */
+- imx290->current_mode = &imx290_modes[0];
+-
+ /* get system clock (xclk) */
+ imx290->xclk = devm_clk_get(dev, "xclk");
+ if (IS_ERR(imx290->xclk)) {
+@@ -809,6 +806,9 @@ static int imx290_probe(struct i2c_clien
+ goto free_ctrl;
+ }
+
++ /* Initialize the frame format (this also sets imx290->current_mode) */
++ imx290_entity_init_cfg(&imx290->sd, NULL);
++
+ ret = v4l2_async_register_subdev(&imx290->sd);
+ if (ret < 0) {
+ dev_err(dev, "Could not register v4l2 device\n");
diff --git a/target/linux/bcm27xx/patches-5.4/950-0818-media-i2c-imx290-fix-the-order-of-the-args-in-SET_RU.patch b/target/linux/bcm27xx/patches-5.4/950-0818-media-i2c-imx290-fix-the-order-of-the-args-in-SET_RU.patch
new file mode 100644
index 0000000000..a3332a7eac
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0818-media-i2c-imx290-fix-the-order-of-the-args-in-SET_RU.patch
@@ -0,0 +1,30 @@
+From 8c3334dd193798648c329779ce7a3c6ddec7944e Mon Sep 17 00:00:00 2001
+From: Andrey Konovalov <andrey.konovalov@linaro.org>
+Date: Fri, 12 Jun 2020 15:53:47 +0200
+Subject: [PATCH] media: i2c: imx290: fix the order of the args in
+ SET_RUNTIME_PM_OPS()
+
+Commit 8d2d1bedb1b9af3e0c039a4444858da7b6da71f8 upstream.
+
+The macro is defined as SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn),
+so imx290_power_off must be the 1st arg, and imx290_power_on the 2nd.
+
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+---
+ drivers/media/i2c/imx290.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -648,7 +648,7 @@ static int imx290_power_off(struct devic
+ }
+
+ static const struct dev_pm_ops imx290_pm_ops = {
+- SET_RUNTIME_PM_OPS(imx290_power_on, imx290_power_off, NULL)
++ SET_RUNTIME_PM_OPS(imx290_power_off, imx290_power_on, NULL)
+ };
+
+ static const struct v4l2_subdev_video_ops imx290_video_ops = {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0819-media-i2c-imx290-fix-reset-GPIO-pin-handling.patch b/target/linux/bcm27xx/patches-5.4/950-0819-media-i2c-imx290-fix-reset-GPIO-pin-handling.patch
new file mode 100644
index 0000000000..f4c122de93
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0819-media-i2c-imx290-fix-reset-GPIO-pin-handling.patch
@@ -0,0 +1,61 @@
+From 47f49370b3c1c7f4d4aae855966d2a3beef6c6d4 Mon Sep 17 00:00:00 2001
+From: Andrey Konovalov <andrey.konovalov@linaro.org>
+Date: Fri, 12 Jun 2020 15:53:48 +0200
+Subject: [PATCH] media: i2c: imx290: fix reset GPIO pin handling
+
+Commit 3909a92d7df622b41b9ceeeea694e641cad7667b upstream.
+
+According to https://www.kernel.org/doc/Documentation/gpio/consumer.txt,
+
+- all of the gpiod_set_value_xxx() functions operate with the *logical*
+value. So in imx290_power_on() the reset signal should be cleared
+(de-asserted) with gpiod_set_value_cansleep(imx290->rst_gpio, 0), and in
+imx290_power_off() the value of 1 must be used to apply/assert the reset
+to the sensor. In the device tree the reset pin is described as
+GPIO_ACTIVE_LOW, and gpiod_set_value_xxx() functions take this into
+account,
+
+- when devm_gpiod_get_optional() is called with GPIOD_ASIS, the GPIO is
+not initialized, and the direction must be set later; using a GPIO
+without setting its direction first is illegal and will result in undefined
+behavior. Fix this by using GPIOD_OUT_HIGH instead of GPIOD_ASIS (this
+asserts the reset signal to the sensor initially).
+
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+---
+ drivers/media/i2c/imx290.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -628,7 +628,7 @@ static int imx290_power_on(struct device
+ }
+
+ usleep_range(1, 2);
+- gpiod_set_value_cansleep(imx290->rst_gpio, 1);
++ gpiod_set_value_cansleep(imx290->rst_gpio, 0);
+ usleep_range(30000, 31000);
+
+ return 0;
+@@ -641,7 +641,7 @@ static int imx290_power_off(struct devic
+ struct imx290 *imx290 = to_imx290(sd);
+
+ clk_disable_unprepare(imx290->xclk);
+- gpiod_set_value_cansleep(imx290->rst_gpio, 0);
++ gpiod_set_value_cansleep(imx290->rst_gpio, 1);
+ regulator_bulk_disable(IMX290_NUM_SUPPLIES, imx290->supplies);
+
+ return 0;
+@@ -757,7 +757,8 @@ static int imx290_probe(struct i2c_clien
+ goto free_err;
+ }
+
+- imx290->rst_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);
++ imx290->rst_gpio = devm_gpiod_get_optional(dev, "reset",
++ GPIOD_OUT_HIGH);
+ if (IS_ERR(imx290->rst_gpio)) {
+ dev_err(dev, "Cannot get reset gpio\n");
+ ret = PTR_ERR(imx290->rst_gpio);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0820-media-i2c-imx290-Add-support-for-2-data-lanes.patch b/target/linux/bcm27xx/patches-5.4/950-0820-media-i2c-imx290-Add-support-for-2-data-lanes.patch
new file mode 100644
index 0000000000..68b89999c5
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0820-media-i2c-imx290-Add-support-for-2-data-lanes.patch
@@ -0,0 +1,314 @@
+From 78d867300b5026ab31c9a3fbd37b6590b7940f66 Mon Sep 17 00:00:00 2001
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Date: Fri, 12 Jun 2020 15:53:49 +0200
+Subject: [PATCH] media: i2c: imx290: Add support for 2 data lanes
+
+Commit 97589ad61c730e0f486635c6c19fa25ab8e8f29d upstream.
+
+The IMX290 sensor can output frames with 2/4 CSI2 data lanes. This commit
+adds support for 2 lane mode in addition to the 4 lane and also
+configuring the data lane settings in the driver based on system
+configuration.
+
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+---
+ drivers/media/i2c/imx290.c | 147 +++++++++++++++++++++++++++++++++----
+ 1 file changed, 133 insertions(+), 14 deletions(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -25,7 +25,12 @@
+ #define IMX290_STANDBY 0x3000
+ #define IMX290_REGHOLD 0x3001
+ #define IMX290_XMSTA 0x3002
++#define IMX290_FR_FDG_SEL 0x3009
+ #define IMX290_GAIN 0x3014
++#define IMX290_HMAX_LOW 0x301c
++#define IMX290_HMAX_HIGH 0x301d
++#define IMX290_PHY_LANE_NUM 0x3407
++#define IMX290_CSI_LANE_MODE 0x3443
+
+ #define IMX290_DEFAULT_LINK_FREQ 445500000
+
+@@ -45,6 +50,7 @@ struct imx290_regval {
+ struct imx290_mode {
+ u32 width;
+ u32 height;
++ u32 hmax;
+ u32 pixel_rate;
+ u32 link_freq_index;
+
+@@ -56,6 +62,7 @@ struct imx290 {
+ struct device *dev;
+ struct clk *xclk;
+ struct regmap *regmap;
++ u8 nlanes;
+
+ struct v4l2_subdev sd;
+ struct v4l2_fwnode_endpoint ep;
+@@ -89,14 +96,11 @@ static const struct regmap_config imx290
+
+ static const struct imx290_regval imx290_global_init_settings[] = {
+ { 0x3007, 0x00 },
+- { 0x3009, 0x00 },
+ { 0x3018, 0x65 },
+ { 0x3019, 0x04 },
+ { 0x301a, 0x00 },
+- { 0x3443, 0x03 },
+ { 0x3444, 0x20 },
+ { 0x3445, 0x25 },
+- { 0x3407, 0x03 },
+ { 0x303a, 0x0c },
+ { 0x3040, 0x00 },
+ { 0x3041, 0x00 },
+@@ -169,7 +173,6 @@ static const struct imx290_regval imx290
+ { 0x3164, 0x1a },
+ { 0x3480, 0x49 },
+ /* data rate settings */
+- { 0x3009, 0x01 },
+ { 0x3405, 0x10 },
+ { 0x3446, 0x57 },
+ { 0x3447, 0x00 },
+@@ -187,8 +190,6 @@ static const struct imx290_regval imx290
+ { 0x3453, 0x00 },
+ { 0x3454, 0x17 },
+ { 0x3455, 0x00 },
+- { 0x301c, 0x98 },
+- { 0x301d, 0x08 },
+ };
+
+ static const struct imx290_regval imx290_720p_settings[] = {
+@@ -210,7 +211,6 @@ static const struct imx290_regval imx290
+ { 0x3164, 0x1a },
+ { 0x3480, 0x49 },
+ /* data rate settings */
+- { 0x3009, 0x01 },
+ { 0x3405, 0x10 },
+ { 0x3446, 0x4f },
+ { 0x3447, 0x00 },
+@@ -228,8 +228,6 @@ static const struct imx290_regval imx290
+ { 0x3453, 0x00 },
+ { 0x3454, 0x17 },
+ { 0x3455, 0x00 },
+- { 0x301c, 0xe4 },
+- { 0x301d, 0x0c },
+ };
+
+ static const struct imx290_regval imx290_10bit_settings[] = {
+@@ -250,10 +248,11 @@ static const s64 imx290_link_freq[] = {
+ };
+
+ /* Mode configs */
+-static const struct imx290_mode imx290_modes[] = {
++static const struct imx290_mode imx290_modes_2lanes[] = {
+ {
+ .width = 1920,
+ .height = 1080,
++ .hmax = 0x1130,
+ .data = imx290_1080p_settings,
+ .data_size = ARRAY_SIZE(imx290_1080p_settings),
+ .pixel_rate = 178200000,
+@@ -262,6 +261,7 @@ static const struct imx290_mode imx290_m
+ {
+ .width = 1280,
+ .height = 720,
++ .hmax = 0x19c8,
+ .data = imx290_720p_settings,
+ .data_size = ARRAY_SIZE(imx290_720p_settings),
+ .pixel_rate = 178200000,
+@@ -269,6 +269,44 @@ static const struct imx290_mode imx290_m
+ },
+ };
+
++static const struct imx290_mode imx290_modes_4lanes[] = {
++ {
++ .width = 1920,
++ .height = 1080,
++ .hmax = 0x0898,
++ .data = imx290_1080p_settings,
++ .data_size = ARRAY_SIZE(imx290_1080p_settings),
++ .pixel_rate = 178200000,
++ .link_freq_index = 0,
++ },
++ {
++ .width = 1280,
++ .height = 720,
++ .hmax = 0x0ce4,
++ .data = imx290_720p_settings,
++ .data_size = ARRAY_SIZE(imx290_720p_settings),
++ .pixel_rate = 178200000,
++ .link_freq_index = 0,
++ },
++};
++
++static inline const struct imx290_mode *imx290_modes_ptr(const struct imx290 *imx290)
++{
++ /* We rely on imx290_probe() to ensure that nlanes is either 2 or 4 */
++ if (imx290->nlanes == 2)
++ return imx290_modes_2lanes;
++ else
++ return imx290_modes_4lanes;
++}
++
++static inline int imx290_modes_num(const struct imx290 *imx290)
++{
++ if (imx290->nlanes == 2)
++ return ARRAY_SIZE(imx290_modes_2lanes);
++ else
++ return ARRAY_SIZE(imx290_modes_4lanes);
++}
++
+ static inline struct imx290 *to_imx290(struct v4l2_subdev *_sd)
+ {
+ return container_of(_sd, struct imx290, sd);
+@@ -450,9 +488,8 @@ static int imx290_set_fmt(struct v4l2_su
+
+ mutex_lock(&imx290->lock);
+
+- mode = v4l2_find_nearest_size(imx290_modes,
+- ARRAY_SIZE(imx290_modes),
+- width, height,
++ mode = v4l2_find_nearest_size(imx290_modes_ptr(imx290),
++ imx290_modes_num(imx290), width, height,
+ fmt->format.width, fmt->format.height);
+
+ fmt->format.width = mode->width;
+@@ -522,6 +559,25 @@ static int imx290_write_current_format(s
+ return 0;
+ }
+
++static int imx290_set_hmax(struct imx290 *imx290, u32 val)
++{
++ int ret;
++
++ ret = imx290_write_reg(imx290, IMX290_HMAX_LOW, (val & 0xff));
++ if (ret) {
++ dev_err(imx290->dev, "Error setting HMAX register\n");
++ return ret;
++ }
++
++ ret = imx290_write_reg(imx290, IMX290_HMAX_HIGH, ((val >> 8) & 0xff));
++ if (ret) {
++ dev_err(imx290->dev, "Error setting HMAX register\n");
++ return ret;
++ }
++
++ return 0;
++}
++
+ /* Start streaming */
+ static int imx290_start_streaming(struct imx290 *imx290)
+ {
+@@ -550,6 +606,9 @@ static int imx290_start_streaming(struct
+ dev_err(imx290->dev, "Could not set current mode\n");
+ return ret;
+ }
++ ret = imx290_set_hmax(imx290, imx290->current_mode->hmax);
++ if (ret < 0)
++ return ret;
+
+ /* Apply customized values from user */
+ ret = v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler);
+@@ -607,6 +666,49 @@ static int imx290_get_regulators(struct
+ imx290->supplies);
+ }
+
++static int imx290_set_data_lanes(struct imx290 *imx290)
++{
++ int ret = 0, laneval, frsel;
++
++ switch (imx290->nlanes) {
++ case 2:
++ laneval = 0x01;
++ frsel = 0x02;
++ break;
++ case 4:
++ laneval = 0x03;
++ frsel = 0x01;
++ break;
++ default:
++ /*
++ * We should never hit this since the data lane count is
++ * validated in probe itself
++ */
++ dev_err(imx290->dev, "Lane configuration not supported\n");
++ ret = -EINVAL;
++ goto exit;
++ }
++
++ ret = imx290_write_reg(imx290, IMX290_PHY_LANE_NUM, laneval);
++ if (ret) {
++ dev_err(imx290->dev, "Error setting Physical Lane number register\n");
++ goto exit;
++ }
++
++ ret = imx290_write_reg(imx290, IMX290_CSI_LANE_MODE, laneval);
++ if (ret) {
++ dev_err(imx290->dev, "Error setting CSI Lane mode register\n");
++ goto exit;
++ }
++
++ ret = imx290_write_reg(imx290, IMX290_FR_FDG_SEL, frsel);
++ if (ret)
++ dev_err(imx290->dev, "Error setting FR/FDG SEL register\n");
++
++exit:
++ return ret;
++}
++
+ static int imx290_power_on(struct device *dev)
+ {
+ struct i2c_client *client = to_i2c_client(dev);
+@@ -631,6 +733,9 @@ static int imx290_power_on(struct device
+ gpiod_set_value_cansleep(imx290->rst_gpio, 0);
+ usleep_range(30000, 31000);
+
++ /* Set data lane count */
++ imx290_set_data_lanes(imx290);
++
+ return 0;
+ }
+
+@@ -677,6 +782,7 @@ static int imx290_probe(struct i2c_clien
+ struct fwnode_handle *endpoint;
+ struct imx290 *imx290;
+ u32 xclk_freq;
++ u32 default_pixel_rate;
+ int ret;
+
+ imx290 = devm_kzalloc(dev, sizeof(*imx290), GFP_KERNEL);
+@@ -703,6 +809,16 @@ static int imx290_probe(struct i2c_clien
+ goto free_err;
+ }
+
++ /* Get number of data lanes */
++ imx290->nlanes = imx290->ep.bus.mipi_csi2.num_data_lanes;
++ if (imx290->nlanes != 2 && imx290->nlanes != 4) {
++ dev_err(dev, "Invalid data lanes: %d\n", imx290->nlanes);
++ ret = -EINVAL;
++ goto free_err;
++ }
++
++ dev_dbg(dev, "Using %u data lanes\n", imx290->nlanes);
++
+ if (!imx290->ep.nr_of_link_frequencies) {
+ dev_err(dev, "link-frequency property not found in DT\n");
+ ret = -EINVAL;
+@@ -780,10 +896,13 @@ static int imx290_probe(struct i2c_clien
+ if (imx290->link_freq)
+ imx290->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
++ default_pixel_rate = imx290->nlanes == 2 ?
++ imx290_modes_2lanes[0].pixel_rate :
++ imx290_modes_4lanes[0].pixel_rate;
+ imx290->pixel_rate = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
+ V4L2_CID_PIXEL_RATE, 1,
+ INT_MAX, 1,
+- imx290_modes[0].pixel_rate);
++ default_pixel_rate);
+
+ imx290->sd.ctrl_handler = &imx290->ctrls;
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0821-media-i2c-imx290-Add-configurable-link-frequency-and.patch b/target/linux/bcm27xx/patches-5.4/950-0821-media-i2c-imx290-Add-configurable-link-frequency-and.patch
new file mode 100644
index 0000000000..f74627962e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0821-media-i2c-imx290-Add-configurable-link-frequency-and.patch
@@ -0,0 +1,307 @@
+From e3c6ec43e950d9e08715e2c693771080c7d078a3 Mon Sep 17 00:00:00 2001
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Date: Fri, 12 Jun 2020 15:53:50 +0200
+Subject: [PATCH] media: i2c: imx290: Add configurable link frequency
+ and pixel rate
+
+Commit 98e0500eadb772e1be32d8e369fcc3b7bcac93ed upstream.
+
+IMX290 operates with multiple link frequency and pixel rate combinations.
+The initial driver used a single setting for both but since we now have
+the lane count support in place, let's add configurable link frequency
+and pixel rate.
+
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+---
+ drivers/media/i2c/imx290.c | 148 +++++++++++++++++++++++++++----------
+ 1 file changed, 109 insertions(+), 39 deletions(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -32,8 +32,6 @@
+ #define IMX290_PHY_LANE_NUM 0x3407
+ #define IMX290_CSI_LANE_MODE 0x3443
+
+-#define IMX290_DEFAULT_LINK_FREQ 445500000
+-
+ static const char * const imx290_supply_name[] = {
+ "vdda",
+ "vddd",
+@@ -51,8 +49,7 @@ struct imx290_mode {
+ u32 width;
+ u32 height;
+ u32 hmax;
+- u32 pixel_rate;
+- u32 link_freq_index;
++ u8 link_freq_index;
+
+ const struct imx290_regval *data;
+ u32 data_size;
+@@ -243,9 +240,36 @@ static const struct imx290_regval imx290
+ };
+
+ /* supported link frequencies */
+-static const s64 imx290_link_freq[] = {
+- IMX290_DEFAULT_LINK_FREQ,
+-};
++#define FREQ_INDEX_1080P 0
++#define FREQ_INDEX_720P 1
++static const s64 imx290_link_freq_2lanes[] = {
++ [FREQ_INDEX_1080P] = 445500000,
++ [FREQ_INDEX_720P] = 297000000,
++};
++static const s64 imx290_link_freq_4lanes[] = {
++ [FREQ_INDEX_1080P] = 222750000,
++ [FREQ_INDEX_720P] = 148500000,
++};
++
++/*
++ * In this function and in the similar ones below We rely on imx290_probe()
++ * to ensure that nlanes is either 2 or 4.
++ */
++static inline const s64 *imx290_link_freqs_ptr(const struct imx290 *imx290)
++{
++ if (imx290->nlanes == 2)
++ return imx290_link_freq_2lanes;
++ else
++ return imx290_link_freq_4lanes;
++}
++
++static inline int imx290_link_freqs_num(const struct imx290 *imx290)
++{
++ if (imx290->nlanes == 2)
++ return ARRAY_SIZE(imx290_link_freq_2lanes);
++ else
++ return ARRAY_SIZE(imx290_link_freq_4lanes);
++}
+
+ /* Mode configs */
+ static const struct imx290_mode imx290_modes_2lanes[] = {
+@@ -253,19 +277,17 @@ static const struct imx290_mode imx290_m
+ .width = 1920,
+ .height = 1080,
+ .hmax = 0x1130,
++ .link_freq_index = FREQ_INDEX_1080P,
+ .data = imx290_1080p_settings,
+ .data_size = ARRAY_SIZE(imx290_1080p_settings),
+- .pixel_rate = 178200000,
+- .link_freq_index = 0,
+ },
+ {
+ .width = 1280,
+ .height = 720,
+ .hmax = 0x19c8,
++ .link_freq_index = FREQ_INDEX_720P,
+ .data = imx290_720p_settings,
+ .data_size = ARRAY_SIZE(imx290_720p_settings),
+- .pixel_rate = 178200000,
+- .link_freq_index = 0,
+ },
+ };
+
+@@ -274,25 +296,22 @@ static const struct imx290_mode imx290_m
+ .width = 1920,
+ .height = 1080,
+ .hmax = 0x0898,
++ .link_freq_index = FREQ_INDEX_1080P,
+ .data = imx290_1080p_settings,
+ .data_size = ARRAY_SIZE(imx290_1080p_settings),
+- .pixel_rate = 178200000,
+- .link_freq_index = 0,
+ },
+ {
+ .width = 1280,
+ .height = 720,
+ .hmax = 0x0ce4,
++ .link_freq_index = FREQ_INDEX_720P,
+ .data = imx290_720p_settings,
+ .data_size = ARRAY_SIZE(imx290_720p_settings),
+- .pixel_rate = 178200000,
+- .link_freq_index = 0,
+ },
+ };
+
+ static inline const struct imx290_mode *imx290_modes_ptr(const struct imx290 *imx290)
+ {
+- /* We rely on imx290_probe() to ensure that nlanes is either 2 or 4 */
+ if (imx290->nlanes == 2)
+ return imx290_modes_2lanes;
+ else
+@@ -477,6 +496,30 @@ static int imx290_get_fmt(struct v4l2_su
+ return 0;
+ }
+
++static inline u8 imx290_get_link_freq_index(struct imx290 *imx290)
++{
++ return imx290->current_mode->link_freq_index;
++}
++
++static s64 imx290_get_link_freq(struct imx290 *imx290)
++{
++ u8 index = imx290_get_link_freq_index(imx290);
++
++ return *(imx290_link_freqs_ptr(imx290) + index);
++}
++
++static u64 imx290_calc_pixel_rate(struct imx290 *imx290)
++{
++ s64 link_freq = imx290_get_link_freq(imx290);
++ u8 nlanes = imx290->nlanes;
++ u64 pixel_rate;
++
++ /* pixel rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
++ pixel_rate = link_freq * 2 * nlanes;
++ do_div(pixel_rate, 10);
++ return pixel_rate;
++}
++
+ static int imx290_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+@@ -509,10 +552,14 @@ static int imx290_set_fmt(struct v4l2_su
+ format = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+ } else {
+ format = &imx290->current_format;
+- __v4l2_ctrl_s_ctrl(imx290->link_freq, mode->link_freq_index);
+- __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate, mode->pixel_rate);
+-
+ imx290->current_mode = mode;
++
++ if (imx290->link_freq)
++ __v4l2_ctrl_s_ctrl(imx290->link_freq,
++ imx290_get_link_freq_index(imx290));
++ if (imx290->pixel_rate)
++ __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate,
++ imx290_calc_pixel_rate(imx290));
+ }
+
+ *format = fmt->format;
+@@ -536,12 +583,11 @@ static int imx290_entity_init_cfg(struct
+ return 0;
+ }
+
+-static int imx290_write_current_format(struct imx290 *imx290,
+- struct v4l2_mbus_framefmt *format)
++static int imx290_write_current_format(struct imx290 *imx290)
+ {
+ int ret;
+
+- switch (format->code) {
++ switch (imx290->current_format.code) {
+ case MEDIA_BUS_FMT_SRGGB10_1X10:
+ ret = imx290_set_register_array(imx290, imx290_10bit_settings,
+ ARRAY_SIZE(
+@@ -592,8 +638,8 @@ static int imx290_start_streaming(struct
+ return ret;
+ }
+
+- /* Set current frame format */
+- ret = imx290_write_current_format(imx290, &imx290->current_format);
++ /* Apply the register values related to current frame format */
++ ret = imx290_write_current_format(imx290);
+ if (ret < 0) {
+ dev_err(imx290->dev, "Could not set frame format\n");
+ return ret;
+@@ -776,13 +822,34 @@ static const struct media_entity_operati
+ .link_validate = v4l2_subdev_link_validate,
+ };
+
++/*
++ * Returns 0 if all link frequencies used by the driver for the given number
++ * of MIPI data lanes are mentioned in the device tree, or the value of the
++ * first missing frequency otherwise.
++ */
++static s64 imx290_check_link_freqs(const struct imx290 *imx290)
++{
++ int i, j;
++ const s64 *freqs = imx290_link_freqs_ptr(imx290);
++ int freqs_count = imx290_link_freqs_num(imx290);
++
++ for (i = 0; i < freqs_count; i++) {
++ for (j = 0; j < imx290->ep.nr_of_link_frequencies; j++)
++ if (freqs[i] == imx290->ep.link_frequencies[j])
++ break;
++ if (j == imx290->ep.nr_of_link_frequencies)
++ return freqs[i];
++ }
++ return 0;
++}
++
+ static int imx290_probe(struct i2c_client *client)
+ {
+ struct device *dev = &client->dev;
+ struct fwnode_handle *endpoint;
+ struct imx290 *imx290;
+ u32 xclk_freq;
+- u32 default_pixel_rate;
++ s64 fq;
+ int ret;
+
+ imx290 = devm_kzalloc(dev, sizeof(*imx290), GFP_KERNEL);
+@@ -825,8 +892,10 @@ static int imx290_probe(struct i2c_clien
+ goto free_err;
+ }
+
+- if (imx290->ep.link_frequencies[0] != IMX290_DEFAULT_LINK_FREQ) {
+- dev_err(dev, "Unsupported link frequency\n");
++ /* Check that link frequences for all the modes are in device tree */
++ fq = imx290_check_link_freqs(imx290);
++ if (fq) {
++ dev_err(dev, "Link frequency of %lld is not supported\n", fq);
+ ret = -EINVAL;
+ goto free_err;
+ }
+@@ -883,26 +952,30 @@ static int imx290_probe(struct i2c_clien
+
+ mutex_init(&imx290->lock);
+
++ /*
++ * Initialize the frame format. In particular, imx290->current_mode
++ * and imx290->bpp are set to defaults: imx290_calc_pixel_rate() call
++ * below relies on these fields.
++ */
++ imx290_entity_init_cfg(&imx290->sd, NULL);
++
+ v4l2_ctrl_handler_init(&imx290->ctrls, 3);
+
+ v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
+ V4L2_CID_GAIN, 0, 72, 1, 0);
++
+ imx290->link_freq =
+- v4l2_ctrl_new_int_menu(&imx290->ctrls,
+- &imx290_ctrl_ops,
++ v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops,
+ V4L2_CID_LINK_FREQ,
+- ARRAY_SIZE(imx290_link_freq) - 1,
+- 0, imx290_link_freq);
++ imx290_link_freqs_num(imx290) - 1, 0,
++ imx290_link_freqs_ptr(imx290));
+ if (imx290->link_freq)
+ imx290->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+- default_pixel_rate = imx290->nlanes == 2 ?
+- imx290_modes_2lanes[0].pixel_rate :
+- imx290_modes_4lanes[0].pixel_rate;
+ imx290->pixel_rate = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
+- V4L2_CID_PIXEL_RATE, 1,
+- INT_MAX, 1,
+- default_pixel_rate);
++ V4L2_CID_PIXEL_RATE,
++ 1, INT_MAX, 1,
++ imx290_calc_pixel_rate(imx290));
+
+ imx290->sd.ctrl_handler = &imx290->ctrls;
+
+@@ -926,9 +999,6 @@ static int imx290_probe(struct i2c_clien
+ goto free_ctrl;
+ }
+
+- /* Initialize the frame format (this also sets imx290->current_mode) */
+- imx290_entity_init_cfg(&imx290->sd, NULL);
+-
+ ret = v4l2_async_register_subdev(&imx290->sd);
+ if (ret < 0) {
+ dev_err(dev, "Could not register v4l2 device\n");
diff --git a/target/linux/bcm27xx/patches-5.4/950-0822-media-i2c-imx290-Add-support-for-test-pattern-genera.patch b/target/linux/bcm27xx/patches-5.4/950-0822-media-i2c-imx290-Add-support-for-test-pattern-genera.patch
new file mode 100644
index 0000000000..e7900ab800
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0822-media-i2c-imx290-Add-support-for-test-pattern-genera.patch
@@ -0,0 +1,110 @@
+From f1a8ae8064a65846489386fe95790900fb150242 Mon Sep 17 00:00:00 2001
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Date: Fri, 12 Jun 2020 15:53:51 +0200
+Subject: [PATCH] media: i2c: imx290: Add support for test pattern
+ generation
+
+Commit a58df1f9e4885eaf3d0663574a217e513821a9f0 upstream.
+
+Add support for generating following test patterns by IMX290:
+
+* Sequence Pattern 1
+* Horizontal Color-bar Chart
+* Vertical Color-bar Chart
+* Sequence Pattern 2
+* Gradation Pattern 1
+* Gradation Pattern 2
+* 000/555h Toggle Pattern
+
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+---
+ drivers/media/i2c/imx290.c | 41 +++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 40 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -26,12 +26,19 @@
+ #define IMX290_REGHOLD 0x3001
+ #define IMX290_XMSTA 0x3002
+ #define IMX290_FR_FDG_SEL 0x3009
++#define IMX290_BLKLEVEL_LOW 0x300a
++#define IMX290_BLKLEVEL_HIGH 0x300b
+ #define IMX290_GAIN 0x3014
+ #define IMX290_HMAX_LOW 0x301c
+ #define IMX290_HMAX_HIGH 0x301d
++#define IMX290_PGCTRL 0x308c
+ #define IMX290_PHY_LANE_NUM 0x3407
+ #define IMX290_CSI_LANE_MODE 0x3443
+
++#define IMX290_PGCTRL_REGEN BIT(0)
++#define IMX290_PGCTRL_THRU BIT(1)
++#define IMX290_PGCTRL_MODE(n) ((n) << 4)
++
+ static const char * const imx290_supply_name[] = {
+ "vdda",
+ "vddd",
+@@ -91,6 +98,17 @@ static const struct regmap_config imx290
+ .cache_type = REGCACHE_RBTREE,
+ };
+
++static const char * const imx290_test_pattern_menu[] = {
++ "Disabled",
++ "Sequence Pattern 1",
++ "Horizontal Color-bar Chart",
++ "Vertical Color-bar Chart",
++ "Sequence Pattern 2",
++ "Gradation Pattern 1",
++ "Gradation Pattern 2",
++ "000/555h Toggle Pattern",
++};
++
+ static const struct imx290_regval imx290_global_init_settings[] = {
+ { 0x3007, 0x00 },
+ { 0x3018, 0x65 },
+@@ -448,6 +466,22 @@ static int imx290_set_ctrl(struct v4l2_c
+ case V4L2_CID_GAIN:
+ ret = imx290_set_gain(imx290, ctrl->val);
+ break;
++ case V4L2_CID_TEST_PATTERN:
++ if (ctrl->val) {
++ imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00);
++ imx290_write_reg(imx290, IMX290_BLKLEVEL_HIGH, 0x00);
++ msleep(10);
++ imx290_write_reg(imx290, IMX290_PGCTRL,
++ (u8)(IMX290_PGCTRL_REGEN |
++ IMX290_PGCTRL_THRU |
++ IMX290_PGCTRL_MODE(ctrl->val)));
++ } else {
++ imx290_write_reg(imx290, IMX290_PGCTRL, 0x00);
++ msleep(10);
++ imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x3c);
++ imx290_write_reg(imx290, IMX290_BLKLEVEL_HIGH, 0x00);
++ }
++ break;
+ default:
+ ret = -EINVAL;
+ break;
+@@ -959,7 +993,7 @@ static int imx290_probe(struct i2c_clien
+ */
+ imx290_entity_init_cfg(&imx290->sd, NULL);
+
+- v4l2_ctrl_handler_init(&imx290->ctrls, 3);
++ v4l2_ctrl_handler_init(&imx290->ctrls, 4);
+
+ v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
+ V4L2_CID_GAIN, 0, 72, 1, 0);
+@@ -977,6 +1011,11 @@ static int imx290_probe(struct i2c_clien
+ 1, INT_MAX, 1,
+ imx290_calc_pixel_rate(imx290));
+
++ v4l2_ctrl_new_std_menu_items(&imx290->ctrls, &imx290_ctrl_ops,
++ V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(imx290_test_pattern_menu) - 1,
++ 0, 0, imx290_test_pattern_menu);
++
+ imx290->sd.ctrl_handler = &imx290->ctrls;
+
+ if (imx290->ctrls.error) {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0823-media-i2c-imx290-Add-RAW12-mode-support.patch b/target/linux/bcm27xx/patches-5.4/950-0823-media-i2c-imx290-Add-RAW12-mode-support.patch
new file mode 100644
index 0000000000..6e437350c8
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0823-media-i2c-imx290-Add-RAW12-mode-support.patch
@@ -0,0 +1,109 @@
+From 9f6a310ab3b466940c0a15260987d4cfe868a79a Mon Sep 17 00:00:00 2001
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Date: Fri, 12 Jun 2020 15:53:52 +0200
+Subject: [PATCH] media: i2c: imx290: Add RAW12 mode support
+
+Commit c566ac01ceaa02450acc155201772c0623530e76 upstream.
+
+IMX290 is capable of outputting frames in both Raw Bayer (packed) 10 and
+12 bit formats. Since the driver already supports RAW10 mode, let's add
+the missing RAW12 mode as well.
+
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+---
+ drivers/media/i2c/imx290.c | 36 +++++++++++++++++++++++++++++++++---
+ 1 file changed, 33 insertions(+), 3 deletions(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -67,6 +67,7 @@ struct imx290 {
+ struct clk *xclk;
+ struct regmap *regmap;
+ u8 nlanes;
++ u8 bpp;
+
+ struct v4l2_subdev sd;
+ struct v4l2_fwnode_endpoint ep;
+@@ -86,10 +87,12 @@ struct imx290 {
+
+ struct imx290_pixfmt {
+ u32 code;
++ u8 bpp;
+ };
+
+ static const struct imx290_pixfmt imx290_formats[] = {
+- { MEDIA_BUS_FMT_SRGGB10_1X10 },
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
++ { MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
+ };
+
+ static const struct regmap_config imx290_regmap_config = {
+@@ -257,6 +260,18 @@ static const struct imx290_regval imx290
+ { 0x300b, 0x00},
+ };
+
++static const struct imx290_regval imx290_12bit_settings[] = {
++ { 0x3005, 0x01 },
++ { 0x3046, 0x01 },
++ { 0x3129, 0x00 },
++ { 0x317c, 0x00 },
++ { 0x31ec, 0x0e },
++ { 0x3441, 0x0c },
++ { 0x3442, 0x0c },
++ { 0x300a, 0xf0 },
++ { 0x300b, 0x00 },
++};
++
+ /* supported link frequencies */
+ #define FREQ_INDEX_1080P 0
+ #define FREQ_INDEX_720P 1
+@@ -478,7 +493,12 @@ static int imx290_set_ctrl(struct v4l2_c
+ } else {
+ imx290_write_reg(imx290, IMX290_PGCTRL, 0x00);
+ msleep(10);
+- imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x3c);
++ if (imx290->bpp == 10)
++ imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW,
++ 0x3c);
++ else /* 12 bits per pixel */
++ imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW,
++ 0xf0);
+ imx290_write_reg(imx290, IMX290_BLKLEVEL_HIGH, 0x00);
+ }
+ break;
+@@ -550,7 +570,7 @@ static u64 imx290_calc_pixel_rate(struct
+
+ /* pixel rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
+ pixel_rate = link_freq * 2 * nlanes;
+- do_div(pixel_rate, 10);
++ do_div(pixel_rate, imx290->bpp);
+ return pixel_rate;
+ }
+
+@@ -587,6 +607,7 @@ static int imx290_set_fmt(struct v4l2_su
+ } else {
+ format = &imx290->current_format;
+ imx290->current_mode = mode;
++ imx290->bpp = imx290_formats[i].bpp;
+
+ if (imx290->link_freq)
+ __v4l2_ctrl_s_ctrl(imx290->link_freq,
+@@ -629,6 +650,15 @@ static int imx290_write_current_format(s
+ if (ret < 0) {
+ dev_err(imx290->dev, "Could not set format registers\n");
+ return ret;
++ }
++ break;
++ case MEDIA_BUS_FMT_SRGGB12_1X12:
++ ret = imx290_set_register_array(imx290, imx290_12bit_settings,
++ ARRAY_SIZE(
++ imx290_12bit_settings));
++ if (ret < 0) {
++ dev_err(imx290->dev, "Could not set format registers\n");
++ return ret;
+ }
+ break;
+ default:
diff --git a/target/linux/bcm27xx/patches-5.4/950-0824-media-i2c-imx290-Add-support-to-enumerate-all-frame-.patch b/target/linux/bcm27xx/patches-5.4/950-0824-media-i2c-imx290-Add-support-to-enumerate-all-frame-.patch
new file mode 100644
index 0000000000..8ae528a423
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0824-media-i2c-imx290-Add-support-to-enumerate-all-frame-.patch
@@ -0,0 +1,58 @@
+From 9ca04663315302f1556798e9da29eabf08aecd59 Mon Sep 17 00:00:00 2001
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Date: Fri, 12 Jun 2020 15:53:53 +0200
+Subject: [PATCH] media: i2c: imx290: Add support to enumerate all
+ frame sizes
+
+Commit 3b867fb641d884b714fba390ae866714ba475f29 upstream.
+
+Add support to enumerate all frame sizes supported by IMX290. This is
+required for using with userspace tools such as libcamera.
+
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+---
+ drivers/media/i2c/imx290.c | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -528,6 +528,28 @@ static int imx290_enum_mbus_code(struct
+ return 0;
+ }
+
++static int imx290_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ const struct imx290 *imx290 = to_imx290(sd);
++ const struct imx290_mode *imx290_modes = imx290_modes_ptr(imx290);
++
++ if ((fse->code != imx290_formats[0].code) &&
++ (fse->code != imx290_formats[1].code))
++ return -EINVAL;
++
++ if (fse->index >= imx290_modes_num(imx290))
++ return -EINVAL;
++
++ fse->min_width = imx290_modes[fse->index].width;
++ fse->max_width = imx290_modes[fse->index].width;
++ fse->min_height = imx290_modes[fse->index].height;
++ fse->max_height = imx290_modes[fse->index].height;
++
++ return 0;
++}
++
+ static int imx290_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+@@ -873,6 +895,7 @@ static const struct v4l2_subdev_video_op
+ static const struct v4l2_subdev_pad_ops imx290_pad_ops = {
+ .init_cfg = imx290_entity_init_cfg,
+ .enum_mbus_code = imx290_enum_mbus_code,
++ .enum_frame_size = imx290_enum_frame_size,
+ .get_fmt = imx290_get_fmt,
+ .set_fmt = imx290_set_fmt,
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0825-media-i2c-imx290-Move-the-settle-time-delay-out-of-l.patch b/target/linux/bcm27xx/patches-5.4/950-0825-media-i2c-imx290-Move-the-settle-time-delay-out-of-l.patch
new file mode 100644
index 0000000000..a46c0c98ea
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0825-media-i2c-imx290-Move-the-settle-time-delay-out-of-l.patch
@@ -0,0 +1,37 @@
+From d2155366275ce70438d12169a59959e90b637f9c Mon Sep 17 00:00:00 2001
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Date: Fri, 12 Jun 2020 15:53:54 +0200
+Subject: [PATCH] media: i2c: imx290: Move the settle time delay out
+ of loop
+
+Commit 6544af9b04b4484867c234ba0be1b5008e4a14ee upstream.
+
+The 10ms settle time is needed only at the end of all consecutive
+register writes. So move the delay to outside of the for loop of
+imx290_set_register_array().
+
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+---
+ drivers/media/i2c/imx290.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -404,11 +404,11 @@ static int imx290_set_register_array(str
+ ret = imx290_write_reg(imx290, settings->reg, settings->val);
+ if (ret < 0)
+ return ret;
+-
+- /* Settle time is 10ms for all registers */
+- msleep(10);
+ }
+
++ /* Provide 10ms settle time */
++ msleep(10);
++
+ return 0;
+ }
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0826-media-i2c-imx290-set-bus_type-before-calling-v4l2_fw.patch b/target/linux/bcm27xx/patches-5.4/950-0826-media-i2c-imx290-set-bus_type-before-calling-v4l2_fw.patch
new file mode 100644
index 0000000000..5180ee60e7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0826-media-i2c-imx290-set-bus_type-before-calling-v4l2_fw.patch
@@ -0,0 +1,137 @@
+From e5b34fd95be9c59fe55e4755ba84aa05efaaaf62 Mon Sep 17 00:00:00 2001
+From: Andrey Konovalov <andrey.konovalov@linaro.org>
+Date: Fri, 12 Jun 2020 15:53:55 +0200
+Subject: [PATCH] media: i2c: imx290: set bus_type before calling
+ v4l2_fwnode_endpoint_alloc_parse()
+
+Commit a270675875829b6d46eb9e38960fd6019555ebb8 upstream.
+
+The bus_type field of v4l2_fwnode_endpoint structure passed as the argument
+to v4l2_fwnode_endpoint_alloc_parse() function must be initiaized.
+Set it to V4L2_MBUS_CSI2_DPHY, and check for -ENXIO which is returned
+when the requested media bus type doesn't match the fwnode.
+
+Also remove v4l2_fwnode_endpoint field from struct imx290 as it is only
+needed in the probe function: use the local variable for this purpose.
+
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+---
+ drivers/media/i2c/imx290.c | 38 +++++++++++++++++++-------------------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -70,7 +70,6 @@ struct imx290 {
+ u8 bpp;
+
+ struct v4l2_subdev sd;
+- struct v4l2_fwnode_endpoint ep;
+ struct media_pad pad;
+ struct v4l2_mbus_framefmt current_format;
+ const struct imx290_mode *current_mode;
+@@ -914,17 +913,18 @@ static const struct media_entity_operati
+ * of MIPI data lanes are mentioned in the device tree, or the value of the
+ * first missing frequency otherwise.
+ */
+-static s64 imx290_check_link_freqs(const struct imx290 *imx290)
++static s64 imx290_check_link_freqs(const struct imx290 *imx290,
++ const struct v4l2_fwnode_endpoint *ep)
+ {
+ int i, j;
+ const s64 *freqs = imx290_link_freqs_ptr(imx290);
+ int freqs_count = imx290_link_freqs_num(imx290);
+
+ for (i = 0; i < freqs_count; i++) {
+- for (j = 0; j < imx290->ep.nr_of_link_frequencies; j++)
+- if (freqs[i] == imx290->ep.link_frequencies[j])
++ for (j = 0; j < ep->nr_of_link_frequencies; j++)
++ if (freqs[i] == ep->link_frequencies[j])
+ break;
+- if (j == imx290->ep.nr_of_link_frequencies)
++ if (j == ep->nr_of_link_frequencies)
+ return freqs[i];
+ }
+ return 0;
+@@ -934,6 +934,10 @@ static int imx290_probe(struct i2c_clien
+ {
+ struct device *dev = &client->dev;
+ struct fwnode_handle *endpoint;
++ /* Only CSI2 is supported for now: */
++ struct v4l2_fwnode_endpoint ep = {
++ .bus_type = V4L2_MBUS_CSI2_DPHY
++ };
+ struct imx290 *imx290;
+ u32 xclk_freq;
+ s64 fq;
+@@ -956,15 +960,18 @@ static int imx290_probe(struct i2c_clien
+ return -EINVAL;
+ }
+
+- ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &imx290->ep);
++ ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep);
+ fwnode_handle_put(endpoint);
+- if (ret) {
++ if (ret == -ENXIO) {
++ dev_err(dev, "Unsupported bus type, should be CSI2\n");
++ goto free_err;
++ } else if (ret) {
+ dev_err(dev, "Parsing endpoint node failed\n");
+ goto free_err;
+ }
+
+ /* Get number of data lanes */
+- imx290->nlanes = imx290->ep.bus.mipi_csi2.num_data_lanes;
++ imx290->nlanes = ep.bus.mipi_csi2.num_data_lanes;
+ if (imx290->nlanes != 2 && imx290->nlanes != 4) {
+ dev_err(dev, "Invalid data lanes: %d\n", imx290->nlanes);
+ ret = -EINVAL;
+@@ -973,27 +980,20 @@ static int imx290_probe(struct i2c_clien
+
+ dev_dbg(dev, "Using %u data lanes\n", imx290->nlanes);
+
+- if (!imx290->ep.nr_of_link_frequencies) {
++ if (!ep.nr_of_link_frequencies) {
+ dev_err(dev, "link-frequency property not found in DT\n");
+ ret = -EINVAL;
+ goto free_err;
+ }
+
+ /* Check that link frequences for all the modes are in device tree */
+- fq = imx290_check_link_freqs(imx290);
++ fq = imx290_check_link_freqs(imx290, &ep);
+ if (fq) {
+ dev_err(dev, "Link frequency of %lld is not supported\n", fq);
+ ret = -EINVAL;
+ goto free_err;
+ }
+
+- /* Only CSI2 is supported for now */
+- if (imx290->ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
+- dev_err(dev, "Unsupported bus type, should be CSI2\n");
+- ret = -EINVAL;
+- goto free_err;
+- }
+-
+ /* get system clock (xclk) */
+ imx290->xclk = devm_clk_get(dev, "xclk");
+ if (IS_ERR(imx290->xclk)) {
+@@ -1108,7 +1108,7 @@ static int imx290_probe(struct i2c_clien
+ pm_runtime_enable(dev);
+ pm_runtime_idle(dev);
+
+- v4l2_fwnode_endpoint_free(&imx290->ep);
++ v4l2_fwnode_endpoint_free(&ep);
+
+ return 0;
+
+@@ -1118,7 +1118,7 @@ free_ctrl:
+ v4l2_ctrl_handler_free(&imx290->ctrls);
+ mutex_destroy(&imx290->lock);
+ free_err:
+- v4l2_fwnode_endpoint_free(&imx290->ep);
++ v4l2_fwnode_endpoint_free(&ep);
+
+ return ret;
+ }
diff --git a/target/linux/bcm27xx/patches-5.4/950-0827-media-i2c-imx290-Add-support-for-74.25MHz-clock.patch b/target/linux/bcm27xx/patches-5.4/950-0827-media-i2c-imx290-Add-support-for-74.25MHz-clock.patch
new file mode 100644
index 0000000000..87661b7177
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0827-media-i2c-imx290-Add-support-for-74.25MHz-clock.patch
@@ -0,0 +1,264 @@
+From c175c735869b0dfa8c21fc57d5bd02ca370f9117 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 25 Jun 2020 08:28:51 +0100
+Subject: [PATCH] media: i2c: imx290: Add support for 74.25MHz clock
+
+The existing driver only supported a clock of 37.125MHz, but the
+sensor also supports 74.25MHz.
+
+Add the relevant register modifications to support this alternate
+clock frequency.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/imx290.c | 119 ++++++++++++++++++++++++++++++-------
+ 1 file changed, 97 insertions(+), 22 deletions(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -1,6 +1,10 @@
+ // SPDX-License-Identifier: GPL-2.0
+ /*
+- * Sony IMX290 CMOS Image Sensor Driver
++ * Sony IMX290/327 CMOS Image Sensor Driver
++ *
++ * The IMX290 and IMX327 are very similar 1920x1080 1/2.8 CMOS image sensors.
++ * IMX327 can support up to 60fps, whilst IMX290 support up to 120fps (only
++ * 10bit and when connected over 4 CSI-2 lanes).
+ *
+ * Copyright (C) 2019 FRAMOS GmbH.
+ *
+@@ -22,6 +26,11 @@
+ #include <media/v4l2-fwnode.h>
+ #include <media/v4l2-subdev.h>
+
++enum imx290_clk_index {
++ CLK_37_125,
++ CLK_74_25,
++};
++
+ #define IMX290_STANDBY 0x3000
+ #define IMX290_REGHOLD 0x3001
+ #define IMX290_XMSTA 0x3002
+@@ -60,11 +69,16 @@ struct imx290_mode {
+
+ const struct imx290_regval *data;
+ u32 data_size;
++
++ /* Clock setup can vary. Index as enum imx290_clk_index */
++ const struct imx290_regval *clk_data[2];
++ u32 clk_size;
+ };
+
+ struct imx290 {
+ struct device *dev;
+ struct clk *xclk;
++ u32 xclk_freq;
+ struct regmap *regmap;
+ u8 nlanes;
+ u8 bpp;
+@@ -116,8 +130,6 @@ static const struct imx290_regval imx290
+ { 0x3018, 0x65 },
+ { 0x3019, 0x04 },
+ { 0x301a, 0x00 },
+- { 0x3444, 0x20 },
+- { 0x3445, 0x25 },
+ { 0x303a, 0x0c },
+ { 0x3040, 0x00 },
+ { 0x3041, 0x00 },
+@@ -171,6 +183,30 @@ static const struct imx290_regval imx290
+ { 0x33b3, 0x04 },
+ };
+
++static const struct imx290_regval imx290_37_125mhz_clock_1080p[] = {
++ { 0x305c, 0x18 },
++ { 0x305d, 0x03 },
++ { 0x305e, 0x20 },
++ { 0x305f, 0x01 },
++ { 0x315e, 0x1a },
++ { 0x3164, 0x1a },
++ { 0x3444, 0x20 },
++ { 0x3445, 0x25 },
++ { 0x3480, 0x49 },
++};
++
++static const struct imx290_regval imx290_74_250mhz_clock_1080p[] = {
++ { 0x305c, 0x0c },
++ { 0x305d, 0x03 },
++ { 0x305e, 0x10 },
++ { 0x305f, 0x01 },
++ { 0x315e, 0x1b },
++ { 0x3164, 0x1b },
++ { 0x3444, 0x40 },
++ { 0x3445, 0x4a },
++ { 0x3480, 0x92 },
++};
++
+ static const struct imx290_regval imx290_1080p_settings[] = {
+ /* mode settings */
+ { 0x3007, 0x00 },
+@@ -182,13 +218,6 @@ static const struct imx290_regval imx290
+ { 0x3419, 0x04 },
+ { 0x3012, 0x64 },
+ { 0x3013, 0x00 },
+- { 0x305c, 0x18 },
+- { 0x305d, 0x03 },
+- { 0x305e, 0x20 },
+- { 0x305f, 0x01 },
+- { 0x315e, 0x1a },
+- { 0x3164, 0x1a },
+- { 0x3480, 0x49 },
+ /* data rate settings */
+ { 0x3405, 0x10 },
+ { 0x3446, 0x57 },
+@@ -209,6 +238,30 @@ static const struct imx290_regval imx290
+ { 0x3455, 0x00 },
+ };
+
++static const struct imx290_regval imx290_37_125mhz_clock_720p[] = {
++ { 0x305c, 0x20 },
++ { 0x305d, 0x00 },
++ { 0x305e, 0x20 },
++ { 0x305f, 0x01 },
++ { 0x315e, 0x1a },
++ { 0x3164, 0x1a },
++ { 0x3444, 0x20 },
++ { 0x3445, 0x25 },
++ { 0x3480, 0x49 },
++};
++
++static const struct imx290_regval imx290_74_250mhz_clock_720p[] = {
++ { 0x305c, 0x10 },
++ { 0x305d, 0x00 },
++ { 0x305e, 0x10 },
++ { 0x305f, 0x01 },
++ { 0x315e, 0x1b },
++ { 0x3164, 0x1b },
++ { 0x3444, 0x40 },
++ { 0x3445, 0x4a },
++ { 0x3480, 0x92 },
++};
++
+ static const struct imx290_regval imx290_720p_settings[] = {
+ /* mode settings */
+ { 0x3007, 0x10 },
+@@ -220,13 +273,6 @@ static const struct imx290_regval imx290
+ { 0x3419, 0x02 },
+ { 0x3012, 0x64 },
+ { 0x3013, 0x00 },
+- { 0x305c, 0x20 },
+- { 0x305d, 0x00 },
+- { 0x305e, 0x20 },
+- { 0x305f, 0x01 },
+- { 0x315e, 0x1a },
+- { 0x3164, 0x1a },
+- { 0x3480, 0x49 },
+ /* data rate settings */
+ { 0x3405, 0x10 },
+ { 0x3446, 0x4f },
+@@ -312,6 +358,11 @@ static const struct imx290_mode imx290_m
+ .link_freq_index = FREQ_INDEX_1080P,
+ .data = imx290_1080p_settings,
+ .data_size = ARRAY_SIZE(imx290_1080p_settings),
++ .clk_data = {
++ [CLK_37_125] = imx290_37_125mhz_clock_1080p,
++ [CLK_74_25] = imx290_74_250mhz_clock_1080p,
++ },
++ .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_1080p),
+ },
+ {
+ .width = 1280,
+@@ -320,6 +371,11 @@ static const struct imx290_mode imx290_m
+ .link_freq_index = FREQ_INDEX_720P,
+ .data = imx290_720p_settings,
+ .data_size = ARRAY_SIZE(imx290_720p_settings),
++ .clk_data = {
++ [CLK_37_125] = imx290_37_125mhz_clock_1080p,
++ [CLK_74_25] = imx290_74_250mhz_clock_1080p,
++ },
++ .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_1080p),
+ },
+ };
+
+@@ -331,6 +387,11 @@ static const struct imx290_mode imx290_m
+ .link_freq_index = FREQ_INDEX_1080P,
+ .data = imx290_1080p_settings,
+ .data_size = ARRAY_SIZE(imx290_1080p_settings),
++ .clk_data = {
++ [CLK_37_125] = imx290_37_125mhz_clock_720p,
++ [CLK_74_25] = imx290_74_250mhz_clock_720p,
++ },
++ .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_720p),
+ },
+ {
+ .width = 1280,
+@@ -339,6 +400,11 @@ static const struct imx290_mode imx290_m
+ .link_freq_index = FREQ_INDEX_720P,
+ .data = imx290_720p_settings,
+ .data_size = ARRAY_SIZE(imx290_720p_settings),
++ .clk_data = {
++ [CLK_37_125] = imx290_37_125mhz_clock_720p,
++ [CLK_74_25] = imx290_74_250mhz_clock_720p,
++ },
++ .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_720p),
+ },
+ };
+
+@@ -712,6 +778,8 @@ static int imx290_set_hmax(struct imx290
+ /* Start streaming */
+ static int imx290_start_streaming(struct imx290 *imx290)
+ {
++ enum imx290_clk_index clk_idx = imx290->xclk_freq == 37125000 ?
++ CLK_37_125 : CLK_74_25;
+ int ret;
+
+ /* Set init register settings */
+@@ -723,6 +791,14 @@ static int imx290_start_streaming(struct
+ return ret;
+ }
+
++ ret = imx290_set_register_array(imx290,
++ imx290->current_mode->clk_data[clk_idx],
++ imx290->current_mode->clk_size);
++ if (ret < 0) {
++ dev_err(imx290->dev, "Could not set clock registers\n");
++ return ret;
++ }
++
+ /* Apply the register values related to current frame format */
+ ret = imx290_write_current_format(imx290);
+ if (ret < 0) {
+@@ -939,7 +1015,6 @@ static int imx290_probe(struct i2c_clien
+ .bus_type = V4L2_MBUS_CSI2_DPHY
+ };
+ struct imx290 *imx290;
+- u32 xclk_freq;
+ s64 fq;
+ int ret;
+
+@@ -1003,21 +1078,21 @@ static int imx290_probe(struct i2c_clien
+ }
+
+ ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
+- &xclk_freq);
++ &imx290->xclk_freq);
+ if (ret) {
+ dev_err(dev, "Could not get xclk frequency\n");
+ goto free_err;
+ }
+
+ /* external clock must be 37.125 MHz */
+- if (xclk_freq != 37125000) {
++ if (imx290->xclk_freq != 37125000 && imx290->xclk_freq != 74250000) {
+ dev_err(dev, "External clock frequency %u is not supported\n",
+- xclk_freq);
++ imx290->xclk_freq);
+ ret = -EINVAL;
+ goto free_err;
+ }
+
+- ret = clk_set_rate(imx290->xclk, xclk_freq);
++ ret = clk_set_rate(imx290->xclk, imx290->xclk_freq);
+ if (ret) {
+ dev_err(dev, "Could not set xclk frequency\n");
+ goto free_err;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0828-media-i2c-imx290-Correct-range-for-V4L2_CID_GAIN-to-.patch b/target/linux/bcm27xx/patches-5.4/950-0828-media-i2c-imx290-Correct-range-for-V4L2_CID_GAIN-to-.patch
new file mode 100644
index 0000000000..462c88dab4
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0828-media-i2c-imx290-Correct-range-for-V4L2_CID_GAIN-to-.patch
@@ -0,0 +1,26 @@
+From 6d659cddefb5f9f35160f4b7b8d5a77935480b2d Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 11 Jun 2020 13:41:43 +0100
+Subject: [PATCH] media: i2c: imx290: Correct range for V4L2_CID_GAIN
+ to 0-238
+
+The datasheet lists the gain as being 0.0 to 72.0dB in 0.3dB steps, which
+makes 238 steps total.
+Correct the 0-72 range defined in the driver.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/imx290.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -1124,7 +1124,7 @@ static int imx290_probe(struct i2c_clien
+ v4l2_ctrl_handler_init(&imx290->ctrls, 4);
+
+ v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
+- V4L2_CID_GAIN, 0, 72, 1, 0);
++ V4L2_CID_GAIN, 0, 238, 1, 0);
+
+ imx290->link_freq =
+ v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0829-media-i2c-imx290-Convert-HMAX-setting-into-V4L2_CID_.patch b/target/linux/bcm27xx/patches-5.4/950-0829-media-i2c-imx290-Convert-HMAX-setting-into-V4L2_CID_.patch
new file mode 100644
index 0000000000..7a0a5f06aa
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0829-media-i2c-imx290-Convert-HMAX-setting-into-V4L2_CID_.patch
@@ -0,0 +1,159 @@
+From 116dc059ca9c6b088afba98dde7b679a97ae7198 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 11 Jun 2020 14:36:40 +0100
+Subject: [PATCH] media: i2c: imx290: Convert HMAX setting into
+ V4L2_CID_HBLANK
+
+Userspace needs to know HBLANK if it is to work out exposure times
+and frame rates, therefore convert it to map onto V4L2_CID_HBLANK
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/imx290.c | 66 +++++++++++++++++++++++++-------------
+ 1 file changed, 44 insertions(+), 22 deletions(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -40,6 +40,9 @@ enum imx290_clk_index {
+ #define IMX290_GAIN 0x3014
+ #define IMX290_HMAX_LOW 0x301c
+ #define IMX290_HMAX_HIGH 0x301d
++#define IMX290_HMAX_MIN_2LANE 4400 /* Min of 4400 pixels = 30fps */
++#define IMX290_HMAX_MIN_4LANE 2200 /* Min of 2200 pixels = 60fps */
++#define IMX290_HMAX_MAX 0xffff
+ #define IMX290_PGCTRL 0x308c
+ #define IMX290_PHY_LANE_NUM 0x3407
+ #define IMX290_CSI_LANE_MODE 0x3443
+@@ -82,6 +85,7 @@ struct imx290 {
+ struct regmap *regmap;
+ u8 nlanes;
+ u8 bpp;
++ u16 hmax_min;
+
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+@@ -94,6 +98,7 @@ struct imx290 {
+ struct v4l2_ctrl_handler ctrls;
+ struct v4l2_ctrl *link_freq;
+ struct v4l2_ctrl *pixel_rate;
++ struct v4l2_ctrl *hblank;
+
+ struct mutex lock;
+ };
+@@ -518,6 +523,26 @@ static int imx290_set_gain(struct imx290
+ return ret;
+ }
+
++static int imx290_set_hmax(struct imx290 *imx290, u32 val)
++{
++ u32 hmax = val + imx290->current_mode->width;
++ int ret;
++
++ ret = imx290_write_reg(imx290, IMX290_HMAX_LOW, (hmax & 0xff));
++ if (ret) {
++ dev_err(imx290->dev, "Error setting HMAX register\n");
++ return ret;
++ }
++
++ ret = imx290_write_reg(imx290, IMX290_HMAX_HIGH, ((hmax >> 8) & 0xff));
++ if (ret) {
++ dev_err(imx290->dev, "Error setting HMAX register\n");
++ return ret;
++ }
++
++ return 0;
++}
++
+ /* Stop streaming */
+ static int imx290_stop_streaming(struct imx290 *imx290)
+ {
+@@ -546,6 +571,9 @@ static int imx290_set_ctrl(struct v4l2_c
+ case V4L2_CID_GAIN:
+ ret = imx290_set_gain(imx290, ctrl->val);
+ break;
++ case V4L2_CID_HBLANK:
++ ret = imx290_set_hmax(imx290, ctrl->val);
++ break;
+ case V4L2_CID_TEST_PATTERN:
+ if (ctrl->val) {
+ imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00);
+@@ -702,6 +730,12 @@ static int imx290_set_fmt(struct v4l2_su
+ if (imx290->pixel_rate)
+ __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate,
+ imx290_calc_pixel_rate(imx290));
++
++ if (imx290->hblank)
++ __v4l2_ctrl_modify_range(imx290->hblank,
++ imx290->hmax_min - mode->width,
++ IMX290_HMAX_MAX - mode->width,
++ 1, mode->hmax - mode->width);
+ }
+
+ *format = fmt->format;
+@@ -756,25 +790,6 @@ static int imx290_write_current_format(s
+ return 0;
+ }
+
+-static int imx290_set_hmax(struct imx290 *imx290, u32 val)
+-{
+- int ret;
+-
+- ret = imx290_write_reg(imx290, IMX290_HMAX_LOW, (val & 0xff));
+- if (ret) {
+- dev_err(imx290->dev, "Error setting HMAX register\n");
+- return ret;
+- }
+-
+- ret = imx290_write_reg(imx290, IMX290_HMAX_HIGH, ((val >> 8) & 0xff));
+- if (ret) {
+- dev_err(imx290->dev, "Error setting HMAX register\n");
+- return ret;
+- }
+-
+- return 0;
+-}
+-
+ /* Start streaming */
+ static int imx290_start_streaming(struct imx290 *imx290)
+ {
+@@ -813,9 +828,6 @@ static int imx290_start_streaming(struct
+ dev_err(imx290->dev, "Could not set current mode\n");
+ return ret;
+ }
+- ret = imx290_set_hmax(imx290, imx290->current_mode->hmax);
+- if (ret < 0)
+- return ret;
+
+ /* Apply customized values from user */
+ ret = v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler);
+@@ -1014,6 +1026,7 @@ static int imx290_probe(struct i2c_clien
+ struct v4l2_fwnode_endpoint ep = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY
+ };
++ const struct imx290_mode *mode;
+ struct imx290 *imx290;
+ s64 fq;
+ int ret;
+@@ -1052,6 +1065,8 @@ static int imx290_probe(struct i2c_clien
+ ret = -EINVAL;
+ goto free_err;
+ }
++ imx290->hmax_min = (imx290->nlanes == 2) ? IMX290_HMAX_MIN_2LANE :
++ IMX290_HMAX_MIN_4LANE;
+
+ dev_dbg(dev, "Using %u data lanes\n", imx290->nlanes);
+
+@@ -1126,6 +1141,13 @@ static int imx290_probe(struct i2c_clien
+ v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
+ V4L2_CID_GAIN, 0, 238, 1, 0);
+
++ mode = imx290->current_mode;
++ imx290->hblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
++ V4L2_CID_HBLANK,
++ imx290->hmax_min - mode->width,
++ IMX290_HMAX_MAX - mode->width, 1,
++ mode->hmax - mode->width);
++
+ imx290->link_freq =
+ v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops,
+ V4L2_CID_LINK_FREQ,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0830-media-i2c-imx290-Add-support-for-V4L2_CID_VBLANK.patch b/target/linux/bcm27xx/patches-5.4/950-0830-media-i2c-imx290-Add-support-for-V4L2_CID_VBLANK.patch
new file mode 100644
index 0000000000..daa5d54145
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0830-media-i2c-imx290-Add-support-for-V4L2_CID_VBLANK.patch
@@ -0,0 +1,141 @@
+From 12a04a18c7a56dbd2943b6666c7978b09499fc4b Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 11 Jun 2020 18:09:12 +0100
+Subject: [PATCH] media: i2c: imx290: Add support for V4L2_CID_VBLANK
+
+In order to calculate framerate and durations userspace needs
+the vertical blanking information. This can be configurable,
+and indeed the datasheet lists different values for VBLANK for
+the 1080p and 720p modes.
+
+Add the new control, and adopt the datasheet values for each mode.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/imx290.c | 38 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 36 insertions(+), 2 deletions(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -38,6 +38,8 @@ enum imx290_clk_index {
+ #define IMX290_BLKLEVEL_LOW 0x300a
+ #define IMX290_BLKLEVEL_HIGH 0x300b
+ #define IMX290_GAIN 0x3014
++#define IMX290_VMAX_LOW 0x3018
++#define IMX290_VMAX_MAX 0x3fff
+ #define IMX290_HMAX_LOW 0x301c
+ #define IMX290_HMAX_HIGH 0x301d
+ #define IMX290_HMAX_MIN_2LANE 4400 /* Min of 4400 pixels = 30fps */
+@@ -68,6 +70,7 @@ struct imx290_mode {
+ u32 width;
+ u32 height;
+ u32 hmax;
++ u32 vmax;
+ u8 link_freq_index;
+
+ const struct imx290_regval *data;
+@@ -99,6 +102,7 @@ struct imx290 {
+ struct v4l2_ctrl *link_freq;
+ struct v4l2_ctrl *pixel_rate;
+ struct v4l2_ctrl *hblank;
++ struct v4l2_ctrl *vblank;
+
+ struct mutex lock;
+ };
+@@ -132,8 +136,6 @@ static const char * const imx290_test_pa
+
+ static const struct imx290_regval imx290_global_init_settings[] = {
+ { 0x3007, 0x00 },
+- { 0x3018, 0x65 },
+- { 0x3019, 0x04 },
+ { 0x301a, 0x00 },
+ { 0x303a, 0x0c },
+ { 0x3040, 0x00 },
+@@ -360,6 +362,7 @@ static const struct imx290_mode imx290_m
+ .width = 1920,
+ .height = 1080,
+ .hmax = 0x1130,
++ .vmax = 0x0465,
+ .link_freq_index = FREQ_INDEX_1080P,
+ .data = imx290_1080p_settings,
+ .data_size = ARRAY_SIZE(imx290_1080p_settings),
+@@ -373,6 +376,7 @@ static const struct imx290_mode imx290_m
+ .width = 1280,
+ .height = 720,
+ .hmax = 0x19c8,
++ .vmax = 0x02ee,
+ .link_freq_index = FREQ_INDEX_720P,
+ .data = imx290_720p_settings,
+ .data_size = ARRAY_SIZE(imx290_720p_settings),
+@@ -389,6 +393,7 @@ static const struct imx290_mode imx290_m
+ .width = 1920,
+ .height = 1080,
+ .hmax = 0x0898,
++ .vmax = 0x0465,
+ .link_freq_index = FREQ_INDEX_1080P,
+ .data = imx290_1080p_settings,
+ .data_size = ARRAY_SIZE(imx290_1080p_settings),
+@@ -402,6 +407,7 @@ static const struct imx290_mode imx290_m
+ .width = 1280,
+ .height = 720,
+ .hmax = 0x0ce4,
++ .vmax = 0x02ee,
+ .link_freq_index = FREQ_INDEX_720P,
+ .data = imx290_720p_settings,
+ .data_size = ARRAY_SIZE(imx290_720p_settings),
+@@ -543,6 +549,19 @@ static int imx290_set_hmax(struct imx290
+ return 0;
+ }
+
++static int imx290_set_vmax(struct imx290 *imx290, u32 val)
++{
++ u32 vmax = val + imx290->current_mode->height;
++ int ret;
++
++ ret = imx290_write_buffered_reg(imx290, IMX290_VMAX_LOW, 3,
++ vmax);
++ if (ret)
++ dev_err(imx290->dev, "Unable to write vmax\n");
++
++ return ret;
++}
++
+ /* Stop streaming */
+ static int imx290_stop_streaming(struct imx290 *imx290)
+ {
+@@ -574,6 +593,9 @@ static int imx290_set_ctrl(struct v4l2_c
+ case V4L2_CID_HBLANK:
+ ret = imx290_set_hmax(imx290, ctrl->val);
+ break;
++ case V4L2_CID_VBLANK:
++ ret = imx290_set_vmax(imx290, ctrl->val);
++ break;
+ case V4L2_CID_TEST_PATTERN:
+ if (ctrl->val) {
+ imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00);
+@@ -736,6 +758,12 @@ static int imx290_set_fmt(struct v4l2_su
+ imx290->hmax_min - mode->width,
+ IMX290_HMAX_MAX - mode->width,
+ 1, mode->hmax - mode->width);
++ if (imx290->vblank)
++ __v4l2_ctrl_modify_range(imx290->vblank,
++ mode->vmax - mode->height,
++ IMX290_VMAX_MAX - mode->height,
++ 1,
++ mode->vmax - mode->height);
+ }
+
+ *format = fmt->format;
+@@ -1148,6 +1176,12 @@ static int imx290_probe(struct i2c_clien
+ IMX290_HMAX_MAX - mode->width, 1,
+ mode->hmax - mode->width);
+
++ imx290->vblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
++ V4L2_CID_VBLANK,
++ mode->vmax - mode->height,
++ IMX290_VMAX_MAX - mode->height, 1,
++ mode->vmax - mode->height);
++
+ imx290->link_freq =
+ v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops,
+ V4L2_CID_LINK_FREQ,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0831-media-i2c-imx290-Add-exposure-control-to-the-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0831-media-i2c-imx290-Add-exposure-control-to-the-driver.patch
new file mode 100644
index 0000000000..86836dc3af
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0831-media-i2c-imx290-Add-exposure-control-to-the-driver.patch
@@ -0,0 +1,93 @@
+From d6c85afca764dc32c3d7981867471fc820e07388 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 11 Jun 2020 18:19:13 +0100
+Subject: [PATCH] media: i2c: imx290: Add exposure control to the
+ driver.
+
+Adds support for V4L2_CID_EXPOSURE so that userspace can control
+the sensor exposure time.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/imx290.c | 35 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -45,6 +45,10 @@ enum imx290_clk_index {
+ #define IMX290_HMAX_MIN_2LANE 4400 /* Min of 4400 pixels = 30fps */
+ #define IMX290_HMAX_MIN_4LANE 2200 /* Min of 2200 pixels = 60fps */
+ #define IMX290_HMAX_MAX 0xffff
++
++#define IMX290_EXPOSURE_MIN 2
++#define IMX290_EXPOSURE_STEP 1
++#define IMX290_EXPOSURE_LOW 0x3020
+ #define IMX290_PGCTRL 0x308c
+ #define IMX290_PHY_LANE_NUM 0x3407
+ #define IMX290_CSI_LANE_MODE 0x3443
+@@ -103,6 +107,7 @@ struct imx290 {
+ struct v4l2_ctrl *pixel_rate;
+ struct v4l2_ctrl *hblank;
+ struct v4l2_ctrl *vblank;
++ struct v4l2_ctrl *exposure;
+
+ struct mutex lock;
+ };
+@@ -529,6 +534,20 @@ static int imx290_set_gain(struct imx290
+ return ret;
+ }
+
++static int imx290_set_exposure(struct imx290 *imx290, u32 value)
++{
++ u32 exposure = (imx290->current_mode->height + imx290->vblank->val) -
++ value;
++ int ret;
++
++ ret = imx290_write_buffered_reg(imx290, IMX290_EXPOSURE_LOW, 3,
++ exposure);
++ if (ret)
++ dev_err(imx290->dev, "Unable to write exposure\n");
++
++ return ret;
++}
++
+ static int imx290_set_hmax(struct imx290 *imx290, u32 val)
+ {
+ u32 hmax = val + imx290->current_mode->width;
+@@ -590,6 +609,9 @@ static int imx290_set_ctrl(struct v4l2_c
+ case V4L2_CID_GAIN:
+ ret = imx290_set_gain(imx290, ctrl->val);
+ break;
++ case V4L2_CID_EXPOSURE:
++ ret = imx290_set_exposure(imx290, ctrl->val);
++ break;
+ case V4L2_CID_HBLANK:
+ ret = imx290_set_hmax(imx290, ctrl->val);
+ break;
+@@ -764,6 +786,12 @@ static int imx290_set_fmt(struct v4l2_su
+ IMX290_VMAX_MAX - mode->height,
+ 1,
+ mode->vmax - mode->height);
++ if (imx290->exposure)
++ __v4l2_ctrl_modify_range(imx290->exposure,
++ mode->vmax - mode->height,
++ mode->vmax - 4,
++ IMX290_EXPOSURE_STEP,
++ mode->vmax - 4);
+ }
+
+ *format = fmt->format;
+@@ -1182,6 +1210,13 @@ static int imx290_probe(struct i2c_clien
+ IMX290_VMAX_MAX - mode->height, 1,
+ mode->vmax - mode->height);
+
++ imx290->exposure = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
++ V4L2_CID_EXPOSURE,
++ IMX290_EXPOSURE_MIN,
++ mode->vmax - 4,
++ IMX290_EXPOSURE_STEP,
++ mode->vmax - 4);
++
+ imx290->link_freq =
+ v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops,
+ V4L2_CID_LINK_FREQ,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0832-media-i2c-imx290-Add-H-and-V-flip-controls.patch b/target/linux/bcm27xx/patches-5.4/950-0832-media-i2c-imx290-Add-H-and-V-flip-controls.patch
new file mode 100644
index 0000000000..b96807b6cd
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0832-media-i2c-imx290-Add-H-and-V-flip-controls.patch
@@ -0,0 +1,83 @@
+From a6048e36f5e5d73a29d1f5096fc77286f8aa949d Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 11 Jun 2020 18:34:16 +0100
+Subject: [PATCH] media: i2c: imx290: Add H and V flip controls
+
+The sensor supports horizontal and vertical flips, so support them
+through V4L2_CID_HFLIP and V4L2_CID_VFLIP.
+
+This sensor does NOT change the Bayer order when changing the
+direction of readout, therefore no special handling is required for
+that.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/imx290.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -34,6 +34,7 @@ enum imx290_clk_index {
+ #define IMX290_STANDBY 0x3000
+ #define IMX290_REGHOLD 0x3001
+ #define IMX290_XMSTA 0x3002
++#define IMX290_FLIP_WINMODE 0x3007
+ #define IMX290_FR_FDG_SEL 0x3009
+ #define IMX290_BLKLEVEL_LOW 0x300a
+ #define IMX290_BLKLEVEL_HIGH 0x300b
+@@ -107,6 +108,8 @@ struct imx290 {
+ struct v4l2_ctrl *pixel_rate;
+ struct v4l2_ctrl *hblank;
+ struct v4l2_ctrl *vblank;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vflip;
+ struct v4l2_ctrl *exposure;
+
+ struct mutex lock;
+@@ -600,6 +603,7 @@ static int imx290_set_ctrl(struct v4l2_c
+ struct imx290 *imx290 = container_of(ctrl->handler,
+ struct imx290, ctrls);
+ int ret = 0;
++ u8 val;
+
+ /* V4L2 controls values will be applied only when power is already up */
+ if (!pm_runtime_get_if_in_use(imx290->dev))
+@@ -618,6 +622,16 @@ static int imx290_set_ctrl(struct v4l2_c
+ case V4L2_CID_VBLANK:
+ ret = imx290_set_vmax(imx290, ctrl->val);
+ break;
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ /* WINMODE is in bits [6:4], so need to read-modify-write */
++ ret = imx290_read_reg(imx290, IMX290_FLIP_WINMODE, &val);
++ if (ret)
++ break;
++ val &= ~0x03;
++ val |= imx290->vflip->val | (imx290->hflip->val << 1);
++ ret = imx290_write_reg(imx290, IMX290_FLIP_WINMODE, val);
++ break;
+ case V4L2_CID_TEST_PATTERN:
+ if (ctrl->val) {
+ imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00);
+@@ -924,6 +938,9 @@ static int imx290_set_stream(struct v4l2
+ imx290_stop_streaming(imx290);
+ pm_runtime_put(imx290->dev);
+ }
++ /* vflip and hflip cannot change during streaming */
++ __v4l2_ctrl_grab(imx290->vflip, enable);
++ __v4l2_ctrl_grab(imx290->hflip, enable);
+
+ unlock_and_return:
+
+@@ -1217,6 +1234,11 @@ static int imx290_probe(struct i2c_clien
+ IMX290_EXPOSURE_STEP,
+ mode->vmax - 4);
+
++ imx290->hflip = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ imx290->vflip = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++
+ imx290->link_freq =
+ v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops,
+ V4L2_CID_LINK_FREQ,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0833-media-dt-bindings-media-i2c-Add-mono-version-to-IMX2.patch b/target/linux/bcm27xx/patches-5.4/950-0833-media-dt-bindings-media-i2c-Add-mono-version-to-IMX2.patch
new file mode 100644
index 0000000000..50c93f0a9e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0833-media-dt-bindings-media-i2c-Add-mono-version-to-IMX2.patch
@@ -0,0 +1,36 @@
+From 05ba3df09751ff516de5d862c98f5a979b51bb56 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 25 Jun 2020 16:52:14 +0100
+Subject: [PATCH] media: dt-bindings: media: i2c: Add mono version to
+ IMX290 bindings
+
+The IMX290 module is available as either monochrome or colour and
+the variant is not detectable at runtime.
+
+Add a new compatible string for the monochrome version.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ Documentation/devicetree/bindings/media/i2c/imx290.txt | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/Documentation/devicetree/bindings/media/i2c/imx290.txt
++++ b/Documentation/devicetree/bindings/media/i2c/imx290.txt
+@@ -1,13 +1,14 @@
+ * Sony IMX290 1/2.8-Inch CMOS Image Sensor
+
+ The Sony IMX290 is a 1/2.8-Inch CMOS Solid-state image sensor with
+-Square Pixel for Color Cameras. It is programmable through I2C and 4-wire
+-interfaces. The sensor output is available via CMOS logic parallel SDR output,
++Square Pixel for Color or Monochrome Cameras. It is programmable through I2C
++and 4-wire interfaces.
++The sensor output is available via CMOS logic parallel SDR output,
+ Low voltage LVDS DDR output and CSI-2 serial data output. The CSI-2 bus is the
+ default. No bindings have been defined for the other busses.
+
+ Required Properties:
+-- compatible: Should be "sony,imx290"
++- compatible: Should be "sony,imx290", or "sony,imx290-mono"
+ - reg: I2C bus address of the device
+ - clocks: Reference to the xclk clock.
+ - clock-names: Should be "xclk".
diff --git a/target/linux/bcm27xx/patches-5.4/950-0834-media-i2c-imx290-Add-support-for-the-mono-sensor-var.patch b/target/linux/bcm27xx/patches-5.4/950-0834-media-i2c-imx290-Add-support-for-the-mono-sensor-var.patch
new file mode 100644
index 0000000000..f75a2203df
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0834-media-i2c-imx290-Add-support-for-the-mono-sensor-var.patch
@@ -0,0 +1,185 @@
+From c9f918319593861c4975b229579def5fbd637ad9 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 25 Jun 2020 17:03:11 +0100
+Subject: [PATCH] media : i2c: imx290: Add support for the mono
+ sensor variant.
+
+The IMX290 module is available as either mono or colour (Bayer).
+
+Update the driver so that it can advertise the correct mono
+formats instead of the colour ones.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/imx290.c | 58 +++++++++++++++++++++++++++-----------
+ 1 file changed, 41 insertions(+), 17 deletions(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -1,10 +1,12 @@
+ // SPDX-License-Identifier: GPL-2.0
+ /*
+- * Sony IMX290/327 CMOS Image Sensor Driver
++ * Sony IMX290 & IMX327 CMOS Image Sensor Driver
+ *
+ * The IMX290 and IMX327 are very similar 1920x1080 1/2.8 CMOS image sensors.
+- * IMX327 can support up to 60fps, whilst IMX290 support up to 120fps (only
+- * 10bit and when connected over 4 CSI-2 lanes).
++ * IMX327 can support up to 60fps, whilst IMX290 can support up to 120fps, but
++ * only 10bit and when connected over 4 CSI-2 lanes.
++ * The modules don't appear to have a mechanism to identify whether the mono or
++ * colour variant is connected, therefore it is done via compatible string.
+ *
+ * Copyright (C) 2019 FRAMOS GmbH.
+ *
+@@ -17,6 +19,7 @@
+ #include <linux/gpio/consumer.h>
+ #include <linux/i2c.h>
+ #include <linux/module.h>
++#include <linux/of_device.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/regmap.h>
+ #include <linux/regulator/consumer.h>
+@@ -95,6 +98,8 @@ struct imx290 {
+ u8 bpp;
+ u16 hmax_min;
+
++ const struct imx290_pixfmt *formats;
++
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+ struct v4l2_mbus_framefmt current_format;
+@@ -120,11 +125,18 @@ struct imx290_pixfmt {
+ u8 bpp;
+ };
+
+-static const struct imx290_pixfmt imx290_formats[] = {
++#define IMX290_NUM_FORMATS 2
++
++static const struct imx290_pixfmt imx290_colour_formats[IMX290_NUM_FORMATS] = {
+ { MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
+ { MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
+ };
+
++static const struct imx290_pixfmt imx290_mono_formats[IMX290_NUM_FORMATS] = {
++ { MEDIA_BUS_FMT_Y10_1X10, 10 },
++ { MEDIA_BUS_FMT_Y12_1X12, 12 },
++};
++
+ static const struct regmap_config imx290_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+@@ -671,10 +683,12 @@ static int imx290_enum_mbus_code(struct
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+ {
+- if (code->index >= ARRAY_SIZE(imx290_formats))
++ const struct imx290 *imx290 = to_imx290(sd);
++
++ if (code->index >= IMX290_NUM_FORMATS)
+ return -EINVAL;
+
+- code->code = imx290_formats[code->index].code;
++ code->code = imx290->formats[code->index].code;
+
+ return 0;
+ }
+@@ -686,8 +700,8 @@ static int imx290_enum_frame_size(struct
+ const struct imx290 *imx290 = to_imx290(sd);
+ const struct imx290_mode *imx290_modes = imx290_modes_ptr(imx290);
+
+- if ((fse->code != imx290_formats[0].code) &&
+- (fse->code != imx290_formats[1].code))
++ if (fse->code != imx290->formats[0].code &&
++ fse->code != imx290->formats[1].code)
+ return -EINVAL;
+
+ if (fse->index >= imx290_modes_num(imx290))
+@@ -765,14 +779,14 @@ static int imx290_set_fmt(struct v4l2_su
+ fmt->format.width = mode->width;
+ fmt->format.height = mode->height;
+
+- for (i = 0; i < ARRAY_SIZE(imx290_formats); i++)
+- if (imx290_formats[i].code == fmt->format.code)
++ for (i = 0; i < IMX290_NUM_FORMATS; i++)
++ if (imx290->formats[i].code == fmt->format.code)
+ break;
+
+- if (i >= ARRAY_SIZE(imx290_formats))
++ if (i >= IMX290_NUM_FORMATS)
+ i = 0;
+
+- fmt->format.code = imx290_formats[i].code;
++ fmt->format.code = imx290->formats[i].code;
+ fmt->format.field = V4L2_FIELD_NONE;
+
+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+@@ -780,7 +794,7 @@ static int imx290_set_fmt(struct v4l2_su
+ } else {
+ format = &imx290->current_format;
+ imx290->current_mode = mode;
+- imx290->bpp = imx290_formats[i].bpp;
++ imx290->bpp = imx290->formats[i].bpp;
+
+ if (imx290->link_freq)
+ __v4l2_ctrl_s_ctrl(imx290->link_freq,
+@@ -835,6 +849,7 @@ static int imx290_write_current_format(s
+
+ switch (imx290->current_format.code) {
+ case MEDIA_BUS_FMT_SRGGB10_1X10:
++ case MEDIA_BUS_FMT_Y10_1X10:
+ ret = imx290_set_register_array(imx290, imx290_10bit_settings,
+ ARRAY_SIZE(
+ imx290_10bit_settings));
+@@ -844,6 +859,7 @@ static int imx290_write_current_format(s
+ }
+ break;
+ case MEDIA_BUS_FMT_SRGGB12_1X12:
++ case MEDIA_BUS_FMT_Y12_1X12:
+ ret = imx290_set_register_array(imx290, imx290_12bit_settings,
+ ARRAY_SIZE(
+ imx290_12bit_settings));
+@@ -1091,6 +1107,12 @@ static s64 imx290_check_link_freqs(const
+ return 0;
+ }
+
++static const struct of_device_id imx290_of_match[] = {
++ { .compatible = "sony,imx290", .data = imx290_colour_formats },
++ { .compatible = "sony,imx290-mono", .data = imx290_mono_formats },
++ { /* sentinel */ }
++};
++
+ static int imx290_probe(struct i2c_client *client)
+ {
+ struct device *dev = &client->dev;
+@@ -1099,6 +1121,7 @@ static int imx290_probe(struct i2c_clien
+ struct v4l2_fwnode_endpoint ep = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY
+ };
++ const struct of_device_id *match;
+ const struct imx290_mode *mode;
+ struct imx290 *imx290;
+ s64 fq;
+@@ -1115,6 +1138,11 @@ static int imx290_probe(struct i2c_clien
+ return -ENODEV;
+ }
+
++ match = of_match_device(imx290_of_match, dev);
++ if (!match)
++ return -ENODEV;
++ imx290->formats = (const struct imx290_pixfmt *)match->data;
++
+ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
+ if (!endpoint) {
+ dev_err(dev, "Endpoint node not found\n");
+@@ -1330,10 +1358,6 @@ static int imx290_remove(struct i2c_clie
+ return 0;
+ }
+
+-static const struct of_device_id imx290_of_match[] = {
+- { .compatible = "sony,imx290" },
+- { /* sentinel */ }
+-};
+ MODULE_DEVICE_TABLE(of, imx290_of_match);
+
+ static struct i2c_driver imx290_i2c_driver = {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0835-media-i2c-imx290-Switch-set_hmax-to-use-imx290_write.patch b/target/linux/bcm27xx/patches-5.4/950-0835-media-i2c-imx290-Switch-set_hmax-to-use-imx290_write.patch
new file mode 100644
index 0000000000..7819e70ea3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0835-media-i2c-imx290-Switch-set_hmax-to-use-imx290_write.patch
@@ -0,0 +1,43 @@
+From 970208edb92b04eaa329c666e2e91717984c28b6 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 26 Jun 2020 18:11:49 +0100
+Subject: [PATCH] media: i2c: imx290: Switch set_hmax to use
+ imx290_write_buffered_reg
+
+imx290_set_hmax was using two independent writes to set up hmax,
+when all other multi-register writes were using imx290_write_buffered_reg
+which claims the group hold first.
+
+Switch imx290_set_hmax to using imx290_write_buffered_reg too.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/imx290.c | 15 ++++-----------
+ 1 file changed, 4 insertions(+), 11 deletions(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -568,19 +568,12 @@ static int imx290_set_hmax(struct imx290
+ u32 hmax = val + imx290->current_mode->width;
+ int ret;
+
+- ret = imx290_write_reg(imx290, IMX290_HMAX_LOW, (hmax & 0xff));
+- if (ret) {
++ ret = imx290_write_buffered_reg(imx290, IMX290_HMAX_LOW, 2,
++ hmax);
++ if (ret)
+ dev_err(imx290->dev, "Error setting HMAX register\n");
+- return ret;
+- }
+
+- ret = imx290_write_reg(imx290, IMX290_HMAX_HIGH, ((hmax >> 8) & 0xff));
+- if (ret) {
+- dev_err(imx290->dev, "Error setting HMAX register\n");
+- return ret;
+- }
+-
+- return 0;
++ return ret;
+ }
+
+ static int imx290_set_vmax(struct imx290 *imx290, u32 val)
diff --git a/target/linux/bcm27xx/patches-5.4/950-0836-dtoverlays-Add-an-overlay-for-the-Sony-IMX290-image-.patch b/target/linux/bcm27xx/patches-5.4/950-0836-dtoverlays-Add-an-overlay-for-the-Sony-IMX290-image-.patch
new file mode 100644
index 0000000000..f64db00ddc
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0836-dtoverlays-Add-an-overlay-for-the-Sony-IMX290-image-.patch
@@ -0,0 +1,236 @@
+From 57250281004e141dff4662d1abb3f31982ec01ee Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 19 May 2020 13:35:17 +0100
+Subject: [PATCH] dtoverlays: Add an overlay for the Sony IMX290
+ image sensor
+
+Adds an overlay to configure the IMX290 image sensor.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 16 ++
+ arch/arm/boot/dts/overlays/imx290-overlay.dts | 32 ++++
+ .../boot/dts/overlays/imx290_327-overlay.dtsi | 145 ++++++++++++++++++
+ 4 files changed, 194 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/imx290-overlay.dts
+ create mode 100644 arch/arm/boot/dts/overlays/imx290_327-overlay.dtsi
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -85,6 +85,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ i2s-gpio28-31.dtbo \
+ ilitek251x.dtbo \
+ imx219.dtbo \
++ imx290.dtbo \
+ imx477.dtbo \
+ iqaudio-codec.dtbo \
+ iqaudio-dac.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1430,6 +1430,22 @@ Load: dtoverlay=imx219
+ Params: <None>
+
+
++Name: imx290
++Info: Sony IMX290 camera module.
++ Uses Unicam 1, which is the standard camera connector on most Pi
++ variants. NB This currently uses 4 CSI2 data lanes and therefore will
++ only work on a CM.
++Load: dtoverlay=imx290,<param>
++Params: 4lane Enable 4 CSI2 lanes. This requires a Compute
++ Module (1, 3, or 4).
++ clock-frequency Sets the clock frequency to match that used on
++ the board.
++ Modules from Vision Components use 37.125MHz
++ (the default), whilst those from Innomaker use
++ 74.25MHz.
++ mono Denote that the module is a mono sensor.
++
++
+ Name: imx477
+ Info: Sony IMX477 camera module.
+ Uses Unicam 1, which is the standard camera connector on most Pi
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/imx290-overlay.dts
+@@ -0,0 +1,32 @@
++// SPDX-License-Identifier: GPL-2.0-only
++// Definitions for IMX290 camera module on VC I2C bus
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++#include "imx290_327-overlay.dtsi"
++
++/{
++ compatible = "brcm,bcm2835";
++
++ // Fragment numbers deliberately high to avoid conflicts with the
++ // included imx290_327 overlay file.
++
++ fragment@101 {
++ target = <&imx290>;
++ __overlay__ {
++ compatible = "sony,imx290";
++ };
++ };
++
++ fragment@102 {
++ target = <&imx290>;
++ __dormant__ {
++ compatible = "sony,imx290-mono";
++ };
++ };
++
++ __overrides__ {
++ mono = <0>, "-101+102";
++ };
++};
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/imx290_327-overlay.dtsi
+@@ -0,0 +1,145 @@
++// SPDX-License-Identifier: GPL-2.0-only
++// Partial definitions for IMX290 or IMX327 camera module on VC I2C bus
++// The compatible string should be set in an overlay that then includes this one
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++
++/{
++ compatible = "brcm,bcm2835";
++
++ fragment@0 {
++ target = <&i2c_csi_dsi>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ imx290: imx290@1a {
++ reg = <0x1a>;
++ status = "okay";
++
++ clocks = <&imx290_clk>;
++ clock-names = "xclk";
++ clock-frequency = <37125000>;
++
++ vdda-supply = <&imx290_vdda>; /* 2.8v */
++ vdddo-supply = <&imx290_vdddo>; /* 1.8v */
++ vddd-supply = <&imx290_vddd>; /* 1.5v */
++
++ port {
++ imx290_0: endpoint {
++ remote-endpoint = <&csi1_ep>;
++ clock-lanes = <0>;
++ };
++ };
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&csi1>;
++ __overlay__ {
++ status = "okay";
++
++ port {
++ csi1_ep: endpoint {
++ remote-endpoint = <&imx290_0>;
++ };
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&i2c0if>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@3 {
++ target-path="/";
++ __overlay__ {
++ imx290_vdda: fixedregulator@0 {
++ compatible = "regulator-fixed";
++ regulator-name = "imx290_vdda";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ gpio = <&gpio 41 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++ imx290_vdddo: fixedregulator@1 {
++ compatible = "regulator-fixed";
++ regulator-name = "imx290_vdddo";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++ imx290_vddd: fixedregulator@2 {
++ compatible = "regulator-fixed";
++ regulator-name = "imx290_vddd";
++ regulator-min-microvolt = <1500000>;
++ regulator-max-microvolt = <1500000>;
++ };
++
++ imx290_clk: camera-clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <37125000>;
++ };
++ };
++ };
++
++ fragment@4 {
++ target = <&i2c0mux>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@5 {
++ target-path="/__overrides__";
++ __overlay__ {
++ cam0-pwdn-ctrl = <&imx290_vdda>,"gpio:0";
++ cam0-pwdn = <&imx290_vdda>,"gpio:4";
++ };
++ };
++
++ fragment@6 {
++ target = <&imx290_0>;
++ __overlay__ {
++ data-lanes = <1 2>;
++ link-frequencies =
++ /bits/ 64 <445500000 297000000>;
++ };
++ };
++
++ fragment@7 {
++ target = <&imx290_0>;
++ __dormant__ {
++ data-lanes = <1 2 3 4>;
++ link-frequencies =
++ /bits/ 64 <222750000 148500000>;
++ };
++ };
++
++ fragment@8 {
++ target = <&csi1_ep>;
++ __overlay__ {
++ data-lanes = <1 2>;
++ };
++ };
++
++ fragment@9 {
++ target = <&csi1_ep>;
++ __dormant__ {
++ data-lanes = <1 2 3 4>;
++ };
++ };
++
++ __overrides__ {
++ 4lane = <0>, "-6+7-8+9";
++ clock-frequency = <&imx290_clk>,"clock-frequency:0",
++ <&imx290>,"clock-frequency:0";
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-0837-vc4_hdmi-Set-HD_CTL_WHOLSMP-and-HD_CTL_CHALIGN_SET.patch b/target/linux/bcm27xx/patches-5.4/950-0837-vc4_hdmi-Set-HD_CTL_WHOLSMP-and-HD_CTL_CHALIGN_SET.patch
new file mode 100644
index 0000000000..859a560bba
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0837-vc4_hdmi-Set-HD_CTL_WHOLSMP-and-HD_CTL_CHALIGN_SET.patch
@@ -0,0 +1,38 @@
+From c69a53be3b5f6f7cba0ac6a5461d4f342f7e9c41 Mon Sep 17 00:00:00 2001
+From: Dom Cobley <popcornmix@gmail.com>
+Date: Tue, 23 Jun 2020 18:37:01 +0100
+Subject: [PATCH] vc4_hdmi: Set HD_CTL_WHOLSMP and HD_CTL_CHALIGN_SET
+
+Symptom is random switching of speakers when using multichannel.
+
+Repeatedly running speakertest -c8 occasionally starts with
+channels jumbled. This is fixed with HD_CTL_WHOLSMP.
+
+The other bit looks beneficial and apears harmless in testing so
+I'd suggest adding it too.
+
+Documentation says: HD_CTL_WHILSMP_SET
+Wait for whole sample. When this bit is set MAI transmit will start
+only when there is at least one whole sample available in the fifo.
+
+Documentation says: HD_CTL_CHALIGN_SET
+Channel Align When Overflow. This bit is used to realign the audio channels in case of an overflow.
+If this bit is set, after the detection of an overflow, equal amount of dummy words to the missing
+words will be written to fifo, filling up the broken sample and maintaining alignment.
+
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -1002,6 +1002,8 @@ static int vc4_hdmi_audio_trigger(struct
+ HDMI_WRITE(HDMI_MAI_CTL,
+ VC4_SET_FIELD(vc4_hdmi->audio.channels,
+ VC4_HD_MAI_CTL_CHNUM) |
++ VC4_HD_MAI_CTL_WHOLSMP |
++ VC4_HD_MAI_CTL_CHALIGN |
+ VC4_HD_MAI_CTL_ENABLE);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
diff --git a/target/linux/bcm27xx/patches-5.4/950-0838-staging-vc04_services-isp-Fixup-g-s_selection-implem.patch b/target/linux/bcm27xx/patches-5.4/950-0838-staging-vc04_services-isp-Fixup-g-s_selection-implem.patch
new file mode 100644
index 0000000000..fd24c87bc3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0838-staging-vc04_services-isp-Fixup-g-s_selection-implem.patch
@@ -0,0 +1,129 @@
+From 7ec008222fcb4682fa2cfdbb62e657bf98950ec5 Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Tue, 19 May 2020 15:56:47 +0100
+Subject: [PATCH] staging: vc04_services: isp: Fixup g/s_selection
+ implementation
+
+Add V4L2_SEL_TGT_CROP_DEFAULT and V4L2_SEL_TGT_CROP_BOUND targets.
+Disable the appropriate ioctls for the meta capture nodes - this now
+passes v4l2-compliance tests.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ .../bcm2835-isp/bcm2835-v4l2-isp.c | 84 ++++++++++++-------
+ 1 file changed, 55 insertions(+), 29 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
+@@ -1006,15 +1006,32 @@ static int bcm2835_isp_node_s_selection(
+ if (!s->r.width || !s->r.height)
+ return -EINVAL;
+
+- /* Adjust the crop window if goes outside the frame dimensions. */
+- s->r.left = min((unsigned int)max(s->r.left, 0),
+- node->q_data.width - MIN_DIM);
+- s->r.top = min((unsigned int)max(s->r.top, 0),
+- node->q_data.height - MIN_DIM);
+- s->r.width = max(min(s->r.width, node->q_data.width - s->r.left),
+- MIN_DIM);
+- s->r.height = max(min(s->r.height, node->q_data.height - s->r.top),
+- MIN_DIM);
++ /* We can only set crop on the input. */
++ switch (s->target) {
++ case V4L2_SEL_TGT_CROP:
++ /*
++ * Adjust the crop window if it goes outside of the frame
++ * dimensions.
++ */
++ s->r.left = min((unsigned int)max(s->r.left, 0),
++ node->q_data.width - MIN_DIM);
++ s->r.top = min((unsigned int)max(s->r.top, 0),
++ node->q_data.height - MIN_DIM);
++ s->r.width = max(min(s->r.width,
++ node->q_data.width - s->r.left), MIN_DIM);
++ s->r.height = max(min(s->r.height,
++ node->q_data.height - s->r.top), MIN_DIM);
++ break;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ /* Default (i.e. no) crop window. */
++ s->r.left = 0;
++ s->r.top = 0;
++ s->r.width = node->q_data.width;
++ s->r.height = node->q_data.height;
++ break;
++ default:
++ return -EINVAL;
++ }
+
+ crop.rect.x = s->r.left;
+ crop.rect.y = s->r.top;
+@@ -1029,33 +1046,40 @@ static int bcm2835_isp_node_s_selection(
+ static int bcm2835_isp_node_g_selection(struct file *file, void *fh,
+ struct v4l2_selection *s)
+ {
++ struct mmal_parameter_crop crop;
+ struct bcm2835_isp_node *node = video_drvdata(file);
+- struct bcm2835_isp_dev *dev = node_get_dev(node);
+ struct vchiq_mmal_port *port = get_port_data(node);
+- struct mmal_parameter_crop crop;
++ struct bcm2835_isp_dev *dev = node_get_dev(node);
+ u32 crop_size = sizeof(crop);
+ int ret;
+
+- /* This return value is required for V4L2 compliance. */
+- if (node_is_stats(node))
+- return -ENOTTY;
+-
+ /* We can only return out an input crop. */
+- if (s->target != V4L2_SEL_TGT_CROP)
+- return -EINVAL;
+-
+- ret = vchiq_mmal_port_parameter_get(dev->mmal_instance, port,
+- MMAL_PARAMETER_CROP,
+- &crop, &crop_size);
+- if (!ret)
+- return -EINVAL;
+-
+- s->r.left = crop.rect.x;
+- s->r.top = crop.rect.y;
+- s->r.width = crop.rect.width;
+- s->r.height = crop.rect.height;
++ switch (s->target) {
++ case V4L2_SEL_TGT_CROP:
++ ret = vchiq_mmal_port_parameter_get(dev->mmal_instance, port,
++ MMAL_PARAMETER_CROP,
++ &crop, &crop_size);
++ if (!ret) {
++ s->r.left = crop.rect.x;
++ s->r.top = crop.rect.y;
++ s->r.width = crop.rect.width;
++ s->r.height = crop.rect.height;
++ }
++ break;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ /* Default (i.e. no) crop window. */
++ s->r.left = 0;
++ s->r.top = 0;
++ s->r.width = node->q_data.width;
++ s->r.height = node->q_data.height;
++ ret = 0;
++ break;
++ default:
++ ret = -EINVAL;
++ }
+
+- return 0;
++ return ret;
+ }
+
+ static int bcm3285_isp_subscribe_event(struct v4l2_fh *fh,
+@@ -1218,6 +1242,8 @@ static int register_node(struct bcm2835_
+ node->vfl_dir = VFL_DIR_RX;
+ node->name = "stats";
+ v4l2_disable_ioctl(&node->vfd, VIDIOC_S_CTRL);
++ v4l2_disable_ioctl(&node->vfd, VIDIOC_S_SELECTION);
++ v4l2_disable_ioctl(&node->vfd, VIDIOC_G_SELECTION);
+ break;
+ }
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0839-staging-vc04_services-isp-Reorder-operations-during-.patch b/target/linux/bcm27xx/patches-5.4/950-0839-staging-vc04_services-isp-Reorder-operations-during-.patch
new file mode 100644
index 0000000000..3300ed4686
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0839-staging-vc04_services-isp-Reorder-operations-during-.patch
@@ -0,0 +1,92 @@
+From af066bde5a442efd50868ffed1aad30190400c91 Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Tue, 19 May 2020 15:57:08 +0100
+Subject: [PATCH] staging: vc04_services: isp: Reorder operations
+ during device probe
+
+Register the video node at the end of the probe, swapping order with
+registering the controls.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ .../bcm2835-isp/bcm2835-v4l2-isp.c | 48 ++++++++++++-------
+ 1 file changed, 32 insertions(+), 16 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
+@@ -1295,21 +1295,6 @@ static int register_node(struct bcm2835_
+ }
+ node->queue_init = true;
+
+- /* Define the device names */
+- snprintf(vfd->name, sizeof(node->vfd.name), "%s-%s%d", BCM2835_ISP_NAME,
+- node->name, node->id);
+-
+- ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr + index);
+- if (ret) {
+- v4l2_err(&dev->v4l2_dev,
+- "Failed to register video %s[%d] device node\n",
+- node->name, node->id);
+- return ret;
+- }
+-
+- node->registered = true;
+- video_set_drvdata(vfd, node);
+-
+ /* Set some controls and defaults, but only on the VIDEO_OUTPUT node. */
+ if (node_is_output(node)) {
+ unsigned int i;
+@@ -1324,7 +1309,12 @@ static int register_node(struct bcm2835_
+ .step = 1,
+ };
+
+- v4l2_ctrl_handler_init(&dev->ctrl_handler, 4);
++ ret = v4l2_ctrl_handler_init(&dev->ctrl_handler, 12);
++ if (ret) {
++ v4l2_err(&dev->v4l2_dev, "ctrl_handler init failed (%d)\n",
++ ret);
++ return ret;
++ }
+
+ dev->r_gain = 1000;
+ dev->b_gain = 1000;
+@@ -1350,13 +1340,39 @@ static int register_node(struct bcm2835_
+ }
+
+ node->vfd.ctrl_handler = &dev->ctrl_handler;
++ if (dev->ctrl_handler.error) {
++ ret = dev->ctrl_handler.error;
++ v4l2_err(&dev->v4l2_dev, "controls init failed (%d)\n",
++ ret);
++ v4l2_ctrl_handler_free(&dev->ctrl_handler);
++ goto ctrl_cleanup;
++ }
+ }
+
++ /* Define the device names */
++ snprintf(vfd->name, sizeof(node->vfd.name), "%s-%s%d", BCM2835_ISP_NAME,
++ node->name, node->id);
++
++ ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr + index);
++ if (ret) {
++ v4l2_err(&dev->v4l2_dev,
++ "Failed to register video %s[%d] device node\n",
++ node->name, node->id);
++ goto ctrl_cleanup;
++ }
++
++ node->registered = true;
++ video_set_drvdata(vfd, node);
++
+ v4l2_info(&dev->v4l2_dev,
+ "Device node %s[%d] registered as /dev/video%d\n",
+ node->name, node->id, vfd->num);
+
+ return 0;
++
++ctrl_cleanup:
++ v4l2_ctrl_handler_free(&dev->ctrl_handler);
++ return ret;
+ }
+
+ /* Unregister one of the /dev/video<N> nodes associated with the ISP. */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0840-uapi-bcm2835-isp-Fixups-for-bcm2835-isp-uapi-structu.patch b/target/linux/bcm27xx/patches-5.4/950-0840-uapi-bcm2835-isp-Fixups-for-bcm2835-isp-uapi-structu.patch
new file mode 100644
index 0000000000..e3ee0d96d7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0840-uapi-bcm2835-isp-Fixups-for-bcm2835-isp-uapi-structu.patch
@@ -0,0 +1,34 @@
+From b1a21b378ea123942db1d07007a040c5e89b23aa Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Tue, 19 May 2020 15:57:23 +0100
+Subject: [PATCH] uapi: bcm2835-isp: Fixups for bcm2835-isp uapi
+ structures
+
+Rename pad_[] to padding[].
+struct bcm2835_isp_rational.den is now unsigned.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ include/uapi/linux/bcm2835-isp.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/include/uapi/linux/bcm2835-isp.h
++++ b/include/uapi/linux/bcm2835-isp.h
+@@ -46,7 +46,7 @@
+ */
+ struct bcm2835_isp_rational {
+ __s32 num;
+- __s32 den;
++ __u32 den;
+ };
+
+ /**
+@@ -140,7 +140,7 @@ struct bcm2835_isp_black_level {
+ __u16 black_level_r;
+ __u16 black_level_g;
+ __u16 black_level_b;
+- __u8 pad_[2]; /* Unused */
++ __u8 padding[2]; /* Unused */
+ };
+
+ /**
diff --git a/target/linux/bcm27xx/patches-5.4/950-0841-ARM-dts-Add-Bluetooth-nodes-for-Raspberry-Pi.patch b/target/linux/bcm27xx/patches-5.4/950-0841-ARM-dts-Add-Bluetooth-nodes-for-Raspberry-Pi.patch
new file mode 100644
index 0000000000..fd66e6590d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0841-ARM-dts-Add-Bluetooth-nodes-for-Raspberry-Pi.patch
@@ -0,0 +1,283 @@
+From c46a59c99e53ab41096afcf7f7879bb12769346b Mon Sep 17 00:00:00 2001
+From: Maxim Mikityanskiy <maxtram95@gmail.com>
+Date: Sat, 27 Jun 2020 13:08:26 +0300
+Subject: [PATCH] ARM: dts: Add Bluetooth nodes for Raspberry Pi
+
+Add device tree nodes for Bluetooth on supported Raspberry Pi boards.
+It's disabled by default and can be enabled by `krnbt=on` dtparam. It's
+an alternative way of configuring Bluetooth, as compared to hciattach or
+btattach. When the dtparam is enabled, the Bluetooth driver is probed
+automatically and doesn't require any additional bring-up scripts.
+
+Note that Raspberry Pi 3 B rev 1.2 doesn't have the required hardware
+flow control pins of UART0 connected to the Bluetooth module, so the
+user should decrease the baudrate by passing `krnbt_baudrate=921600`
+dtparam to make it more stable. It resembles the behavior of the btuart
+script from Raspbian.
+
+The miniuart-bt overlay was modified to support Bluetooth probing with
+device tree, too. It's disabled by default and can be enabled by
+`krnbt=on` parameter of the miniuart-bt overlay.
+
+Signed-off-by: Maxim Mikityanskiy <maxtram95@gmail.com>
+---
+ arch/arm/boot/dts/bcm2708-rpi-bt.dtsi | 26 +++++++++++++++++++
+ arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 1 +
+ arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 1 +
+ arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 1 +
+ arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 3 +--
+ arch/arm/boot/dts/bcm271x-rpi-bt.dtsi | 26 +++++++++++++++++++
+ arch/arm/boot/dts/overlays/README | 12 +++++++--
+ .../boot/dts/overlays/disable-bt-overlay.dts | 13 ++++++++--
+ .../boot/dts/overlays/miniuart-bt-overlay.dts | 21 ++++++++++++---
+ 9 files changed, 94 insertions(+), 10 deletions(-)
+ create mode 100644 arch/arm/boot/dts/bcm2708-rpi-bt.dtsi
+ create mode 100644 arch/arm/boot/dts/bcm271x-rpi-bt.dtsi
+
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm2708-rpi-bt.dtsi
+@@ -0,0 +1,26 @@
++// SPDX-License-Identifier: GPL-2.0
++
++&uart0 {
++ bt: bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ max-speed = <3000000>;
++ shutdown-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>;
++ status = "disabled";
++ };
++};
++
++&uart1 {
++ minibt: bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ max-speed = <460800>;
++ shutdown-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>;
++ status = "disabled";
++ };
++};
++
++/ {
++ __overrides__ {
++ krnbt = <&bt>,"status";
++ krnbt_baudrate = <&bt>,"max-speed:0";
++ };
++};
+--- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts
+@@ -4,6 +4,7 @@
+ #include "bcm2708-rpi.dtsi"
+ #include "bcm283x-rpi-csi1-2lane.dtsi"
+ #include "bcm283x-rpi-i2c0mux_0_28.dtsi"
++#include "bcm2708-rpi-bt.dtsi"
+
+ / {
+ compatible = "raspberrypi,model-zero-w", "brcm,bcm2835";
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts
+@@ -5,6 +5,7 @@
+ #include "bcm283x-rpi-lan7515.dtsi"
+ #include "bcm283x-rpi-csi1-2lane.dtsi"
+ #include "bcm283x-rpi-i2c0mux_0_44.dtsi"
++#include "bcm271x-rpi-bt.dtsi"
+
+ / {
+ compatible = "raspberrypi,3-model-b-plus", "brcm,bcm2837";
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
+@@ -5,6 +5,7 @@
+ #include "bcm283x-rpi-smsc9514.dtsi"
+ #include "bcm283x-rpi-csi1-2lane.dtsi"
+ #include "bcm283x-rpi-i2c0mux_0_44.dtsi"
++#include "bcm271x-rpi-bt.dtsi"
+
+ / {
+ compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
+--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+@@ -182,6 +182,7 @@
+ // Downstream rpi- changes
+
+ #include "bcm270x.dtsi"
++#include "bcm271x-rpi-bt.dtsi"
+
+ / {
+ soc {
+@@ -250,8 +251,6 @@
+ &uart0 {
+ pinctrl-0 = <&uart0_pins &bt_pins>;
+ status = "okay";
+-
+- /delete-node/ bluetooth;
+ };
+
+ &uart1 {
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm271x-rpi-bt.dtsi
+@@ -0,0 +1,26 @@
++// SPDX-License-Identifier: GPL-2.0
++
++&uart0 {
++ bt: bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ max-speed = <3000000>;
++ shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
++ status = "disabled";
++ };
++};
++
++&uart1 {
++ minibt: bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ max-speed = <460800>;
++ shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
++ status = "disabled";
++ };
++};
++
++/ {
++ __overrides__ {
++ krnbt = <&bt>,"status";
++ krnbt_baudrate = <&bt>,"max-speed:0";
++ };
++};
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -162,6 +162,13 @@ Params:
+ i2s Set to "on" to enable the i2s interface
+ (default "off")
+
++ krnbt Set to "on" to enable autoprobing of Bluetooth
++ driver without need of hciattach/btattach
++ (default "off")
++
++ krnbt_baudrate Set the baudrate of the PL011 UART when used
++ with krnbt=on
++
+ spi Set to "on" to enable the spi interfaces
+ (default "off")
+
+@@ -1764,8 +1771,9 @@ Info: Switch the onboard Bluetooth fun
+ in which case use /dev/serial1 instead because it will always be
+ correct. Furthermore, you must also set core_freq and core_freq_min to
+ the same value in config.txt or the miniuart will not work.
+-Load: dtoverlay=miniuart-bt
+-Params: <None>
++Load: dtoverlay=miniuart-bt,<param>=<val>
++Params: krnbt Set to "on" to enable autoprobing of Bluetooth
++ driver without need of hciattach/btattach
+
+
+ Name: mmc
+--- a/arch/arm/boot/dts/overlays/disable-bt-overlay.dts
++++ b/arch/arm/boot/dts/overlays/disable-bt-overlay.dts
+@@ -8,6 +8,8 @@
+ sudo systemctl disable hciuart
+ */
+
++#include <dt-bindings/gpio/gpio.h>
++
+ /{
+ compatible = "brcm,bcm2835";
+
+@@ -28,6 +30,13 @@
+ };
+
+ fragment@2 {
++ target = <&bt>;
++ __overlay__ {
++ status = "disabled";
++ };
++ };
++
++ fragment@3 {
+ target = <&uart0_pins>;
+ __overlay__ {
+ brcm,pins;
+@@ -36,7 +45,7 @@
+ };
+ };
+
+- fragment@3 {
++ fragment@4 {
+ target = <&bt_pins>;
+ __overlay__ {
+ brcm,pins;
+@@ -45,7 +54,7 @@
+ };
+ };
+
+- fragment@4 {
++ fragment@5 {
+ target-path = "/aliases";
+ __overlay__ {
+ serial0 = "/soc/serial@7e201000";
+--- a/arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts
++++ b/arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts
+@@ -15,6 +15,8 @@
+ this overlay is used.
+ */
+
++#include <dt-bindings/gpio/gpio.h>
++
+ /{
+ compatible = "brcm,bcm2835";
+
+@@ -28,6 +30,13 @@
+ };
+
+ fragment@1 {
++ target = <&bt>;
++ __overlay__ {
++ status = "disabled";
++ };
++ };
++
++ fragment@2 {
+ target = <&uart1>;
+ __overlay__ {
+ pinctrl-names = "default";
+@@ -36,7 +45,7 @@
+ };
+ };
+
+- fragment@2 {
++ fragment@3 {
+ target = <&uart0_pins>;
+ __overlay__ {
+ brcm,pins;
+@@ -45,7 +54,7 @@
+ };
+ };
+
+- fragment@3 {
++ fragment@4 {
+ target = <&uart1_pins>;
+ __overlay__ {
+ brcm,pins = <32 33>;
+@@ -54,7 +63,7 @@
+ };
+ };
+
+- fragment@4 {
++ fragment@5 {
+ target = <&gpio>;
+ __overlay__ {
+ fake_bt_cts: fake_bt_cts {
+@@ -64,11 +73,15 @@
+ };
+ };
+
+- fragment@5 {
++ fragment@6 {
+ target-path = "/aliases";
+ __overlay__ {
+ serial0 = "/soc/serial@7e201000";
+ serial1 = "/soc/serial@7e215040";
+ };
+ };
++
++ __overrides__ {
++ krnbt = <&minibt>,"status";
++ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0842-drm-vc4-Allow-interlaced-HDMI-modes-from-FKMS.patch b/target/linux/bcm27xx/patches-5.4/950-0842-drm-vc4-Allow-interlaced-HDMI-modes-from-FKMS.patch
new file mode 100644
index 0000000000..8cb85316c6
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0842-drm-vc4-Allow-interlaced-HDMI-modes-from-FKMS.patch
@@ -0,0 +1,37 @@
+From 354bf89fd678a6da6256a6ac37440c27c3b62e80 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 30 Jun 2020 18:04:13 +0100
+Subject: [PATCH] drm/vc4: Allow interlaced HDMI modes from FKMS.
+
+Having checked the firmware handling for interlaced modes,
+it appears to be possible to support interlaced modes on
+HDMI without adverse side effects, so do so.
+
+https://github.com/raspberrypi/linux/issues/3694
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -936,6 +936,9 @@ static void vc4_crtc_mode_set_nofb(struc
+ break;
+ }
+
++ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
++ mb.timings.flags |= TIMINGS_FLAGS_INTERLACE;
++
+ mb.timings.video_id_code = frame.avi.video_code;
+
+ if (!vc4_encoder->hdmi_monitor) {
+@@ -1632,7 +1635,7 @@ vc4_fkms_connector_init(struct drm_devic
+ DRM_MODE_CONNECTOR_HDMIA);
+ drm_connector_helper_add(connector,
+ &vc4_fkms_connector_helper_funcs);
+- connector->interlace_allowed = 0;
++ connector->interlace_allowed = 1;
+ }
+
+ ret = drm_mode_create_tv_margin_properties(dev);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0843-serial-8250-bcm2835aux-defer-if-clock-is-zero.patch b/target/linux/bcm27xx/patches-5.4/950-0843-serial-8250-bcm2835aux-defer-if-clock-is-zero.patch
new file mode 100644
index 0000000000..b421ba9cdc
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0843-serial-8250-bcm2835aux-defer-if-clock-is-zero.patch
@@ -0,0 +1,28 @@
+From 80163961af8e31a2045271c5a12adaae620445e1 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 2 Jul 2020 13:53:20 +0100
+Subject: [PATCH] serial: 8250: bcm2835aux - defer if clock is zero
+
+See: https://github.com/raspberrypi/linux/issues/3700
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/tty/serial/8250/8250_bcm2835aux.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/tty/serial/8250/8250_bcm2835aux.c
++++ b/drivers/tty/serial/8250/8250_bcm2835aux.c
+@@ -92,6 +92,13 @@ static int bcm2835aux_serial_probe(struc
+ */
+ data->uart.port.uartclk = clk_get_rate(data->clk) * 2;
+
++ /* The clock is only queried at probe time, which means we get one shot
++ * at this. A zero clock is never going to work and is almost certainly
++ * due to a parent not being ready, so prefer to defer.
++ */
++ if (!data->uart.port.uartclk)
++ return -EPROBE_DEFER;
++
+ /* register the port */
+ ret = serial8250_register_8250_port(&data->uart);
+ if (ret < 0) {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0844-media-v4l-Add-14-bit-raw-bayer-pixel-formats.patch b/target/linux/bcm27xx/patches-5.4/950-0844-media-v4l-Add-14-bit-raw-bayer-pixel-formats.patch
new file mode 100644
index 0000000000..1bb9a932a3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0844-media-v4l-Add-14-bit-raw-bayer-pixel-formats.patch
@@ -0,0 +1,151 @@
+From 59a535539277240c4bdbb9c21bc07c8b586b2c3a Mon Sep 17 00:00:00 2001
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+Date: Mon, 24 Feb 2020 18:52:20 +0100
+Subject: [PATCH] media: v4l: Add 14-bit raw bayer pixel formats
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit d12127ed0e18192491c2508caae45bb19c2f8fdd upstream.
+
+The formats added by this patch are:
+
+ V4L2_PIX_FMT_SBGGR14
+ V4L2_PIX_FMT_SGBRG14
+ V4L2_PIX_FMT_SGRBG14
+ V4L2_PIX_FMT_SRGGB14
+
+Signed-off-by: Jouni Ukkonen <jouni.ukkonen@intel.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+[dg@emlix.com: rebased onto current media_tree]
+Signed-off-by: Daniel Glöckner <dg@emlix.com>
+Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+---
+ Documentation/media/uapi/v4l/pixfmt-bayer.rst | 1 +
+ .../media/uapi/v4l/pixfmt-srggb14.rst | 82 +++++++++++++++++++
+ drivers/media/v4l2-core/v4l2-ioctl.c | 4 +
+ include/uapi/linux/videodev2.h | 4 +
+ 4 files changed, 91 insertions(+)
+ create mode 100644 Documentation/media/uapi/v4l/pixfmt-srggb14.rst
+
+--- a/Documentation/media/uapi/v4l/pixfmt-bayer.rst
++++ b/Documentation/media/uapi/v4l/pixfmt-bayer.rst
+@@ -34,5 +34,6 @@ orders. See also `the Wikipedia article
+ pixfmt-srggb10-ipu3
+ pixfmt-srggb12
+ pixfmt-srggb12p
++ pixfmt-srggb14
+ pixfmt-srggb14p
+ pixfmt-srggb16
+--- /dev/null
++++ b/Documentation/media/uapi/v4l/pixfmt-srggb14.rst
+@@ -0,0 +1,82 @@
++.. Permission is granted to copy, distribute and/or modify this
++.. document under the terms of the GNU Free Documentation License,
++.. Version 1.1 or any later version published by the Free Software
++.. Foundation, with no Invariant Sections, no Front-Cover Texts
++.. and no Back-Cover Texts. A copy of the license is included at
++.. Documentation/media/uapi/fdl-appendix.rst.
++..
++.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
++
++.. _V4L2-PIX-FMT-SRGGB14:
++.. _v4l2-pix-fmt-sbggr14:
++.. _v4l2-pix-fmt-sgbrg14:
++.. _v4l2-pix-fmt-sgrbg14:
++
++
++***************************************************************************************************************************
++V4L2_PIX_FMT_SRGGB14 ('RG14'), V4L2_PIX_FMT_SGRBG14 ('GR14'), V4L2_PIX_FMT_SGBRG14 ('GB14'), V4L2_PIX_FMT_SBGGR14 ('BG14'),
++***************************************************************************************************************************
++
++
++14-bit Bayer formats expanded to 16 bits
++
++
++Description
++===========
++
++These four pixel formats are raw sRGB / Bayer formats with 14 bits per
++colour. Each sample is stored in a 16-bit word, with two unused high
++bits filled with zeros. Each n-pixel row contains n/2 green samples
++and n/2 blue or red samples, with alternating red and blue rows. Bytes
++are stored in memory in little endian order. They are conventionally
++described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an
++example of a small V4L2_PIX_FMT_SBGGR14 image:
++
++**Byte Order.**
++Each cell is one byte, the two most significant bits in the high bytes are
++zero.
++
++
++
++.. flat-table::
++ :header-rows: 0
++ :stub-columns: 0
++ :widths: 2 1 1 1 1 1 1 1 1
++
++
++ * - start + 0:
++ - B\ :sub:`00low`
++ - B\ :sub:`00high`
++ - G\ :sub:`01low`
++ - G\ :sub:`01high`
++ - B\ :sub:`02low`
++ - B\ :sub:`02high`
++ - G\ :sub:`03low`
++ - G\ :sub:`03high`
++ * - start + 8:
++ - G\ :sub:`10low`
++ - G\ :sub:`10high`
++ - R\ :sub:`11low`
++ - R\ :sub:`11high`
++ - G\ :sub:`12low`
++ - G\ :sub:`12high`
++ - R\ :sub:`13low`
++ - R\ :sub:`13high`
++ * - start + 16:
++ - B\ :sub:`20low`
++ - B\ :sub:`20high`
++ - G\ :sub:`21low`
++ - G\ :sub:`21high`
++ - B\ :sub:`22low`
++ - B\ :sub:`22high`
++ - G\ :sub:`23low`
++ - G\ :sub:`23high`
++ * - start + 24:
++ - G\ :sub:`30low`
++ - G\ :sub:`30high`
++ - R\ :sub:`31low`
++ - R\ :sub:`31high`
++ - G\ :sub:`32low`
++ - G\ :sub:`32high`
++ - R\ :sub:`33low`
++ - R\ :sub:`33high`
+--- a/drivers/media/v4l2-core/v4l2-ioctl.c
++++ b/drivers/media/v4l2-core/v4l2-ioctl.c
+@@ -1298,6 +1298,10 @@ static void v4l_fill_fmtdesc(struct v4l2
+ case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break;
+ case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break;
+ case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB Packed"; break;
++ case V4L2_PIX_FMT_SBGGR14: descr = "14-bit Bayer BGBG/GRGR"; break;
++ case V4L2_PIX_FMT_SGBRG14: descr = "14-bit Bayer GBGB/RGRG"; break;
++ case V4L2_PIX_FMT_SGRBG14: descr = "14-bit Bayer GRGR/BGBG"; break;
++ case V4L2_PIX_FMT_SRGGB14: descr = "14-bit Bayer RGRG/GBGB"; break;
+ case V4L2_PIX_FMT_SBGGR14P: descr = "14-bit Bayer BGBG/GRGR Packed"; break;
+ case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG Packed"; break;
+ case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break;
+--- a/include/uapi/linux/videodev2.h
++++ b/include/uapi/linux/videodev2.h
+@@ -666,6 +666,10 @@ struct v4l2_pix_format {
+ #define V4L2_PIX_FMT_SGBRG12P v4l2_fourcc('p', 'G', 'C', 'C')
+ #define V4L2_PIX_FMT_SGRBG12P v4l2_fourcc('p', 'g', 'C', 'C')
+ #define V4L2_PIX_FMT_SRGGB12P v4l2_fourcc('p', 'R', 'C', 'C')
++#define V4L2_PIX_FMT_SBGGR14 v4l2_fourcc('B', 'G', '1', '4') /* 14 BGBG.. GRGR.. */
++#define V4L2_PIX_FMT_SGBRG14 v4l2_fourcc('G', 'B', '1', '4') /* 14 GBGB.. RGRG.. */
++#define V4L2_PIX_FMT_SGRBG14 v4l2_fourcc('G', 'R', '1', '4') /* 14 GRGR.. BGBG.. */
++#define V4L2_PIX_FMT_SRGGB14 v4l2_fourcc('R', 'G', '1', '4') /* 14 RGRG.. GBGB.. */
+ /* 14bit raw bayer packed, 7 bytes for every 4 pixels */
+ #define V4L2_PIX_FMT_SBGGR14P v4l2_fourcc('p', 'B', 'E', 'E')
+ #define V4L2_PIX_FMT_SGBRG14P v4l2_fourcc('p', 'G', 'E', 'E')
diff --git a/target/linux/bcm27xx/patches-5.4/950-0845-media-v4l-Add-14-bit-raw-greyscale-pixel-format.patch b/target/linux/bcm27xx/patches-5.4/950-0845-media-v4l-Add-14-bit-raw-greyscale-pixel-format.patch
new file mode 100644
index 0000000000..1910668595
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0845-media-v4l-Add-14-bit-raw-greyscale-pixel-format.patch
@@ -0,0 +1,131 @@
+From 363792f3fff5f4f79e2ac08ccfcc21c05216787a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Daniel=20Gl=C3=B6ckner?= <dg@emlix.com>
+Date: Mon, 24 Feb 2020 18:52:21 +0100
+Subject: [PATCH] media: v4l: Add 14-bit raw greyscale pixel format
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit ae9753a04cfc8e41262605875e531b6ea5e3d0ac upstream.
+
+The new format is called V4L2_PIX_FMT_Y14. Like V4L2_PIX_FMT_Y10 and
+V4L2_PIX_FMT_Y12 it is stored in two bytes per pixel but has only two
+unused bits at the top.
+
+Signed-off-by: Daniel Glöckner <dg@emlix.com>
+Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
+Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+---
+ Documentation/media/uapi/v4l/pixfmt-y14.rst | 72 ++++++++++++++++++++
+ Documentation/media/uapi/v4l/yuv-formats.rst | 1 +
+ drivers/media/v4l2-core/v4l2-ioctl.c | 1 +
+ include/uapi/linux/videodev2.h | 1 +
+ 4 files changed, 75 insertions(+)
+ create mode 100644 Documentation/media/uapi/v4l/pixfmt-y14.rst
+
+--- /dev/null
++++ b/Documentation/media/uapi/v4l/pixfmt-y14.rst
+@@ -0,0 +1,72 @@
++.. Permission is granted to copy, distribute and/or modify this
++.. document under the terms of the GNU Free Documentation License,
++.. Version 1.1 or any later version published by the Free Software
++.. Foundation, with no Invariant Sections, no Front-Cover Texts
++.. and no Back-Cover Texts. A copy of the license is included at
++.. Documentation/media/uapi/fdl-appendix.rst.
++..
++.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
++
++.. _V4L2-PIX-FMT-Y14:
++
++*************************
++V4L2_PIX_FMT_Y14 ('Y14 ')
++*************************
++
++
++Grey-scale image
++
++
++Description
++===========
++
++This is a grey-scale image with a depth of 14 bits per pixel. Pixels are
++stored in 16-bit words with unused high bits padded with 0. The least
++significant byte is stored at lower memory addresses (little-endian).
++
++**Byte Order.**
++Each cell is one byte.
++
++
++
++
++.. flat-table::
++ :header-rows: 0
++ :stub-columns: 0
++
++ * - start + 0:
++ - Y'\ :sub:`00low`
++ - Y'\ :sub:`00high`
++ - Y'\ :sub:`01low`
++ - Y'\ :sub:`01high`
++ - Y'\ :sub:`02low`
++ - Y'\ :sub:`02high`
++ - Y'\ :sub:`03low`
++ - Y'\ :sub:`03high`
++ * - start + 8:
++ - Y'\ :sub:`10low`
++ - Y'\ :sub:`10high`
++ - Y'\ :sub:`11low`
++ - Y'\ :sub:`11high`
++ - Y'\ :sub:`12low`
++ - Y'\ :sub:`12high`
++ - Y'\ :sub:`13low`
++ - Y'\ :sub:`13high`
++ * - start + 16:
++ - Y'\ :sub:`20low`
++ - Y'\ :sub:`20high`
++ - Y'\ :sub:`21low`
++ - Y'\ :sub:`21high`
++ - Y'\ :sub:`22low`
++ - Y'\ :sub:`22high`
++ - Y'\ :sub:`23low`
++ - Y'\ :sub:`23high`
++ * - start + 24:
++ - Y'\ :sub:`30low`
++ - Y'\ :sub:`30high`
++ - Y'\ :sub:`31low`
++ - Y'\ :sub:`31high`
++ - Y'\ :sub:`32low`
++ - Y'\ :sub:`32high`
++ - Y'\ :sub:`33low`
++ - Y'\ :sub:`33high`
+--- a/Documentation/media/uapi/v4l/yuv-formats.rst
++++ b/Documentation/media/uapi/v4l/yuv-formats.rst
+@@ -35,6 +35,7 @@ to brightness information.
+ pixfmt-grey
+ pixfmt-y10
+ pixfmt-y12
++ pixfmt-y14
+ pixfmt-y10b
+ pixfmt-y10p
+ pixfmt-y16
+--- a/drivers/media/v4l2-core/v4l2-ioctl.c
++++ b/drivers/media/v4l2-core/v4l2-ioctl.c
+@@ -1212,6 +1212,7 @@ static void v4l_fill_fmtdesc(struct v4l2
+ case V4L2_PIX_FMT_Y6: descr = "6-bit Greyscale"; break;
+ case V4L2_PIX_FMT_Y10: descr = "10-bit Greyscale"; break;
+ case V4L2_PIX_FMT_Y12: descr = "12-bit Greyscale"; break;
++ case V4L2_PIX_FMT_Y14: descr = "14-bit Greyscale"; break;
+ case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break;
+ case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break;
+ case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break;
+--- a/include/uapi/linux/videodev2.h
++++ b/include/uapi/linux/videodev2.h
+@@ -569,6 +569,7 @@ struct v4l2_pix_format {
+ #define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */
+ #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */
+ #define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */
++#define V4L2_PIX_FMT_Y14 v4l2_fourcc('Y', '1', '4', ' ') /* 14 Greyscale */
+ #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */
+ #define V4L2_PIX_FMT_Y16_BE v4l2_fourcc_be('Y', '1', '6', ' ') /* 16 Greyscale BE */
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0846-media-v4l-Add-1X14-14-bit-greyscale-media-bus-code-d.patch b/target/linux/bcm27xx/patches-5.4/950-0846-media-v4l-Add-1X14-14-bit-greyscale-media-bus-code-d.patch
new file mode 100644
index 0000000000..09c4330157
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0846-media-v4l-Add-1X14-14-bit-greyscale-media-bus-code-d.patch
@@ -0,0 +1,88 @@
+From efc06d6c82d5b6b3ee5dd2bfa7c010f737a0fa49 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Daniel=20Gl=C3=B6ckner?= <dg@emlix.com>
+Date: Mon, 24 Feb 2020 18:52:22 +0100
+Subject: [PATCH] media: v4l: Add 1X14 14-bit greyscale media bus
+ code definition
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit 573a750813459725c6f6fc4bc5779da1fe03238a upstream.
+
+The code is called MEDIA_BUS_FMT_Y14_1X14 and behaves just like
+MEDIA_BUS_FMT_Y12_1X12 with two more bits.
+
+Signed-off-by: Daniel Glöckner <dg@emlix.com>
+Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
+Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+---
+ .../media/uapi/v4l/subdev-formats.rst | 37 +++++++++++++++++++
+ include/uapi/linux/media-bus-format.h | 3 +-
+ 2 files changed, 39 insertions(+), 1 deletion(-)
+
+--- a/Documentation/media/uapi/v4l/subdev-formats.rst
++++ b/Documentation/media/uapi/v4l/subdev-formats.rst
+@@ -5792,6 +5792,43 @@ the following codes.
+ - u\ :sub:`2`
+ - u\ :sub:`1`
+ - u\ :sub:`0`
++ * .. _MEDIA-BUS-FMT-Y14-1X14:
++
++ - MEDIA_BUS_FMT_Y14_1X14
++ - 0x202d
++ -
++ -
++ -
++ -
++ -
++ -
++ -
++ -
++ -
++ -
++ -
++ -
++ -
++ -
++ -
++ -
++ -
++ -
++ -
++ - y\ :sub:`13`
++ - y\ :sub:`12`
++ - y\ :sub:`11`
++ - y\ :sub:`10`
++ - y\ :sub:`9`
++ - y\ :sub:`8`
++ - y\ :sub:`7`
++ - y\ :sub:`6`
++ - y\ :sub:`5`
++ - y\ :sub:`4`
++ - y\ :sub:`3`
++ - y\ :sub:`2`
++ - y\ :sub:`1`
++ - y\ :sub:`0`
+ * .. _MEDIA-BUS-FMT-UYVY8-1X16:
+
+ - MEDIA_BUS_FMT_UYVY8_1X16
+--- a/include/uapi/linux/media-bus-format.h
++++ b/include/uapi/linux/media-bus-format.h
+@@ -64,7 +64,7 @@
+ #define MEDIA_BUS_FMT_RGB121212_1X36 0x1019
+ #define MEDIA_BUS_FMT_RGB161616_1X48 0x101a
+
+-/* YUV (including grey) - next is 0x202d */
++/* YUV (including grey) - next is 0x202e */
+ #define MEDIA_BUS_FMT_Y8_1X8 0x2001
+ #define MEDIA_BUS_FMT_UV8_1X8 0x2015
+ #define MEDIA_BUS_FMT_UYVY8_1_5X8 0x2002
+@@ -86,6 +86,7 @@
+ #define MEDIA_BUS_FMT_VYUY12_2X12 0x201d
+ #define MEDIA_BUS_FMT_YUYV12_2X12 0x201e
+ #define MEDIA_BUS_FMT_YVYU12_2X12 0x201f
++#define MEDIA_BUS_FMT_Y14_1X14 0x202d
+ #define MEDIA_BUS_FMT_UYVY8_1X16 0x200f
+ #define MEDIA_BUS_FMT_VYUY8_1X16 0x2010
+ #define MEDIA_BUS_FMT_YUYV8_1X16 0x2011
diff --git a/target/linux/bcm27xx/patches-5.4/950-0847-media-Add-a-pixel-format-for-MIPI-packed-12bit-luma-.patch b/target/linux/bcm27xx/patches-5.4/950-0847-media-Add-a-pixel-format-for-MIPI-packed-12bit-luma-.patch
new file mode 100644
index 0000000000..b5d407b205
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0847-media-Add-a-pixel-format-for-MIPI-packed-12bit-luma-.patch
@@ -0,0 +1,95 @@
+From 14ed8669ba80f2bb9a5f0d6be51052813d4a75e8 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 7 May 2020 16:59:03 +0100
+Subject: [PATCH] media: Add a pixel format for MIPI packed 12bit
+ luma only.
+
+This is the format used by monochrome 12bit image sensors.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ Documentation/media/uapi/v4l/pixfmt-y12p.rst | 45 ++++++++++++++++++++
+ Documentation/media/uapi/v4l/yuv-formats.rst | 1 +
+ drivers/media/v4l2-core/v4l2-ioctl.c | 1 +
+ include/uapi/linux/videodev2.h | 1 +
+ 4 files changed, 48 insertions(+)
+ create mode 100644 Documentation/media/uapi/v4l/pixfmt-y12p.rst
+
+--- /dev/null
++++ b/Documentation/media/uapi/v4l/pixfmt-y12p.rst
+@@ -0,0 +1,45 @@
++.. Permission is granted to copy, distribute and/or modify this
++.. document under the terms of the GNU Free Documentation License,
++.. Version 1.1 or any later version published by the Free Software
++.. Foundation, with no Invariant Sections, no Front-Cover Texts
++.. and no Back-Cover Texts. A copy of the license is included at
++.. Documentation/media/uapi/fdl-appendix.rst.
++..
++.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
++
++.. _V4L2-PIX-FMT-Y12P:
++
++******************************
++V4L2_PIX_FMT_Y12P ('Y12P')
++******************************
++
++Grey-scale image as a MIPI RAW12 packed array
++
++
++Description
++===========
++
++This is a packed grey-scale image format with a depth of 12 bits per
++pixel. Two consecutive pixels are packed into 3 bytes. The first 2 bytes
++contain the 8 high order bits of the pixels, and the 3rd byte contains the 4
++least significants bits of each pixel, in the same order.
++
++**Byte Order.**
++Each cell is one byte.
++
++.. tabularcolumns:: |p{2.2cm}|p{1.2cm}|p{1.2cm}|p{3.1cm}|
++
++
++.. flat-table::
++ :header-rows: 0
++ :stub-columns: 0
++ :widths: 2 1 1 1
++
++
++ - - start + 0:
++ - Y'\ :sub:`00high`
++ - Y'\ :sub:`01high`
++ - Y'\ :sub:`01low`\ (bits 7--4)
++
++ Y'\ :sub:`00low`\ (bits 3--0)
++
+--- a/Documentation/media/uapi/v4l/yuv-formats.rst
++++ b/Documentation/media/uapi/v4l/yuv-formats.rst
+@@ -35,6 +35,7 @@ to brightness information.
+ pixfmt-grey
+ pixfmt-y10
+ pixfmt-y12
++ pixfmt-y12p
+ pixfmt-y14
+ pixfmt-y10b
+ pixfmt-y10p
+--- a/drivers/media/v4l2-core/v4l2-ioctl.c
++++ b/drivers/media/v4l2-core/v4l2-ioctl.c
+@@ -1217,6 +1217,7 @@ static void v4l_fill_fmtdesc(struct v4l2
+ case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break;
+ case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break;
+ case V4L2_PIX_FMT_Y10P: descr = "10-bit Greyscale (MIPI Packed)"; break;
++ case V4L2_PIX_FMT_Y12P: descr = "12-bit Greyscale (MIPI Packed)"; break;
+ case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break;
+ case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break;
+ case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break;
+--- a/include/uapi/linux/videodev2.h
++++ b/include/uapi/linux/videodev2.h
+@@ -576,6 +576,7 @@ struct v4l2_pix_format {
+ /* Grey bit-packed formats */
+ #define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */
+ #define V4L2_PIX_FMT_Y10P v4l2_fourcc('Y', '1', '0', 'P') /* 10 Greyscale, MIPI RAW10 packed */
++#define V4L2_PIX_FMT_Y12P v4l2_fourcc('Y', '1', '2', 'P') /* 12 Greyscale, MIPI RAW12 packed */
+
+ /* Palette formats */
+ #define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0848-media-Add-a-pixel-format-for-MIPI-packed-14bit-luma-.patch b/target/linux/bcm27xx/patches-5.4/950-0848-media-Add-a-pixel-format-for-MIPI-packed-14bit-luma-.patch
new file mode 100644
index 0000000000..f8b255f15a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0848-media-Add-a-pixel-format-for-MIPI-packed-14bit-luma-.patch
@@ -0,0 +1,104 @@
+From 8c51a9a891458e5d66cfedea84b1a38ceb01b7ae Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 25 Jun 2020 17:51:03 +0100
+Subject: [PATCH] media: Add a pixel format for MIPI packed 14bit
+ luma only.
+
+This is the format used by monochrome 14bit image sensors.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ Documentation/media/uapi/v4l/pixfmt-y14p.rst | 54 ++++++++++++++++++++
+ Documentation/media/uapi/v4l/yuv-formats.rst | 1 +
+ drivers/media/v4l2-core/v4l2-ioctl.c | 1 +
+ include/uapi/linux/videodev2.h | 1 +
+ 4 files changed, 57 insertions(+)
+ create mode 100644 Documentation/media/uapi/v4l/pixfmt-y14p.rst
+
+--- /dev/null
++++ b/Documentation/media/uapi/v4l/pixfmt-y14p.rst
+@@ -0,0 +1,54 @@
++.. Permission is granted to copy, distribute and/or modify this
++.. document under the terms of the GNU Free Documentation License,
++.. Version 1.1 or any later version published by the Free Software
++.. Foundation, with no Invariant Sections, no Front-Cover Texts
++.. and no Back-Cover Texts. A copy of the license is included at
++.. Documentation/media/uapi/fdl-appendix.rst.
++..
++.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
++
++.. _V4L2-PIX-FMT-Y14P:
++
++**************************
++V4L2_PIX_FMT_Y14P ('Y14P')
++**************************
++
++Grey-scale image as a MIPI RAW14 packed array
++
++
++Description
++===========
++
++This is a packed grey-scale image format with a depth of 14 bits per
++pixel. Every four consecutive samples are packed into seven bytes. Each
++of the first four bytes contain the eight high order bits of the pixels,
++and the three following bytes contains the six least significants bits of
++each pixel, in the same order.
++
++**Byte Order.**
++Each cell is one byte.
++
++.. tabularcolumns:: |p{1.8cm}|p{1.0cm}|p{1.0cm}|p{1.0cm}|p{1.1cm}|p{3.3cm}|p{3.3cm}|p{3.3cm}|
++
++.. flat-table::
++ :header-rows: 0
++ :stub-columns: 0
++ :widths: 2 1 1 1 1 3 3 3
++
++
++ - - start + 0:
++ - Y'\ :sub:`00high`
++ - Y'\ :sub:`01high`
++ - Y'\ :sub:`02high`
++ - Y'\ :sub:`03high`
++ - Y'\ :sub:`01low bits 1--0`\ (bits 7--6)
++
++ Y'\ :sub:`00low bits 5--0`\ (bits 5--0)
++
++ - Y'\ :sub:`02low bits 3--0`\ (bits 7--4)
++
++ Y'\ :sub:`01low bits 5--2`\ (bits 3--0)
++
++ - Y'\ :sub:`03low bits 5--0`\ (bits 7--2)
++
++ Y'\ :sub:`02low bits 5--4`\ (bits 1--0)
+--- a/Documentation/media/uapi/v4l/yuv-formats.rst
++++ b/Documentation/media/uapi/v4l/yuv-formats.rst
+@@ -37,6 +37,7 @@ to brightness information.
+ pixfmt-y12
+ pixfmt-y12p
+ pixfmt-y14
++ pixfmt-y14p
+ pixfmt-y10b
+ pixfmt-y10p
+ pixfmt-y16
+--- a/drivers/media/v4l2-core/v4l2-ioctl.c
++++ b/drivers/media/v4l2-core/v4l2-ioctl.c
+@@ -1218,6 +1218,7 @@ static void v4l_fill_fmtdesc(struct v4l2
+ case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break;
+ case V4L2_PIX_FMT_Y10P: descr = "10-bit Greyscale (MIPI Packed)"; break;
+ case V4L2_PIX_FMT_Y12P: descr = "12-bit Greyscale (MIPI Packed)"; break;
++ case V4L2_PIX_FMT_Y14P: descr = "14-bit Greyscale (MIPI Packed)"; break;
+ case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break;
+ case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break;
+ case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break;
+--- a/include/uapi/linux/videodev2.h
++++ b/include/uapi/linux/videodev2.h
+@@ -577,6 +577,7 @@ struct v4l2_pix_format {
+ #define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */
+ #define V4L2_PIX_FMT_Y10P v4l2_fourcc('Y', '1', '0', 'P') /* 10 Greyscale, MIPI RAW10 packed */
+ #define V4L2_PIX_FMT_Y12P v4l2_fourcc('Y', '1', '2', 'P') /* 12 Greyscale, MIPI RAW12 packed */
++#define V4L2_PIX_FMT_Y14P v4l2_fourcc('Y', '1', '4', 'P') /* 14 Greyscale, MIPI RAW12 packed */
+
+ /* Palette formats */
+ #define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0849-staging-vc04_services-isp-Add-support-for-14bit-Baye.patch b/target/linux/bcm27xx/patches-5.4/950-0849-staging-vc04_services-isp-Add-support-for-14bit-Baye.patch
new file mode 100644
index 0000000000..837b6b5d95
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0849-staging-vc04_services-isp-Add-support-for-14bit-Baye.patch
@@ -0,0 +1,75 @@
+From ac6ebed4a0e06b4102831976e826a5986732ed33 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 6 May 2020 18:09:04 +0100
+Subject: [PATCH] staging: vc04_services: isp: Add support for 14bit
+ Bayer
+
+The only thing missing was a set of defines, therefore add them in.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../bcm2835-isp/bcm2835_isp_fmts.h | 37 +++++++++++++++++++
+ .../vc04_services/vchiq-mmal/mmal-encodings.h | 6 +++
+ 2 files changed, 43 insertions(+)
+
+--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h
++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h
+@@ -254,6 +254,43 @@ static const struct bcm2835_isp_fmt supp
+ .colorspace = V4L2_COLORSPACE_RAW,
+ .step_size = 2,
+ }, {
++ /* 14 bit */
++ .fourcc = V4L2_PIX_FMT_SRGGB14P,
++ .depth = 14,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB14P,
++ .size_multiplier_x2 = 2,
++ .colorspace = V4L2_COLORSPACE_RAW,
++ .step_size = 2,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SBGGR14P,
++ .depth = 14,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR14P,
++ .size_multiplier_x2 = 2,
++ .colorspace = V4L2_COLORSPACE_RAW,
++ .step_size = 2,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SGRBG14P,
++ .depth = 14,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG14P,
++ .size_multiplier_x2 = 2,
++ .colorspace = V4L2_COLORSPACE_RAW,
++ .step_size = 2,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SGBRG14P,
++ .depth = 14,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG14P,
++ .size_multiplier_x2 = 2,
++ .colorspace = V4L2_COLORSPACE_RAW,
++ .step_size = 2,
++ }, {
+ /* 16 bit */
+ .fourcc = V4L2_PIX_FMT_SRGGB16,
+ .depth = 16,
+--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h
++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h
+@@ -90,6 +90,12 @@
+ #define MMAL_ENCODING_BAYER_SGBRG12P MMAL_FOURCC('p', 'G', '1', '2')
+ #define MMAL_ENCODING_BAYER_SRGGB12P MMAL_FOURCC('p', 'R', '1', '2')
+
++//14 bit per pixel Bayer formats.
++#define MMAL_ENCODING_BAYER_SBGGR14P MMAL_FOURCC('p', 'B', 'E', 'E')
++#define MMAL_ENCODING_BAYER_SGBRG14P MMAL_FOURCC('p', 'G', 'E', 'E')
++#define MMAL_ENCODING_BAYER_SGRBG14P MMAL_FOURCC('p', 'g', 'E', 'E')
++#define MMAL_ENCODING_BAYER_SRGGB14P MMAL_FOURCC('p', 'R', 'E', 'E')
++
+ /* 16 bit per pixel Bayer formats. */
+ #define MMAL_ENCODING_BAYER_SBGGR16 MMAL_FOURCC('B', 'G', '1', '6')
+ #define MMAL_ENCODING_BAYER_SGBRG16 MMAL_FOURCC('G', 'B', '1', '6')
diff --git a/target/linux/bcm27xx/patches-5.4/950-0850-staging-vc04_services-isp-Add-monochrome-image-forma.patch b/target/linux/bcm27xx/patches-5.4/950-0850-staging-vc04_services-isp-Add-monochrome-image-forma.patch
new file mode 100644
index 0000000000..849417f6ae
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0850-staging-vc04_services-isp-Add-monochrome-image-forma.patch
@@ -0,0 +1,92 @@
+From ef305037fd7423386d3a59b640114bdff67d824f Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 6 May 2020 18:11:14 +0100
+Subject: [PATCH] staging: vc04_services: isp: Add monochrome image
+ formats
+
+Adds support for monochrome image formats in the various
+MIPI packings.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../bcm2835-isp/bcm2835_isp_fmts.h | 52 ++++++++++++++++++-
+ .../vc04_services/vchiq-mmal/mmal-encodings.h | 7 +++
+ 2 files changed, 58 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h
++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h
+@@ -328,7 +328,57 @@ static const struct bcm2835_isp_fmt supp
+ .colorspace = V4L2_COLORSPACE_RAW,
+ .step_size = 2,
+ }, {
+- /* ISP statistics format */
++ /* Monochrome MIPI formats */
++ /* 8 bit */
++ .fourcc = V4L2_PIX_FMT_GREY,
++ .depth = 8,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_GREY,
++ .size_multiplier_x2 = 2,
++ .colorspace = V4L2_COLORSPACE_RAW,
++ .step_size = 2,
++ }, {
++ /* 10 bit */
++ .fourcc = V4L2_PIX_FMT_Y10P,
++ .depth = 10,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_Y10P,
++ .size_multiplier_x2 = 2,
++ .colorspace = V4L2_COLORSPACE_RAW,
++ .step_size = 2,
++ }, {
++ /* 12 bit */
++ .fourcc = V4L2_PIX_FMT_Y12P,
++ .depth = 12,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_Y12P,
++ .size_multiplier_x2 = 2,
++ .colorspace = V4L2_COLORSPACE_RAW,
++ .step_size = 2,
++ }, {
++ /* 14 bit */
++ .fourcc = V4L2_PIX_FMT_Y14P,
++ .depth = 14,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_Y14P,
++ .size_multiplier_x2 = 2,
++ .colorspace = V4L2_COLORSPACE_RAW,
++ .step_size = 2,
++ }, {
++ /* 16 bit */
++ .fourcc = V4L2_PIX_FMT_Y16,
++ .depth = 16,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_Y16,
++ .size_multiplier_x2 = 2,
++ .colorspace = V4L2_COLORSPACE_RAW,
++ .step_size = 2,
++ }, {
+ .fourcc = V4L2_META_FMT_BCM2835_ISP_STATS,
+ .mmal_fmt = MMAL_ENCODING_BRCM_STATS,
+ /* The rest are not valid fields for stats. */
+--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h
++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h
+@@ -102,6 +102,13 @@
+ #define MMAL_ENCODING_BAYER_SGRBG16 MMAL_FOURCC('G', 'R', '1', '6')
+ #define MMAL_ENCODING_BAYER_SRGGB16 MMAL_FOURCC('R', 'G', '1', '6')
+
++/* MIPI packed monochrome images */
++#define MMAL_ENCODING_GREY MMAL_FOURCC('G', 'R', 'E', 'Y')
++#define MMAL_ENCODING_Y10P MMAL_FOURCC('Y', '1', '0', 'P')
++#define MMAL_ENCODING_Y12P MMAL_FOURCC('Y', '1', '2', 'P')
++#define MMAL_ENCODING_Y14P MMAL_FOURCC('Y', '1', '4', 'P')
++#define MMAL_ENCODING_Y16 MMAL_FOURCC('Y', '1', '6', ' ')
++
+ /** An EGL image handle
+ */
+ #define MMAL_ENCODING_EGL_IMAGE MMAL_FOURCC('E', 'G', 'L', 'I')
diff --git a/target/linux/bcm27xx/patches-5.4/950-0851-staging-vc04_services-isp-Increase-the-number-of-sup.patch b/target/linux/bcm27xx/patches-5.4/950-0851-staging-vc04_services-isp-Increase-the-number-of-sup.patch
new file mode 100644
index 0000000000..ebf16db9ae
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0851-staging-vc04_services-isp-Increase-the-number-of-sup.patch
@@ -0,0 +1,29 @@
+From 9b0b99ee3711846203d6f2500925e8b463fbeb8e Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 6 May 2020 18:24:34 +0100
+Subject: [PATCH] staging: vc04_services: isp: Increase the number of
+ supported formats expected
+
+The ISP now supports 47 different input formats, therefore increase the
+array size for the number expected.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
+@@ -1134,10 +1134,10 @@ static const struct v4l2_ioctl_ops bcm28
+ * Size of the array to provide to the VPU when asking for the list of supported
+ * formats.
+ *
+- * The ISP component currently advertises 33 input formats, so add a small
++ * The ISP component currently advertises 44 input formats, so add a small
+ * overhead on that.
+ */
+-#define MAX_SUPPORTED_ENCODINGS 40
++#define MAX_SUPPORTED_ENCODINGS 50
+
+ /* Populate node->supported_fmts with the formats supported by those ports. */
+ static int bcm2835_isp_get_supported_fmts(struct bcm2835_isp_node *node)
diff --git a/target/linux/bcm27xx/patches-5.4/950-0852-staging-vc04_services-codec-Increase-the-number-of-s.patch b/target/linux/bcm27xx/patches-5.4/950-0852-staging-vc04_services-codec-Increase-the-number-of-s.patch
new file mode 100644
index 0000000000..c4e20c61a1
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0852-staging-vc04_services-codec-Increase-the-number-of-s.patch
@@ -0,0 +1,29 @@
+From 8827ec069302241c3a22371887d3980b9f855bba Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 25 Jun 2020 17:40:56 +0100
+Subject: [PATCH] staging: vc04_services: codec: Increase the number
+ of supported formats expected
+
+The ISP now supports 47 different input formats, therefore increase the
+array size for the number expected.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+@@ -2569,10 +2569,10 @@ static const struct v4l2_m2m_ops m2m_ops
+
+ /* Size of the array to provide to the VPU when asking for the list of supported
+ * formats.
+- * The ISP component currently advertises 33 input formats, so add a small
++ * The ISP component currently advertises 44 input formats, so add a small
+ * overhead on that.
+ */
+-#define MAX_SUPPORTED_ENCODINGS 40
++#define MAX_SUPPORTED_ENCODINGS 50
+
+ /* Populate dev->supported_fmts with the formats supported by those ports. */
+ static int bcm2835_codec_get_supported_fmts(struct bcm2835_codec_dev *dev)
diff --git a/target/linux/bcm27xx/patches-5.4/950-0853-staging-vc04_services-codec-Add-support-for-mono-for.patch b/target/linux/bcm27xx/patches-5.4/950-0853-staging-vc04_services-codec-Add-support-for-mono-for.patch
new file mode 100644
index 0000000000..620ad14248
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0853-staging-vc04_services-codec-Add-support-for-mono-for.patch
@@ -0,0 +1,64 @@
+From 6e6861281012b9ac99b85b9e2703cad35d91c279 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 1 Jul 2020 10:38:12 +0100
+Subject: [PATCH] staging: vc04_services: codec: Add support for mono
+ formats
+
+The firmware ISP component now allows for processing of mono
+images, so add those formats for use by the simple ISP device.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../bcm2835-codec/bcm2835-v4l2-codec.c | 41 +++++++++++++++++++
+ 1 file changed, 41 insertions(+)
+
+--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+@@ -344,6 +344,47 @@ static const struct bcm2835_codec_fmt su
+ .size_multiplier_x2 = 2,
+ .is_bayer = true,
+ }, {
++ /* Monochrome MIPI formats */
++ /* 8 bit */
++ .fourcc = V4L2_PIX_FMT_GREY,
++ .depth = 8,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_GREY,
++ .size_multiplier_x2 = 2,
++ }, {
++ /* 10 bit */
++ .fourcc = V4L2_PIX_FMT_Y10P,
++ .depth = 10,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_Y10P,
++ .size_multiplier_x2 = 2,
++ }, {
++ /* 12 bit */
++ .fourcc = V4L2_PIX_FMT_Y12P,
++ .depth = 12,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_Y12P,
++ .size_multiplier_x2 = 2,
++ }, {
++ /* 14 bit */
++ .fourcc = V4L2_PIX_FMT_Y14P,
++ .depth = 14,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_Y14P,
++ .size_multiplier_x2 = 2,
++ }, {
++ /* 16 bit */
++ .fourcc = V4L2_PIX_FMT_Y16,
++ .depth = 16,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_Y16,
++ .size_multiplier_x2 = 2,
++ }, {
+ /* Compressed formats */
+ .fourcc = V4L2_PIX_FMT_H264,
+ .depth = 0,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0854-staging-vc04_services-codec-Add-support-for-14bit-Ba.patch b/target/linux/bcm27xx/patches-5.4/950-0854-staging-vc04_services-codec-Add-support-for-14bit-Ba.patch
new file mode 100644
index 0000000000..e261f62570
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0854-staging-vc04_services-codec-Add-support-for-14bit-Ba.patch
@@ -0,0 +1,57 @@
+From 34963c9fb717bc47131b662c34a472c4f717f7fe Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 1 Jul 2020 10:50:12 +0100
+Subject: [PATCH] staging: vc04_services: codec: Add support for
+ 14bit Bayer formats
+
+Now that the 14bit Bayer formats have been defined within
+V4L2, add them to the lookup table of V4L2/MMAL formats.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../bcm2835-codec/bcm2835-v4l2-codec.c | 34 +++++++++++++++++++
+ 1 file changed, 34 insertions(+)
+
+--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+@@ -311,6 +311,40 @@ static const struct bcm2835_codec_fmt su
+ .size_multiplier_x2 = 2,
+ .is_bayer = true,
+ }, {
++ /* 14 bit */
++ .fourcc = V4L2_PIX_FMT_SRGGB14P,
++ .depth = 14,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB14P,
++ .size_multiplier_x2 = 2,
++ .is_bayer = true,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SBGGR14P,
++ .depth = 14,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR14P,
++ .size_multiplier_x2 = 2,
++ .is_bayer = true,
++
++ }, {
++ .fourcc = V4L2_PIX_FMT_SGRBG14P,
++ .depth = 14,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG14P,
++ .size_multiplier_x2 = 2,
++ .is_bayer = true,
++ }, {
++ .fourcc = V4L2_PIX_FMT_SGBRG14P,
++ .depth = 14,
++ .bytesperline_align = 32,
++ .flags = 0,
++ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG14P,
++ .size_multiplier_x2 = 2,
++ .is_bayer = true,
++ }, {
+ /* 16 bit */
+ .fourcc = V4L2_PIX_FMT_SRGGB16,
+ .depth = 16,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0855-media-bcm2835-unicam-Add-support-for-12bit-mono-pack.patch b/target/linux/bcm27xx/patches-5.4/950-0855-media-bcm2835-unicam-Add-support-for-12bit-mono-pack.patch
new file mode 100644
index 0000000000..fdef58c626
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0855-media-bcm2835-unicam-Add-support-for-12bit-mono-pack.patch
@@ -0,0 +1,25 @@
+From 511c9a4b7c3d2e40eee68dad4d4c02ca42678204 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 25 Jun 2020 17:53:32 +0100
+Subject: [PATCH] media: bcm2835-unicam: Add support for 12bit mono
+ packed format
+
+Now that V4L2_PIX_FMT_Y12P is defined, allow passing raw 12bit
+mono packed data through the peripheral.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/platform/bcm2835/bcm2835-unicam.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -336,7 +336,7 @@ static const struct unicam_fmt formats[]
+ .depth = 10,
+ .csi_dt = 0x2b,
+ }, {
+- /* NB There is no packed V4L2 fourcc for this format. */
++ .fourcc = V4L2_PIX_FMT_Y12P,
+ .repacked_fourcc = V4L2_PIX_FMT_Y12,
+ .code = MEDIA_BUS_FMT_Y12_1X12,
+ .depth = 12,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0856-media-bcm2835-unicam-Add-support-for-14bit-mono-sour.patch b/target/linux/bcm27xx/patches-5.4/950-0856-media-bcm2835-unicam-Add-support-for-14bit-mono-sour.patch
new file mode 100644
index 0000000000..a65945cb1b
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0856-media-bcm2835-unicam-Add-support-for-14bit-mono-sour.patch
@@ -0,0 +1,29 @@
+From 668ed11b1e8fbbe7ad9a63abbfece67d44b0aa85 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 25 Jun 2020 18:03:47 +0100
+Subject: [PATCH] media: bcm2835-unicam: Add support for 14bit mono
+ sources
+
+Now that V4L2_PIX_FMT_Y14 and V4L2_PIX_FMT_Y14P are defined,
+allow passing 14bit mono data through the peripheral.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/platform/bcm2835/bcm2835-unicam.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -341,6 +341,12 @@ static const struct unicam_fmt formats[]
+ .code = MEDIA_BUS_FMT_Y12_1X12,
+ .depth = 12,
+ .csi_dt = 0x2c,
++ }, {
++ .fourcc = V4L2_PIX_FMT_Y14P,
++ .repacked_fourcc = V4L2_PIX_FMT_Y14,
++ .code = MEDIA_BUS_FMT_Y14_1X14,
++ .depth = 14,
++ .csi_dt = 0x2d,
+ },
+ /* Embedded data format */
+ {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0857-media-bcm2835-unicam-Add-support-for-unpacked-14bit-.patch b/target/linux/bcm27xx/patches-5.4/950-0857-media-bcm2835-unicam-Add-support-for-unpacked-14bit-.patch
new file mode 100644
index 0000000000..b52a59a6e0
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0857-media-bcm2835-unicam-Add-support-for-unpacked-14bit-.patch
@@ -0,0 +1,42 @@
+From 9c0121e45af13c0b0850601ee4d88029c548b240 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 1 Jul 2020 10:57:57 +0100
+Subject: [PATCH] media: bcm2835-unicam: Add support for unpacked
+ 14bit Bayer formats
+
+Now that the 14bit non-packed Bayer formats are defined, add them
+into the supported formats lookup table.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/platform/bcm2835/bcm2835-unicam.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -299,21 +299,25 @@ static const struct unicam_fmt formats[]
+ .csi_dt = 0x2c,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SBGGR14P,
++ .repacked_fourcc = V4L2_PIX_FMT_SBGGR14,
+ .code = MEDIA_BUS_FMT_SBGGR14_1X14,
+ .depth = 14,
+ .csi_dt = 0x2d,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SGBRG14P,
++ .repacked_fourcc = V4L2_PIX_FMT_SGBRG14,
+ .code = MEDIA_BUS_FMT_SGBRG14_1X14,
+ .depth = 14,
+ .csi_dt = 0x2d,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SGRBG14P,
++ .repacked_fourcc = V4L2_PIX_FMT_SGRBG14,
+ .code = MEDIA_BUS_FMT_SGRBG14_1X14,
+ .depth = 14,
+ .csi_dt = 0x2d,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SRGGB14P,
++ .repacked_fourcc = V4L2_PIX_FMT_SRGGB14,
+ .code = MEDIA_BUS_FMT_SRGGB14_1X14,
+ .depth = 14,
+ .csi_dt = 0x2d,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0858-overlays-Fix-miniuart-bt-krnbt-parameter.patch b/target/linux/bcm27xx/patches-5.4/950-0858-overlays-Fix-miniuart-bt-krnbt-parameter.patch
new file mode 100644
index 0000000000..f7edf8a5b5
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0858-overlays-Fix-miniuart-bt-krnbt-parameter.patch
@@ -0,0 +1,32 @@
+From 2d54451c77c85e153046baebdfedeabc224a59d7 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 2 Jul 2020 15:21:05 +0100
+Subject: [PATCH] overlays: Fix miniuart-bt "krnbt" parameter
+
+Although superficially appealing, an overlay parameter that targets a
+label in the base DTB is not currently supported. Instead it is
+necessary to create a fragment targeting the label which is patched
+by the parameter.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts
++++ b/arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts
+@@ -81,7 +81,13 @@
+ };
+ };
+
++ fragment@7 {
++ target = <&minibt>;
++ minibt_frag: __overlay__ {
++ };
++ };
++
+ __overrides__ {
+- krnbt = <&minibt>,"status";
++ krnbt = <&minibt_frag>,"status";
+ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0859-drm-vc4-Make-FKMS-max-refresh-rate-a-module-paramete.patch b/target/linux/bcm27xx/patches-5.4/950-0859-drm-vc4-Make-FKMS-max-refresh-rate-a-module-paramete.patch
new file mode 100644
index 0000000000..bf27d7aa53
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0859-drm-vc4-Make-FKMS-max-refresh-rate-a-module-paramete.patch
@@ -0,0 +1,55 @@
+From ff882e312a746a4a794a089e912e5e56baa8b5b4 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 3 Jul 2020 14:11:55 +0100
+Subject: [PATCH] drm/vc4: Make FKMS max refresh rate a module
+ parameter
+
+Some people want to use the high refresh rate modes for 1080p100
+and 1080p120, but they're currently filtered out as generally
+they don't add anything.
+
+Make the filter threshold a module parameter so that it can be
+adjusted.
+
+https://github.com/raspberrypi/linux/issues/3677
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -14,6 +14,8 @@
+ * Pi's firmware display stack.
+ */
+
++#include <linux/module.h>
++
+ #include "drm/drm_atomic_helper.h"
+ #include "drm/drm_gem_framebuffer_helper.h"
+ #include "drm/drm_plane_helper.h"
+@@ -32,6 +34,10 @@
+ #include "vc_image_types.h"
+ #include <soc/bcm2835/raspberrypi-firmware.h>
+
++int fkms_max_refresh_rate = 85;
++module_param(fkms_max_refresh_rate, int, 0644);
++MODULE_PARM_DESC(fkms_max_refresh_rate, "Max supported refresh rate");
++
+ struct get_display_cfg {
+ u32 max_pixel_clock[2]; //Max pixel clock for each display
+ };
+@@ -1069,8 +1075,10 @@ vc4_crtc_mode_valid(struct drm_crtc *crt
+ return MODE_NO_DBLESCAN;
+ }
+
+- /* Disable refresh rates > 85Hz as limited gain from them */
+- if (drm_mode_vrefresh(mode) > 85)
++ /* Disable refresh rates > defined threshold (default 85Hz) as limited
++ * gain from them
++ */
++ if (drm_mode_vrefresh(mode) > fkms_max_refresh_rate)
+ return MODE_BAD_VVALUE;
+
+ /* Limit the pixel clock based on the HDMI clock limits from the
diff --git a/target/linux/bcm27xx/patches-5.4/950-0860-drm-vc4-FKMS-Block-modes-with-odd-horizontal-timing-.patch b/target/linux/bcm27xx/patches-5.4/950-0860-drm-vc4-FKMS-Block-modes-with-odd-horizontal-timing-.patch
new file mode 100644
index 0000000000..4bddd13ad5
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0860-drm-vc4-FKMS-Block-modes-with-odd-horizontal-timing-.patch
@@ -0,0 +1,74 @@
+From aa791f2cb6777e8ca99102009b631afdeea1c59d Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 3 Jul 2020 16:06:55 +0100
+Subject: [PATCH] drm/vc4: FKMS Block modes with odd horizontal
+ timing values on Pi4
+
+Pi4 HDMI pipeline is 2 pixels/clock and can not produce timings
+that have odd values for active pixels, front porch, sync width,
+or back porch.
+Detect these modes and block them within fkms.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -44,6 +44,7 @@ struct get_display_cfg {
+
+ struct vc4_fkms {
+ struct get_display_cfg cfg;
++ bool bcm2711;
+ };
+
+ #define PLANES_PER_CRTC 3
+@@ -1097,6 +1098,17 @@ vc4_crtc_mode_valid(struct drm_crtc *crt
+ break;
+ }
+
++ /* Pi4 can't generate odd horizontal timings on HDMI, so reject modes
++ * that would set them.
++ */
++ if (fkms->bcm2711 &&
++ (vc4_crtc->display_number == 2 || vc4_crtc->display_number == 7) &&
++ ((mode->hdisplay | /* active */
++ (mode->hsync_start - mode->hdisplay) | /* front porch */
++ (mode->hsync_end - mode->hsync_start) | /* sync pulse */
++ (mode->htotal - mode->hsync_end)) & 1)) /* back porch */
++ return MODE_H_ILLEGAL;
++
+ return MODE_OK;
+ }
+
+@@ -1282,6 +1294,8 @@ static const struct drm_crtc_helper_func
+
+ static const struct of_device_id vc4_firmware_kms_dt_match[] = {
+ { .compatible = "raspberrypi,rpi-firmware-kms" },
++ { .compatible = "raspberrypi,rpi-firmware-kms-2711",
++ .data = (void *)1 },
+ {}
+ };
+
+@@ -1815,6 +1829,7 @@ static int vc4_fkms_bind(struct device *
+ struct drm_device *drm = dev_get_drvdata(master);
+ struct vc4_dev *vc4 = to_vc4_dev(drm);
+ struct device_node *firmware_node;
++ const struct of_device_id *match;
+ struct vc4_crtc **crtc_list;
+ u32 num_displays, display_num;
+ struct vc4_fkms *fkms;
+@@ -1827,6 +1842,12 @@ static int vc4_fkms_bind(struct device *
+ if (!fkms)
+ return -ENOMEM;
+
++ match = of_match_device(vc4_firmware_kms_dt_match, dev);
++ if (!match)
++ return -ENODEV;
++ if (match->data)
++ fkms->bcm2711 = true;
++
+ /* firmware kms doesn't have precise a scanoutpos implementation, so
+ * we can't do the precise vblank timestamp mode.
+ */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0861-dt-Use-rpi-firmware-kms-2711-on-2711-platforms.patch b/target/linux/bcm27xx/patches-5.4/950-0861-dt-Use-rpi-firmware-kms-2711-on-2711-platforms.patch
new file mode 100644
index 0000000000..d1805a6cd5
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0861-dt-Use-rpi-firmware-kms-2711-on-2711-platforms.patch
@@ -0,0 +1,37 @@
+From 603b5b55d5f52869263647c44fe682d105f8ee46 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 3 Jul 2020 16:05:37 +0100
+Subject: [PATCH] dt: Use rpi-firmware-kms-2711 on 2711 platforms
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 4 ++++
+ arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+@@ -443,6 +443,10 @@
+ };
+ };
+
++&firmwarekms {
++ compatible = "raspberrypi,rpi-firmware-kms-2711";
++};
++
+ // =============================================
+ // Board specific stuff here
+
+--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
+@@ -461,6 +461,10 @@
+ };
+ };
+
++&firmwarekms {
++ compatible = "raspberrypi,rpi-firmware-kms-2711";
++};
++
+ // =============================================
+ // Board specific stuff here
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0862-drm-vc4-FKMS-Put-includes-in-alphabetical-order-and-.patch b/target/linux/bcm27xx/patches-5.4/950-0862-drm-vc4-FKMS-Put-includes-in-alphabetical-order-and-.patch
new file mode 100644
index 0000000000..4adbe8a03c
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0862-drm-vc4-FKMS-Put-includes-in-alphabetical-order-and-.patch
@@ -0,0 +1,57 @@
+From 0a5e493ea20d9d24d0808d8a4e05a97deb19b423 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 3 Jul 2020 16:13:33 +0100
+Subject: [PATCH] drm/vc4: FKMS: Put includes in alphabetical order,
+ and use <> instead of ""
+
+Reorder the includes, and use the system include paths rather than
+local ones
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c | 29 +++++++++++++-------------
+ 1 file changed, 15 insertions(+), 14 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -14,25 +14,26 @@
+ * Pi's firmware display stack.
+ */
+
++#include <drm/drm_atomic_helper.h>
++#include <drm/drm_crtc_helper.h>
++#include <drm/drm_drv.h>
++#include <drm/drm_fb_cma_helper.h>
++#include <drm/drm_fourcc.h>
++#include <drm/drm_gem_framebuffer_helper.h>
++#include <drm/drm_plane_helper.h>
++#include <drm/drm_probe_helper.h>
++#include <drm/drm_vblank.h>
++
++#include <linux/component.h>
++#include <linux/clk.h>
++#include <linux/debugfs.h>
+ #include <linux/module.h>
+
+-#include "drm/drm_atomic_helper.h"
+-#include "drm/drm_gem_framebuffer_helper.h"
+-#include "drm/drm_plane_helper.h"
+-#include "drm/drm_crtc_helper.h"
+-#include "drm/drm_fourcc.h"
+-#include "drm/drm_probe_helper.h"
+-#include "drm/drm_drv.h"
+-#include "drm/drm_vblank.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 <soc/bcm2835/raspberrypi-firmware.h>
++
+ #include "vc4_drv.h"
+ #include "vc4_regs.h"
+ #include "vc_image_types.h"
+-#include <soc/bcm2835/raspberrypi-firmware.h>
+
+ int fkms_max_refresh_rate = 85;
+ module_param(fkms_max_refresh_rate, int, 0644);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0863-irqchip-bcm2835-Quiesce-IRQs-left-enabled-by-bootloa.patch b/target/linux/bcm27xx/patches-5.4/950-0863-irqchip-bcm2835-Quiesce-IRQs-left-enabled-by-bootloa.patch
new file mode 100644
index 0000000000..f27d448864
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0863-irqchip-bcm2835-Quiesce-IRQs-left-enabled-by-bootloa.patch
@@ -0,0 +1,105 @@
+From 4ae861da5eaf53e5b4303f080bff0e34e22da0d9 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Tue, 4 Feb 2020 15:50:41 +0100
+Subject: [PATCH] irqchip/bcm2835: Quiesce IRQs left enabled by
+ bootloader
+
+[ Upstream commit bd59b343a9c902c522f006e6d71080f4893bbf42 ]
+
+Per the spec, the BCM2835's IRQs are all disabled when coming out of
+power-on reset. Its IRQ driver assumes that's still the case when the
+kernel boots and does not perform any initialization of the registers.
+However the Raspberry Pi Foundation's bootloader leaves the USB
+interrupt enabled when handing over control to the kernel.
+
+Quiesce IRQs and the FIQ if they were left enabled and log a message to
+let users know that they should update the bootloader once a fixed
+version is released.
+
+If the USB interrupt is not quiesced and the USB driver later on claims
+the FIQ (as it does on the Raspberry Pi Foundation's downstream kernel),
+interrupt latency for all other peripherals increases and occasional
+lockups occur. That's because both the FIQ and the normal USB interrupt
+fire simultaneously:
+
+On a multicore Raspberry Pi, if normal interrupts are routed to CPU 0
+and the FIQ to CPU 1 (hardcoded in the Foundation's kernel), then a USB
+interrupt causes CPU 0 to spin in bcm2836_chained_handle_irq() until the
+FIQ on CPU 1 has cleared it. Other peripherals' interrupts are starved
+as long. I've seen CPU 0 blocked for up to 2.9 msec. eMMC throughput
+on a Compute Module 3 irregularly dips to 23.0 MB/s without this commit
+but remains relatively constant at 23.5 MB/s with this commit.
+
+The lockups occur when CPU 0 receives a USB interrupt while holding a
+lock which CPU 1 is trying to acquire while the FIQ is temporarily
+disabled on CPU 1. At best users get RCU CPU stall warnings, but most
+of the time the system just freezes.
+
+Fixes: 89214f009c1d ("ARM: bcm2835: add interrupt controller driver")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Link: https://lore.kernel.org/r/f97868ba4e9b86ddad71f44ec9d8b3b7d8daa1ea.1582618537.git.lukas@wunner.de
+---
+ drivers/irqchip/irq-bcm2835.c | 21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+--- a/drivers/irqchip/irq-bcm2835.c
++++ b/drivers/irqchip/irq-bcm2835.c
+@@ -67,8 +67,7 @@
+ #define ARM_LOCAL_GPU_INT_ROUTING 0x0c
+
+ #define REG_FIQ_CONTROL 0x0c
+-#define REG_FIQ_ENABLE 0x80
+-#define REG_FIQ_DISABLE 0
++#define FIQ_CONTROL_ENABLE BIT(7)
+
+ #define NR_BANKS 3
+ #define IRQS_PER_BANK 32
+@@ -116,7 +115,7 @@ static inline unsigned int hwirq_to_fiq(
+ static void armctrl_mask_irq(struct irq_data *d)
+ {
+ if (d->hwirq >= NUMBER_IRQS)
+- writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL);
++ writel_relaxed(0, intc.base + REG_FIQ_CONTROL);
+ else
+ writel_relaxed(HWIRQ_BIT(d->hwirq),
+ intc.disable[HWIRQ_BANK(d->hwirq)]);
+@@ -143,7 +142,7 @@ static void armctrl_unmask_irq(struct ir
+ ARM_LOCAL_GPU_INT_ROUTING);
+ }
+
+- writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq),
++ writel_relaxed(FIQ_CONTROL_ENABLE | hwirq_to_fiq(d->hwirq),
+ intc.base + REG_FIQ_CONTROL);
+ } else {
+ writel_relaxed(HWIRQ_BIT(d->hwirq),
+@@ -201,6 +200,7 @@ static int __init armctrl_of_init(struct
+ {
+ void __iomem *base;
+ int irq = 0, last_irq, b, i;
++ u32 reg;
+
+ base = of_iomap(node, 0);
+ if (!base)
+@@ -224,6 +224,19 @@ static int __init armctrl_of_init(struct
+ handle_level_irq);
+ irq_set_probe(irq);
+ }
++
++ reg = readl_relaxed(intc.enable[b]);
++ if (reg) {
++ writel_relaxed(reg, intc.disable[b]);
++ pr_err(FW_BUG "Bootloader left irq enabled: "
++ "bank %d irq %*pbl\n", b, IRQS_PER_BANK, &reg);
++ }
++ }
++
++ reg = readl_relaxed(base + REG_FIQ_CONTROL);
++ if (reg & FIQ_CONTROL_ENABLE) {
++ writel_relaxed(0, base + REG_FIQ_CONTROL);
++ pr_err(FW_BUG "Bootloader left fiq enabled\n");
+ }
+
+ last_irq = irq;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0864-dtoverlays-Fixup-imx219-and-imx477-overlays-due-to-p.patch b/target/linux/bcm27xx/patches-5.4/950-0864-dtoverlays-Fixup-imx219-and-imx477-overlays-due-to-p.patch
new file mode 100644
index 0000000000..44ecd49f16
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0864-dtoverlays-Fixup-imx219-and-imx477-overlays-due-to-p.patch
@@ -0,0 +1,42 @@
+From ae906e8cc5152d171ff4d0bf7e668b941a6b1a06 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 1 Jul 2020 18:28:10 +0100
+Subject: [PATCH] dtoverlays: Fixup imx219 and imx477 overlays due to
+ parsing failures
+
+imx219 overlay failed to detect as CSI2 as it was missing any
+of the CSI2 properties on the Unicam end of the configuration.
+Clean up imx477 as well to include all the relevant properties.
+
+Fixes: "dt/dtoverlays: Fix up base DT and overlays for updated Unicam driver"
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/imx219-overlay.dts | 3 +++
+ arch/arm/boot/dts/overlays/imx477-overlay.dts | 2 ++
+ 2 files changed, 5 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/imx219-overlay.dts
++++ b/arch/arm/boot/dts/overlays/imx219-overlay.dts
+@@ -49,6 +49,9 @@
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&imx219_0>;
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ clock-noncontinuous;
+ };
+ };
+ };
+--- a/arch/arm/boot/dts/overlays/imx477-overlay.dts
++++ b/arch/arm/boot/dts/overlays/imx477-overlay.dts
+@@ -49,7 +49,9 @@
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&imx477_0>;
++ clock-lanes = <0>;
+ data-lanes = <1 2>;
++ clock-noncontinuous;
+ };
+ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0865-overlays-rpi-ft5406-Fix-boolean-parameters.patch b/target/linux/bcm27xx/patches-5.4/950-0865-overlays-rpi-ft5406-Fix-boolean-parameters.patch
new file mode 100644
index 0000000000..f1daaf2e66
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0865-overlays-rpi-ft5406-Fix-boolean-parameters.patch
@@ -0,0 +1,27 @@
+From e61f4babc548c69b26f60c93eaa4e20d676db8b8 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Sat, 4 Jul 2020 22:19:26 +0100
+Subject: [PATCH] overlays: rpi-ft5406: Fix boolean parameters
+
+An improvement in the automated testing of overlays revealed
+these invalid boolean parameter declarations.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts
++++ b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts
+@@ -18,8 +18,8 @@
+ __overrides__ {
+ touchscreen-size-x = <&ts>,"touchscreen-size-x:0";
+ touchscreen-size-y = <&ts>,"touchscreen-size-y:0";
+- touchscreen-inverted-x = <&ts>,"touchscreen-inverted-x:?";
+- touchscreen-inverted-y = <&ts>,"touchscreen-inverted-y:?";
+- touchscreen-swapped-x-y = <&ts>,"touchscreen-swapped-x-y:?";
++ touchscreen-inverted-x = <&ts>,"touchscreen-inverted-x?";
++ touchscreen-inverted-y = <&ts>,"touchscreen-inverted-y?";
++ touchscreen-swapped-x-y = <&ts>,"touchscreen-swapped-x-y?";
+ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0866-ARM-dts-Copy-kernel-BT-changes-to-CM4.patch b/target/linux/bcm27xx/patches-5.4/950-0866-ARM-dts-Copy-kernel-BT-changes-to-CM4.patch
new file mode 100644
index 0000000000..0c4158b165
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0866-ARM-dts-Copy-kernel-BT-changes-to-CM4.patch
@@ -0,0 +1,29 @@
+From c1037594129cb19e62ea7551b0b4c449a392d883 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 6 Jul 2020 17:53:47 +0100
+Subject: [PATCH] ARM: dts: Copy kernel BT changes to CM4
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
+@@ -194,6 +194,7 @@
+ // Downstream rpi- changes
+
+ #include "bcm270x.dtsi"
++#include "bcm271x-rpi-bt.dtsi"
+
+ / {
+ soc {
+@@ -267,8 +268,6 @@
+ &uart0 {
+ pinctrl-0 = <&uart0_pins &bt_pins>;
+ status = "okay";
+-
+- /delete-node/ bluetooth;
+ };
+
+ &uart1 {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0867-ARM-dts-Make-bcm2711-dts-more-like-5.7.patch b/target/linux/bcm27xx/patches-5.4/950-0867-ARM-dts-Make-bcm2711-dts-more-like-5.7.patch
new file mode 100644
index 0000000000..bbe5569e61
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0867-ARM-dts-Make-bcm2711-dts-more-like-5.7.patch
@@ -0,0 +1,696 @@
+From 0f02c32b2d27fa5f0b21c67fb5518a36b5234f3a Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 7 Jul 2020 09:01:54 +0100
+Subject: [PATCH] ARM: dts: Make bcm2711 dts more like 5.7
+
+The multiple declarations of pixelvalve2 were causing problems for the
+DT checkers. Aligning the dts files closer to the later kernel versions
+avoids some repetition and should make maintenance easier.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 142 ++++++++++++-----------
+ arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 69 +----------
+ arch/arm/boot/dts/bcm2711-rpi.dtsi | 150 +++++++++++++++++++++++-
+ arch/arm/boot/dts/bcm2711.dtsi | 157 +++-----------------------
+ 4 files changed, 245 insertions(+), 273 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+@@ -19,7 +19,9 @@
+ };
+
+ aliases {
++ emmc2bus = &emmc2bus;
+ ethernet0 = &genet;
++ pcie0 = &pcie0;
+ };
+
+ leds {
+@@ -30,6 +32,8 @@
+ pwr {
+ label = "PWR";
+ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
++ default-state = "keep";
++ linux,default-trigger = "default-on";
+ };
+ };
+
+@@ -70,6 +74,79 @@
+ };
+ };
+
++&gpio {
++ /*
++ * Parts taken from rpi_SCH_4b_4p0_reduced.pdf and
++ * the official GPU firmware DT blob.
++ *
++ * Legend:
++ * "FOO" = GPIO line named "FOO" on the schematic
++ * "FOO_N" = GPIO line named "FOO" on schematic, active low
++ */
++ gpio-line-names = "ID_SDA",
++ "ID_SCL",
++ "SDA1",
++ "SCL1",
++ "GPIO_GCLK",
++ "GPIO5",
++ "GPIO6",
++ "SPI_CE1_N",
++ "SPI_CE0_N",
++ "SPI_MISO",
++ "SPI_MOSI",
++ "SPI_SCLK",
++ "GPIO12",
++ "GPIO13",
++ /* Serial port */
++ "TXD1",
++ "RXD1",
++ "GPIO16",
++ "GPIO17",
++ "GPIO18",
++ "GPIO19",
++ "GPIO20",
++ "GPIO21",
++ "GPIO22",
++ "GPIO23",
++ "GPIO24",
++ "GPIO25",
++ "GPIO26",
++ "GPIO27",
++ "RGMII_MDIO",
++ "RGMIO_MDC",
++ /* Used by BT module */
++ "CTS0",
++ "RTS0",
++ "TXD0",
++ "RXD0",
++ /* Used by Wifi */
++ "SD1_CLK",
++ "SD1_CMD",
++ "SD1_DATA0",
++ "SD1_DATA1",
++ "SD1_DATA2",
++ "SD1_DATA3",
++ /* Shared with SPI flash */
++ "PWM0_MISO",
++ "PWM1_MOSI",
++ "STATUS_LED_G_CLK",
++ "SPIFLASH_CE_N",
++ "SDA0",
++ "SCL0",
++ "RGMII_RXCLK",
++ "RGMII_RXCTL",
++ "RGMII_RXD0",
++ "RGMII_RXD1",
++ "RGMII_RXD2",
++ "RGMII_RXD3",
++ "RGMII_TXCLK",
++ "RGMII_TXCTL",
++ "RGMII_TXD0",
++ "RGMII_TXD1",
++ "RGMII_TXD2",
++ "RGMII_TXD3";
++};
++
+ &pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1_0_gpio40 &pwm1_1_gpio41>;
+@@ -138,46 +215,6 @@
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+-&vc4 {
+- status = "okay";
+-};
+-
+-&pixelvalve0 {
+- status = "okay";
+-};
+-
+-&pixelvalve1 {
+- status = "okay";
+-};
+-
+-&pixelvalve2 {
+- status = "okay";
+-};
+-
+-&pixelvalve3 {
+- status = "okay";
+-};
+-
+-&pixelvalve4 {
+- status = "okay";
+-};
+-
+-&hdmi0 {
+- status = "okay";
+-};
+-
+-&ddc0 {
+- status = "okay";
+-};
+-
+-&hdmi1 {
+- status = "okay";
+-};
+-
+-&ddc1 {
+- status = "okay";
+-};
+-
+ // =============================================
+ // Downstream rpi- changes
+
+@@ -195,8 +232,6 @@
+ #include "bcm283x-rpi-csi1-2lane.dtsi"
+ #include "bcm283x-rpi-i2c0mux_0_44.dtsi"
+
+-/delete-node/ &emmc2;
+-
+ / {
+ chosen {
+ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1";
+@@ -213,29 +248,7 @@
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ i2c6 = &i2c6;
+- /delete-property/ ethernet;
+ /delete-property/ intc;
+- pcie0 = &pcie0;
+- emmc2bus = &emmc2bus;
+- };
+-
+- emmc2bus: emmc2bus {
+- compatible = "simple-bus";
+- #address-cells = <2>;
+- #size-cells = <1>;
+-
+- ranges = <0x0 0x7e000000 0x0 0xfe000000 0x01800000>;
+- dma-ranges = <0x0 0xc0000000 0x0 0x00000000 0x40000000>;
+-
+- emmc2: emmc2@7e340000 {
+- compatible = "brcm,bcm2711-emmc2";
+- status = "okay";
+- interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clocks BCM2711_CLOCK_EMMC2>;
+- reg = <0x0 0x7e340000 0x100>;
+- vqmmc-supply = <&sd_io_1v8_reg>;
+- broken-cd;
+- };
+ };
+
+ /delete-node/ wifi-pwrseq;
+@@ -557,6 +570,7 @@
+ eth_led0 = <&phy1>,"led-modes:0";
+ eth_led1 = <&phy1>,"led-modes:4";
+
++ sd_poll_once = <&emmc2>, "non-removable?";
+ spi_dma4 = <&spi0>, "dmas:0=", <&dma40>,
+ <&spi0>, "dmas:8=", <&dma40>;
+ };
+--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
+@@ -19,7 +19,9 @@
+ };
+
+ aliases {
++ emmc2bus = &emmc2bus;
+ ethernet0 = &genet;
++ pcie0 = &pcie0;
+ };
+
+ leds {
+@@ -30,6 +32,8 @@
+ pwr {
+ label = "PWR";
+ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
++ default-state = "keep";
++ linux,default-trigger = "default-on";
+ };
+ };
+
+@@ -150,46 +154,6 @@
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+-&vc4 {
+- status = "okay";
+-};
+-
+-&pixelvalve0 {
+- status = "okay";
+-};
+-
+-&pixelvalve1 {
+- status = "okay";
+-};
+-
+-&pixelvalve2 {
+- status = "okay";
+-};
+-
+-&pixelvalve3 {
+- status = "okay";
+-};
+-
+-&pixelvalve4 {
+- status = "okay";
+-};
+-
+-&hdmi0 {
+- status = "okay";
+-};
+-
+-&ddc0 {
+- status = "okay";
+-};
+-
+-&hdmi1 {
+- status = "okay";
+-};
+-
+-&ddc1 {
+- status = "okay";
+-};
+-
+ // =============================================
+ // Downstream rpi- changes
+
+@@ -208,8 +172,6 @@
+ #include "bcm283x-rpi-csi1-4lane.dtsi"
+ #include "bcm283x-rpi-i2c0mux_0_44.dtsi"
+
+-/delete-node/ &emmc2;
+-
+ / {
+ chosen {
+ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1";
+@@ -226,29 +188,7 @@
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ i2c6 = &i2c6;
+- /delete-property/ ethernet;
+ /delete-property/ intc;
+- pcie0 = &pcie0;
+- emmc2bus = &emmc2bus;
+- };
+-
+- emmc2bus: emmc2bus {
+- compatible = "simple-bus";
+- #address-cells = <2>;
+- #size-cells = <1>;
+-
+- ranges = <0x0 0x7e000000 0x0 0xfe000000 0x01800000>;
+- dma-ranges = <0x0 0xc0000000 0x0 0x00000000 0x40000000>;
+-
+- emmc2: emmc2@7e340000 {
+- compatible = "brcm,bcm2711-emmc2";
+- status = "okay";
+- interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clocks BCM2711_CLOCK_EMMC2>;
+- reg = <0x0 0x7e340000 0x100>;
+- vqmmc-supply = <&sd_io_1v8_reg>;
+- broken-cd;
+- };
+ };
+
+ /delete-node/ wifi-pwrseq;
+@@ -588,6 +528,7 @@
+ <&ant2>, "output-high?=off",
+ <&ant2>, "output-low?=on";
+
++ sd_poll_once = <&emmc2>, "non-removable?";
+ spi_dma4 = <&spi0>, "dmas:0=", <&dma40>,
+ <&spi0>, "dmas:8=", <&dma40>;
+ };
+--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi
+@@ -4,6 +4,129 @@
+ / {
+ soc {
+ /delete-node/ v3d@7ec00000;
++
++ pixelvalve0: pixelvalve@7e206000 {
++ compatible = "brcm,bcm2711-pixelvalve0";
++ reg = <0x7e206000 0x100>;
++ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
++ status = "disabled";
++ };
++
++ pixelvalve1: pixelvalve@7e207000 {
++ compatible = "brcm,bcm2711-pixelvalve1";
++ reg = <0x7e207000 0x100>;
++ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
++ status = "disabled";
++ };
++
++ pixelvalve2: pixelvalve@7e20a000 {
++ compatible = "brcm,bcm2711-pixelvalve2";
++ reg = <0x7e20a000 0x100>;
++ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
++ status = "disabled";
++ };
++
++ pixelvalve4: pixelvalve@7e216000 {
++ compatible = "brcm,bcm2711-pixelvalve4";
++ reg = <0x7e216000 0x100>;
++ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
++ status = "disabled";
++ };
++
++ pixelvalve3: pixelvalve@7ec12000 {
++ compatible = "brcm,bcm2711-pixelvalve3";
++ reg = <0x7ec12000 0x100>;
++ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
++ status = "disabled";
++ };
++
++ dvp: clock@7ef00000 {
++ compatible = "brcm,brcm2711-dvp";
++ reg = <0x7ef00000 0x10>;
++ clocks = <&clk_108MHz>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
++
++ hdmi0: hdmi@7ef00700 {
++ compatible = "brcm,bcm2711-hdmi0";
++ reg = <0x7ef00700 0x300>,
++ <0x7ef00300 0x200>,
++ <0x7ef00f00 0x80>,
++ <0x7ef00f80 0x80>,
++ <0x7ef01b00 0x200>,
++ <0x7ef01f00 0x400>,
++ <0x7ef00200 0x80>,
++ <0x7ef04300 0x100>,
++ <0x7ef20000 0x100>,
++ <0x7ef00100 0x30>;
++ reg-names = "hdmi",
++ "dvp",
++ "phy",
++ "rm",
++ "packet",
++ "metadata",
++ "csc",
++ "cec",
++ "hd",
++ "intr2";
++ clocks = <&firmware_clocks 13>;
++ clock-names = "hdmi";
++ resets = <&dvp 0>;
++ ddc = <&ddc0>;
++ dmas = <&dma 10>;
++ dma-names = "audio-rx";
++ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
++ status = "disabled";
++ };
++
++ ddc0: i2c@7ef04500 {
++ compatible = "brcm,bcm2711-hdmi-i2c";
++ reg = <0x7ef04500 0x100>, <0x7ef00b00 0x300>;
++ reg-names = "bsc", "auto-i2c";
++ clock-frequency = <97500>;
++ status = "disabled";
++ };
++
++ hdmi1: hdmi@7ef05700 {
++ compatible = "brcm,bcm2711-hdmi1";
++ reg = <0x7ef05700 0x300>,
++ <0x7ef05300 0x200>,
++ <0x7ef05f00 0x80>,
++ <0x7ef05f80 0x80>,
++ <0x7ef06b00 0x200>,
++ <0x7ef06f00 0x400>,
++ <0x7ef00280 0x80>,
++ <0x7ef09300 0x100>,
++ <0x7ef20000 0x100>,
++ <0x7ef00100 0x30>;
++ reg-names = "hdmi",
++ "dvp",
++ "phy",
++ "rm",
++ "packet",
++ "metadata",
++ "csc",
++ "cec",
++ "hd",
++ "intr2";
++ ddc = <&ddc1>;
++ clocks = <&firmware_clocks 13>;
++ clock-names = "hdmi";
++ resets = <&dvp 1>;
++ dmas = <&dma 17>;
++ dma-names = "audio-rx";
++ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
++ status = "disabled";
++ };
++
++ ddc1: i2c@7ef09500 {
++ compatible = "brcm,bcm2711-hdmi-i2c";
++ reg = <0x7ef09500 0x100>, <0x7ef05b00 0x300>;
++ reg-names = "bsc", "auto-i2c";
++ clock-frequency = <97500>;
++ status = "disabled";
++ };
+ };
+
+ __overrides__ {
+@@ -42,22 +165,33 @@
+ scb: scb {
+ /* Add a label */
+ };
+-};
+
+-&cma {
+- /* Limit cma to the lower 768MB to allow room for HIGHMEM on 32-bit */
+- alloc-ranges = <0x0 0x00000000 0x30000000>;
++ vc4: gpu {
++ compatible = "brcm,bcm2711-vc5";
++ status = "disabled";
++ };
++
++ clk_108MHz: clk-108M {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <108000000>;
++ clock-output-names = "108MHz-clock";
++ };
+ };
+
+ &soc {
+ /delete-node/ audio;
+ };
+
++&cma {
++ /* Limit cma to the lower 768MB to allow room for HIGHMEM on 32-bit */
++ alloc-ranges = <0x0 0x00000000 0x30000000>;
++};
++
+ &scb {
+ ranges = <0x0 0x7c000000 0x0 0xfc000000 0x0 0x03800000>,
+ <0x0 0x40000000 0x0 0xff800000 0x0 0x00800000>,
+- <0x6 0x00000000 0x6 0x00000000 0x0 0x40000000>,
+- <0x0 0x00000000 0x0 0x00000000 0x0 0xfc000000>;
++ <0x6 0x00000000 0x6 0x00000000 0x0 0x40000000>;
+ dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0xfc000000>,
+ <0x1 0x00000000 0x1 0x00000000 0x1 0x00000000>;
+
+@@ -171,6 +305,10 @@
+ compatible = "brcm,bcm2711-genet-v5", "brcm,genet-v5";
+ };
+
++&hvs {
++ clocks = <&firmware_clocks 4>;
++};
++
+ &firmware {
+ firmware_clocks: clocks {
+ compatible = "raspberrypi,firmware-clocks";
+--- a/arch/arm/boot/dts/bcm2711.dtsi
++++ b/arch/arm/boot/dts/bcm2711.dtsi
+@@ -12,18 +12,6 @@
+
+ interrupt-parent = <&gicv2>;
+
+- vc4: gpu {
+- compatible = "brcm,bcm2711-vc5";
+- status = "disabled";
+- };
+-
+- clk_108MHz: clk-108M {
+- #clock-cells = <0>;
+- compatible = "fixed-clock";
+- clock-frequency = <108000000>;
+- clock-output-names = "108MHz-clock";
+- };
+-
+ soc {
+ /*
+ * Defined ranges:
+@@ -245,27 +233,6 @@
+ status = "disabled";
+ };
+
+- pixelvalve0: pixelvalve@7e206000 {
+- compatible = "brcm,bcm2711-pixelvalve0";
+- reg = <0x7e206000 0x100>;
+- interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+- status = "disabled";
+- };
+-
+- pixelvalve1: pixelvalve@7e207000 {
+- compatible = "brcm,bcm2711-pixelvalve1";
+- reg = <0x7e207000 0x100>;
+- interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+- status = "disabled";
+- };
+-
+- pixelvalve2: pixelvalve@7e20a000 {
+- compatible = "brcm,bcm2711-pixelvalve2";
+- reg = <0x7e20a000 0x100>;
+- interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+- status = "disabled";
+- };
+-
+ pwm1: pwm@7e20c800 {
+ compatible = "brcm,bcm2835-pwm";
+ reg = <0x7e20c800 0x28>;
+@@ -276,118 +243,30 @@
+ status = "disabled";
+ };
+
+- pixelvalve4: pixelvalve@7e216000 {
+- compatible = "brcm,bcm2711-pixelvalve4";
+- reg = <0x7e216000 0x100>;
+- interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+- status = "disabled";
+- };
+-
+- emmc2: emmc2@7e340000 {
+- compatible = "brcm,bcm2711-emmc2";
+- reg = <0x7e340000 0x100>;
+- interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clocks BCM2711_CLOCK_EMMC2>;
+- status = "disabled";
+- };
+-
+ hvs@7e400000 {
+- clocks = <&firmware_clocks 4>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ };
++ };
+
+- pixelvalve3: pixelvalve@7ec12000 {
+- compatible = "brcm,bcm2711-pixelvalve3";
+- reg = <0x7ec12000 0x100>;
+- interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+- status = "disabled";
+- };
++ /*
++ * emmc2 has different DMA constraints based on SoC revisions. It was
++ * moved into its own bus, so as for RPi4's firmware to update them.
++ * The firmware will find whether the emmc2bus alias is defined, and if
++ * so, it'll edit the dma-ranges property below accordingly.
++ */
++ emmc2bus: emmc2bus {
++ compatible = "simple-bus";
++ #address-cells = <2>;
++ #size-cells = <1>;
+
+- dvp: clock@7ef00000 {
+- compatible = "brcm,brcm2711-dvp";
+- reg = <0x7ef00000 0x10>;
+- clocks = <&clk_108MHz>;
+- #clock-cells = <1>;
+- #reset-cells = <1>;
+- };
++ ranges = <0x0 0x7e000000 0x0 0xfe000000 0x01800000>;
++ dma-ranges = <0x0 0xc0000000 0x0 0x00000000 0x40000000>;
+
+- hdmi0: hdmi@7ef00700 {
+- compatible = "brcm,bcm2711-hdmi0";
+- reg = <0x7ef00700 0x300>,
+- <0x7ef00300 0x200>,
+- <0x7ef00f00 0x80>,
+- <0x7ef00f80 0x80>,
+- <0x7ef01b00 0x200>,
+- <0x7ef01f00 0x400>,
+- <0x7ef00200 0x80>,
+- <0x7ef04300 0x100>,
+- <0x7ef20000 0x100>,
+- <0x7ef00100 0x30>;
+- reg-names = "hdmi",
+- "dvp",
+- "phy",
+- "rm",
+- "packet",
+- "metadata",
+- "csc",
+- "cec",
+- "hd",
+- "intr2";
+- clocks = <&firmware_clocks 13>;
+- clock-names = "hdmi";
+- resets = <&dvp 0>;
+- ddc = <&ddc0>;
+- dmas = <&dma 10>;
+- dma-names = "audio-rx";
+- interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+- status = "disabled";
+- };
+-
+- ddc0: i2c@7ef04500 {
+- compatible = "brcm,bcm2711-hdmi-i2c";
+- reg = <0x7ef04500 0x100>, <0x7ef00b00 0x300>;
+- reg-names = "bsc", "auto-i2c";
+- clock-frequency = <97500>;
+- status = "disabled";
+- };
+-
+- hdmi1: hdmi@7ef05700 {
+- compatible = "brcm,bcm2711-hdmi1";
+- reg = <0x7ef05700 0x300>,
+- <0x7ef05300 0x200>,
+- <0x7ef05f00 0x80>,
+- <0x7ef05f80 0x80>,
+- <0x7ef06b00 0x200>,
+- <0x7ef06f00 0x400>,
+- <0x7ef00280 0x80>,
+- <0x7ef09300 0x100>,
+- <0x7ef20000 0x100>,
+- <0x7ef00100 0x30>;
+- reg-names = "hdmi",
+- "dvp",
+- "phy",
+- "rm",
+- "packet",
+- "metadata",
+- "csc",
+- "cec",
+- "hd",
+- "intr2";
+- ddc = <&ddc1>;
+- clocks = <&firmware_clocks 13>;
+- clock-names = "hdmi";
+- resets = <&dvp 1>;
+- dmas = <&dma 17>;
+- dma-names = "audio-rx";
+- interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+- status = "disabled";
+- };
+-
+- ddc1: i2c@7ef09500 {
+- compatible = "brcm,bcm2711-hdmi-i2c";
+- reg = <0x7ef09500 0x100>, <0x7ef05b00 0x300>;
+- reg-names = "bsc", "auto-i2c";
+- clock-frequency = <97500>;
++ emmc2: emmc2@7e340000 {
++ compatible = "brcm,bcm2711-emmc2";
++ reg = <0x0 0x7e340000 0x100>;
++ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clocks BCM2711_CLOCK_EMMC2>;
+ status = "disabled";
+ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0868-bcm2835-dma-Add-NO_WAIT_RESP-flag.patch b/target/linux/bcm27xx/patches-5.4/950-0868-bcm2835-dma-Add-NO_WAIT_RESP-flag.patch
new file mode 100644
index 0000000000..8fc7069e61
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0868-bcm2835-dma-Add-NO_WAIT_RESP-flag.patch
@@ -0,0 +1,54 @@
+From 8c070947d0d9ef7f890eeff329d4deb1c393ef87 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 1 Jul 2020 20:28:27 +0100
+Subject: [PATCH] bcm2835-dma: Add NO_WAIT_RESP flag
+
+Use bit 27 of the dreq value (the second cell of the DT DMA descriptor)
+to request that the WAIT_RESP bit is not set.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/dma/bcm2835-dma.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/dma/bcm2835-dma.c
++++ b/drivers/dma/bcm2835-dma.c
+@@ -167,6 +167,11 @@ struct bcm2835_desc {
+ #define BCM2835_DMA_WAIT(x) ((x & 31) << 21) /* add DMA-wait cycles */
+ #define BCM2835_DMA_NO_WIDE_BURSTS BIT(26) /* no 2 beat write bursts */
+
++/* A fake bit to request that the driver doesn't set the WAIT_RESP bit. */
++#define BCM2835_DMA_NO_WAIT_RESP BIT(27)
++#define WAIT_RESP(x) ((x & BCM2835_DMA_NO_WAIT_RESP) ? \
++ 0 : BCM2835_DMA_WAIT_RESP)
++
+ /* debug register bits */
+ #define BCM2835_DMA_DEBUG_LAST_NOT_SET_ERR BIT(0)
+ #define BCM2835_DMA_DEBUG_FIFO_ERR BIT(1)
+@@ -845,7 +850,7 @@ static struct dma_async_tx_descriptor *b
+ struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
+ struct bcm2835_desc *d;
+ u32 info = BCM2835_DMA_D_INC | BCM2835_DMA_S_INC;
+- u32 extra = BCM2835_DMA_INT_EN | BCM2835_DMA_WAIT_RESP;
++ u32 extra = BCM2835_DMA_INT_EN | WAIT_RESP(c->dreq);
+ size_t max_len = bcm2835_dma_max_frame_length(c);
+ size_t frames;
+
+@@ -875,7 +880,7 @@ static struct dma_async_tx_descriptor *b
+ struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
+ struct bcm2835_desc *d;
+ dma_addr_t src = 0, dst = 0;
+- u32 info = BCM2835_DMA_WAIT_RESP;
++ u32 info = WAIT_RESP(c->dreq);
+ u32 extra = BCM2835_DMA_INT_EN;
+ size_t frames;
+
+@@ -937,7 +942,7 @@ static struct dma_async_tx_descriptor *b
+ struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
+ struct bcm2835_desc *d;
+ dma_addr_t src, dst;
+- u32 info = BCM2835_DMA_WAIT_RESP;
++ u32 info = WAIT_RESP(c->dreq);
+ u32 extra = 0;
+ size_t max_len = bcm2835_dma_max_frame_length(c);
+ size_t frames;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0869-ARM-dts-Restore-the-old-2711-scb-ranges-property.patch b/target/linux/bcm27xx/patches-5.4/950-0869-ARM-dts-Restore-the-old-2711-scb-ranges-property.patch
new file mode 100644
index 0000000000..614b149f34
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0869-ARM-dts-Restore-the-old-2711-scb-ranges-property.patch
@@ -0,0 +1,24 @@
+From f2233a2a1baf7036469e5291b06457311120dfb4 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 7 Jul 2020 14:08:55 +0100
+Subject: [PATCH] ARM: dts: Restore the old 2711 scb ranges property
+
+The back-ported value breaks PCIe.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2711-rpi.dtsi | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi
+@@ -191,7 +191,8 @@
+ &scb {
+ ranges = <0x0 0x7c000000 0x0 0xfc000000 0x0 0x03800000>,
+ <0x0 0x40000000 0x0 0xff800000 0x0 0x00800000>,
+- <0x6 0x00000000 0x6 0x00000000 0x0 0x40000000>;
++ <0x6 0x00000000 0x6 0x00000000 0x0 0x40000000>,
++ <0x0 0x00000000 0x0 0x00000000 0x0 0xfc000000>;
+ dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0xfc000000>,
+ <0x1 0x00000000 0x1 0x00000000 0x1 0x00000000>;
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0870-media-i2c-add-ov9281-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0870-media-i2c-add-ov9281-driver.patch
new file mode 100644
index 0000000000..c48a146591
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0870-media-i2c-add-ov9281-driver.patch
@@ -0,0 +1,1218 @@
+From ca6aba3a4bf358b763d0e508df95455de3ae992c Mon Sep 17 00:00:00 2001
+From: Zefa Chen <zefa.chen@rock-chips.com>
+Date: Fri, 17 May 2019 18:23:03 +0800
+Subject: [PATCH] media: i2c: add ov9281 driver.
+
+Change-Id: I7b77250bbc56d2f861450cf77271ad15f9b88ab1
+Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com>
+---
+ drivers/media/i2c/Kconfig | 11 +
+ drivers/media/i2c/Makefile | 1 +
+ drivers/media/i2c/ov9281.c | 1171 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 1183 insertions(+)
+ create mode 100644 drivers/media/i2c/ov9281.c
+
+--- a/drivers/media/i2c/Kconfig
++++ b/drivers/media/i2c/Kconfig
+@@ -855,6 +855,17 @@ config VIDEO_OV9640
+ This is a Video4Linux2 sensor driver for the OmniVision
+ OV9640 camera sensor.
+
++config VIDEO_OV9281
++ tristate "OmniVision OV9281 sensor support"
++ depends on I2C && VIDEO_V4L2
++ depends on MEDIA_CAMERA_SUPPORT
++ help
++ This is a Video4Linux2 sensor-level driver for the OmniVision
++ OV9281 camera.
++
++ To compile this driver as a module, choose M here: the
++ module will be called ov9281.
++
+ config VIDEO_OV9650
+ tristate "OmniVision OV9650/OV9652 sensor support"
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+--- a/drivers/media/i2c/Makefile
++++ b/drivers/media/i2c/Makefile
+@@ -79,6 +79,7 @@ obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
+ obj-$(CONFIG_VIDEO_OV772X) += ov772x.o
+ obj-$(CONFIG_VIDEO_OV7740) += ov7740.o
+ obj-$(CONFIG_VIDEO_OV8856) += ov8856.o
++obj-$(CONFIG_VIDEO_OV9281) += ov9281.o
+ obj-$(CONFIG_VIDEO_OV9640) += ov9640.o
+ obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
+ obj-$(CONFIG_VIDEO_OV13858) += ov13858.o
+--- /dev/null
++++ b/drivers/media/i2c/ov9281.c
+@@ -0,0 +1,1171 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * ov9281 driver
++ *
++ * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd.
++ */
++
++#include <linux/clk.h>
++#include <linux/device.h>
++#include <linux/delay.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/regulator/consumer.h>
++#include <linux/sysfs.h>
++#include <linux/slab.h>
++#include <linux/rk-camera-module.h>
++#include <media/media-entity.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-subdev.h>
++#include <linux/pinctrl/consumer.h>
++
++#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x0)
++
++#ifndef V4L2_CID_DIGITAL_GAIN
++#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
++#endif
++
++#define OV9281_LINK_FREQ_400MHZ 400000000
++/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
++#define OV9281_PIXEL_RATE (OV9281_LINK_FREQ_400MHZ * 2 * 2 / 10)
++#define OV9281_XVCLK_FREQ 24000000
++
++#define CHIP_ID 0x9281
++#define OV9281_REG_CHIP_ID 0x300a
++
++#define OV9281_REG_CTRL_MODE 0x0100
++#define OV9281_MODE_SW_STANDBY 0x0
++#define OV9281_MODE_STREAMING BIT(0)
++
++#define OV9281_REG_EXPOSURE 0x3500
++#define OV9281_EXPOSURE_MIN 4
++#define OV9281_EXPOSURE_STEP 1
++#define OV9281_VTS_MAX 0x7fff
++
++#define OV9281_REG_GAIN_H 0x3508
++#define OV9281_REG_GAIN_L 0x3509
++#define OV9281_GAIN_H_MASK 0x07
++#define OV9281_GAIN_H_SHIFT 8
++#define OV9281_GAIN_L_MASK 0xff
++#define OV9281_GAIN_MIN 0x10
++#define OV9281_GAIN_MAX 0xf8
++#define OV9281_GAIN_STEP 1
++#define OV9281_GAIN_DEFAULT 0x10
++
++#define OV9281_REG_TEST_PATTERN 0x5e00
++#define OV9281_TEST_PATTERN_ENABLE 0x80
++#define OV9281_TEST_PATTERN_DISABLE 0x0
++
++#define OV9281_REG_VTS 0x380e
++
++#define REG_NULL 0xFFFF
++
++#define OV9281_REG_VALUE_08BIT 1
++#define OV9281_REG_VALUE_16BIT 2
++#define OV9281_REG_VALUE_24BIT 3
++
++#define OV9281_LANES 2
++#define OV9281_BITS_PER_SAMPLE 10
++
++#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
++#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
++
++#define OV9281_NAME "ov9281"
++
++static const char * const ov9281_supply_names[] = {
++ "avdd", /* Analog power */
++ "dovdd", /* Digital I/O power */
++ "dvdd", /* Digital core power */
++};
++
++#define OV9281_NUM_SUPPLIES ARRAY_SIZE(ov9281_supply_names)
++
++struct regval {
++ u16 addr;
++ u8 val;
++};
++
++struct ov9281_mode {
++ u32 width;
++ u32 height;
++ u32 max_fps;
++ u32 hts_def;
++ u32 vts_def;
++ u32 exp_def;
++ const struct regval *reg_list;
++};
++
++struct ov9281 {
++ struct i2c_client *client;
++ struct clk *xvclk;
++ struct gpio_desc *reset_gpio;
++ struct gpio_desc *pwdn_gpio;
++ struct regulator_bulk_data supplies[OV9281_NUM_SUPPLIES];
++
++ struct pinctrl *pinctrl;
++ struct pinctrl_state *pins_default;
++ struct pinctrl_state *pins_sleep;
++
++ struct v4l2_subdev subdev;
++ struct media_pad pad;
++ struct v4l2_ctrl_handler ctrl_handler;
++ struct v4l2_ctrl *exposure;
++ struct v4l2_ctrl *anal_gain;
++ struct v4l2_ctrl *digi_gain;
++ struct v4l2_ctrl *hblank;
++ struct v4l2_ctrl *vblank;
++ struct v4l2_ctrl *test_pattern;
++ struct mutex mutex;
++ bool streaming;
++ bool power_on;
++ const struct ov9281_mode *cur_mode;
++ u32 module_index;
++ const char *module_facing;
++ const char *module_name;
++ const char *len_name;
++};
++
++#define to_ov9281(sd) container_of(sd, struct ov9281, subdev)
++
++/*
++ * Xclk 24Mhz
++ */
++static const struct regval ov9281_global_regs[] = {
++ {REG_NULL, 0x00},
++};
++
++/*
++ * Xclk 24Mhz
++ * max_framerate 120fps
++ * mipi_datarate per lane 800Mbps
++ */
++static const struct regval ov9281_1280x800_regs[] = {
++ {0x0103, 0x01},
++ {0x0302, 0x32},
++ {0x030d, 0x50},
++ {0x030e, 0x02},
++ {0x3001, 0x00},
++ {0x3004, 0x00},
++ {0x3005, 0x00},
++ {0x3006, 0x04},
++ {0x3011, 0x0a},
++ {0x3013, 0x18},
++ {0x3022, 0x01},
++ {0x3023, 0x00},
++ {0x302c, 0x00},
++ {0x302f, 0x00},
++ {0x3030, 0x04},
++ {0x3039, 0x32},
++ {0x303a, 0x00},
++ {0x303f, 0x01},
++ {0x3500, 0x00},
++ {0x3501, 0x2a},
++ {0x3502, 0x90},
++ {0x3503, 0x08},
++ {0x3505, 0x8c},
++ {0x3507, 0x03},
++ {0x3508, 0x00},
++ {0x3509, 0x10},
++ {0x3610, 0x80},
++ {0x3611, 0xa0},
++ {0x3620, 0x6f},
++ {0x3632, 0x56},
++ {0x3633, 0x78},
++ {0x3662, 0x05},
++ {0x3666, 0x00},
++ {0x366f, 0x5a},
++ {0x3680, 0x84},
++ {0x3712, 0x80},
++ {0x372d, 0x22},
++ {0x3731, 0x80},
++ {0x3732, 0x30},
++ {0x3778, 0x00},
++ {0x377d, 0x22},
++ {0x3788, 0x02},
++ {0x3789, 0xa4},
++ {0x378a, 0x00},
++ {0x378b, 0x4a},
++ {0x3799, 0x20},
++ {0x3800, 0x00},
++ {0x3801, 0x00},
++ {0x3802, 0x00},
++ {0x3803, 0x00},
++ {0x3804, 0x05},
++ {0x3805, 0x0f},
++ {0x3806, 0x03},
++ {0x3807, 0x2f},
++ {0x3808, 0x05},
++ {0x3809, 0x00},
++ {0x380a, 0x03},
++ {0x380b, 0x20},
++ {0x380c, 0x02},
++ {0x380d, 0xd8},
++ {0x380e, 0x03},
++ {0x380f, 0x8e},
++ {0x3810, 0x00},
++ {0x3811, 0x08},
++ {0x3812, 0x00},
++ {0x3813, 0x08},
++ {0x3814, 0x11},
++ {0x3815, 0x11},
++ {0x3820, 0x40},
++ {0x3821, 0x00},
++ {0x3881, 0x42},
++ {0x38b1, 0x00},
++ {0x3920, 0xff},
++ {0x4003, 0x40},
++ {0x4008, 0x04},
++ {0x4009, 0x0b},
++ {0x400c, 0x00},
++ {0x400d, 0x07},
++ {0x4010, 0x40},
++ {0x4043, 0x40},
++ {0x4307, 0x30},
++ {0x4317, 0x00},
++ {0x4501, 0x00},
++ {0x4507, 0x00},
++ {0x4509, 0x00},
++ {0x450a, 0x08},
++ {0x4601, 0x04},
++ {0x470f, 0x00},
++ {0x4f07, 0x00},
++ {0x4800, 0x00},
++ {0x5000, 0x9f},
++ {0x5001, 0x00},
++ {0x5e00, 0x00},
++ {0x5d00, 0x07},
++ {0x5d01, 0x00},
++ {REG_NULL, 0x00},
++};
++
++static const struct ov9281_mode supported_modes[] = {
++ {
++ .width = 1280,
++ .height = 800,
++ .max_fps = 120,
++ .exp_def = 0x0320,
++ .hts_def = 0x0b60,//0x2d8*4
++ .vts_def = 0x038e,
++ .reg_list = ov9281_1280x800_regs,
++ },
++};
++
++static const s64 link_freq_menu_items[] = {
++ OV9281_LINK_FREQ_400MHZ
++};
++
++static const char * const ov9281_test_pattern_menu[] = {
++ "Disabled",
++ "Vertical Color Bar Type 1",
++ "Vertical Color Bar Type 2",
++ "Vertical Color Bar Type 3",
++ "Vertical Color Bar Type 4"
++};
++
++/* Write registers up to 4 at a time */
++static int ov9281_write_reg(struct i2c_client *client, u16 reg,
++ u32 len, u32 val)
++{
++ u32 buf_i, val_i;
++ u8 buf[6];
++ u8 *val_p;
++ __be32 val_be;
++
++ if (len > 4)
++ return -EINVAL;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++
++ val_be = cpu_to_be32(val);
++ val_p = (u8 *)&val_be;
++ buf_i = 2;
++ val_i = 4 - len;
++
++ while (val_i < 4)
++ buf[buf_i++] = val_p[val_i++];
++
++ if (i2c_master_send(client, buf, len + 2) != len + 2)
++ return -EIO;
++
++ return 0;
++}
++
++static int ov9281_write_array(struct i2c_client *client,
++ const struct regval *regs)
++{
++ u32 i;
++ int ret = 0;
++
++ for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++)
++ ret = ov9281_write_reg(client, regs[i].addr,
++ OV9281_REG_VALUE_08BIT, regs[i].val);
++
++ return ret;
++}
++
++/* Read registers up to 4 at a time */
++static int ov9281_read_reg(struct i2c_client *client, u16 reg, unsigned int len,
++ u32 *val)
++{
++ struct i2c_msg msgs[2];
++ u8 *data_be_p;
++ __be32 data_be = 0;
++ __be16 reg_addr_be = cpu_to_be16(reg);
++ int ret;
++
++ if (len > 4 || !len)
++ return -EINVAL;
++
++ data_be_p = (u8 *)&data_be;
++ /* Write register address */
++ msgs[0].addr = client->addr;
++ msgs[0].flags = 0;
++ msgs[0].len = 2;
++ msgs[0].buf = (u8 *)&reg_addr_be;
++
++ /* Read data from register */
++ msgs[1].addr = client->addr;
++ msgs[1].flags = I2C_M_RD;
++ msgs[1].len = len;
++ msgs[1].buf = &data_be_p[4 - len];
++
++ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
++ if (ret != ARRAY_SIZE(msgs))
++ return -EIO;
++
++ *val = be32_to_cpu(data_be);
++
++ return 0;
++}
++
++static int ov9281_get_reso_dist(const struct ov9281_mode *mode,
++ struct v4l2_mbus_framefmt *framefmt)
++{
++ return abs(mode->width - framefmt->width) +
++ abs(mode->height - framefmt->height);
++}
++
++static const struct ov9281_mode *
++ov9281_find_best_fit(struct v4l2_subdev_format *fmt)
++{
++ struct v4l2_mbus_framefmt *framefmt = &fmt->format;
++ int dist;
++ int cur_best_fit = 0;
++ int cur_best_fit_dist = -1;
++ unsigned int i;
++
++ for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
++ dist = ov9281_get_reso_dist(&supported_modes[i], framefmt);
++ if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
++ cur_best_fit_dist = dist;
++ cur_best_fit = i;
++ }
++ }
++
++ return &supported_modes[cur_best_fit];
++}
++
++static int ov9281_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *fmt)
++{
++ struct ov9281 *ov9281 = to_ov9281(sd);
++ const struct ov9281_mode *mode;
++ s64 h_blank, vblank_def;
++
++ mutex_lock(&ov9281->mutex);
++
++ mode = ov9281_find_best_fit(fmt);
++ fmt->format.code = MEDIA_BUS_FMT_Y10_1X10;
++ fmt->format.width = mode->width;
++ fmt->format.height = mode->height;
++ fmt->format.field = V4L2_FIELD_NONE;
++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
++ *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
++#else
++ mutex_unlock(&ov9281->mutex);
++ return -ENOTTY;
++#endif
++ } else {
++ ov9281->cur_mode = mode;
++ h_blank = mode->hts_def - mode->width;
++ __v4l2_ctrl_modify_range(ov9281->hblank, h_blank,
++ h_blank, 1, h_blank);
++ vblank_def = mode->vts_def - mode->height;
++ __v4l2_ctrl_modify_range(ov9281->vblank, vblank_def,
++ OV9281_VTS_MAX - mode->height,
++ 1, vblank_def);
++ }
++
++ mutex_unlock(&ov9281->mutex);
++
++ return 0;
++}
++
++static int ov9281_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *fmt)
++{
++ struct ov9281 *ov9281 = to_ov9281(sd);
++ const struct ov9281_mode *mode = ov9281->cur_mode;
++
++ mutex_lock(&ov9281->mutex);
++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
++ fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
++#else
++ mutex_unlock(&ov9281->mutex);
++ return -ENOTTY;
++#endif
++ } else {
++ fmt->format.width = mode->width;
++ fmt->format.height = mode->height;
++ fmt->format.code = MEDIA_BUS_FMT_Y10_1X10;
++ fmt->format.field = V4L2_FIELD_NONE;
++ }
++ mutex_unlock(&ov9281->mutex);
++
++ return 0;
++}
++
++static int ov9281_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->index != 0)
++ return -EINVAL;
++ code->code = MEDIA_BUS_FMT_Y10_1X10;
++
++ return 0;
++}
++
++static int ov9281_enum_frame_sizes(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ if (fse->index >= ARRAY_SIZE(supported_modes))
++ return -EINVAL;
++
++ if (fse->code != MEDIA_BUS_FMT_Y10_1X10)
++ return -EINVAL;
++
++ fse->min_width = supported_modes[fse->index].width;
++ fse->max_width = supported_modes[fse->index].width;
++ fse->max_height = supported_modes[fse->index].height;
++ fse->min_height = supported_modes[fse->index].height;
++
++ return 0;
++}
++
++static int ov9281_enable_test_pattern(struct ov9281 *ov9281, u32 pattern)
++{
++ u32 val;
++
++ if (pattern)
++ val = (pattern - 1) | OV9281_TEST_PATTERN_ENABLE;
++ else
++ val = OV9281_TEST_PATTERN_DISABLE;
++
++ return ov9281_write_reg(ov9281->client, OV9281_REG_TEST_PATTERN,
++ OV9281_REG_VALUE_08BIT, val);
++}
++
++static int OV9281_g_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct ov9281 *ov9281 = to_ov9281(sd);
++ const struct ov9281_mode *mode = ov9281->cur_mode;
++
++ mutex_lock(&ov9281->mutex);
++ fi->interval.numerator = 10000;
++ fi->interval.denominator = mode->max_fps * 10000;
++ mutex_unlock(&ov9281->mutex);
++
++ return 0;
++}
++
++static void ov9281_get_module_inf(struct ov9281 *ov9281,
++ struct rkmodule_inf *inf)
++{
++ memset(inf, 0, sizeof(*inf));
++ strlcpy(inf->base.sensor, OV9281_NAME, sizeof(inf->base.sensor));
++ strlcpy(inf->base.module, ov9281->module_name,
++ sizeof(inf->base.module));
++ strlcpy(inf->base.lens, ov9281->len_name, sizeof(inf->base.lens));
++}
++
++static long ov9281_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
++{
++ struct ov9281 *ov9281 = to_ov9281(sd);
++ long ret = 0;
++
++ switch (cmd) {
++ case RKMODULE_GET_MODULE_INFO:
++ ov9281_get_module_inf(ov9281, (struct rkmodule_inf *)arg);
++ break;
++ default:
++ ret = -ENOIOCTLCMD;
++ break;
++ }
++
++ return ret;
++}
++
++#ifdef CONFIG_COMPAT
++static long ov9281_compat_ioctl32(struct v4l2_subdev *sd,
++ unsigned int cmd, unsigned long arg)
++{
++ void __user *up = compat_ptr(arg);
++ struct rkmodule_inf *inf;
++ struct rkmodule_awb_cfg *cfg;
++ long ret;
++
++ switch (cmd) {
++ case RKMODULE_GET_MODULE_INFO:
++ inf = kzalloc(sizeof(*inf), GFP_KERNEL);
++ if (!inf) {
++ ret = -ENOMEM;
++ return ret;
++ }
++
++ ret = ov9281_ioctl(sd, cmd, inf);
++ if (!ret)
++ ret = copy_to_user(up, inf, sizeof(*inf));
++ kfree(inf);
++ break;
++ case RKMODULE_AWB_CFG:
++ cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
++ if (!cfg) {
++ ret = -ENOMEM;
++ return ret;
++ }
++
++ ret = copy_from_user(cfg, up, sizeof(*cfg));
++ if (!ret)
++ ret = ov9281_ioctl(sd, cmd, cfg);
++ kfree(cfg);
++ break;
++ default:
++ ret = -ENOIOCTLCMD;
++ break;
++ }
++
++ return ret;
++}
++#endif
++
++static int __ov9281_start_stream(struct ov9281 *ov9281)
++{
++ int ret;
++
++ ret = ov9281_write_array(ov9281->client, ov9281->cur_mode->reg_list);
++ if (ret)
++ return ret;
++
++ /* In case these controls are set before streaming */
++ mutex_unlock(&ov9281->mutex);
++ ret = v4l2_ctrl_handler_setup(&ov9281->ctrl_handler);
++ mutex_lock(&ov9281->mutex);
++ if (ret)
++ return ret;
++
++ return ov9281_write_reg(ov9281->client, OV9281_REG_CTRL_MODE,
++ OV9281_REG_VALUE_08BIT, OV9281_MODE_STREAMING);
++}
++
++static int __ov9281_stop_stream(struct ov9281 *ov9281)
++{
++ return ov9281_write_reg(ov9281->client, OV9281_REG_CTRL_MODE,
++ OV9281_REG_VALUE_08BIT, OV9281_MODE_SW_STANDBY);
++}
++
++static int ov9281_s_stream(struct v4l2_subdev *sd, int on)
++{
++ struct ov9281 *ov9281 = to_ov9281(sd);
++ struct i2c_client *client = ov9281->client;
++ int ret = 0;
++
++ mutex_lock(&ov9281->mutex);
++ on = !!on;
++ if (on == ov9281->streaming)
++ goto unlock_and_return;
++
++ if (on) {
++ ret = pm_runtime_get_sync(&client->dev);
++ if (ret < 0) {
++ pm_runtime_put_noidle(&client->dev);
++ goto unlock_and_return;
++ }
++
++ ret = __ov9281_start_stream(ov9281);
++ if (ret) {
++ v4l2_err(sd, "start stream failed while write regs\n");
++ pm_runtime_put(&client->dev);
++ goto unlock_and_return;
++ }
++ } else {
++ __ov9281_stop_stream(ov9281);
++ pm_runtime_put(&client->dev);
++ }
++
++ ov9281->streaming = on;
++
++unlock_and_return:
++ mutex_unlock(&ov9281->mutex);
++
++ return ret;
++}
++
++static int ov9281_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct ov9281 *ov9281 = to_ov9281(sd);
++ struct i2c_client *client = ov9281->client;
++ int ret = 0;
++
++ mutex_lock(&ov9281->mutex);
++
++ /* If the power state is not modified - no work to do. */
++ if (ov9281->power_on == !!on)
++ goto unlock_and_return;
++
++ if (on) {
++ ret = pm_runtime_get_sync(&client->dev);
++ if (ret < 0) {
++ pm_runtime_put_noidle(&client->dev);
++ goto unlock_and_return;
++ }
++ ret = ov9281_write_array(ov9281->client, ov9281_global_regs);
++ if (ret) {
++ v4l2_err(sd, "could not set init registers\n");
++ pm_runtime_put_noidle(&client->dev);
++ goto unlock_and_return;
++ }
++ ov9281->power_on = true;
++ } else {
++ pm_runtime_put(&client->dev);
++ ov9281->power_on = false;
++ }
++
++unlock_and_return:
++ mutex_unlock(&ov9281->mutex);
++
++ return ret;
++}
++
++/* Calculate the delay in us by clock rate and clock cycles */
++static inline u32 ov9281_cal_delay(u32 cycles)
++{
++ return DIV_ROUND_UP(cycles, OV9281_XVCLK_FREQ / 1000 / 1000);
++}
++
++static int __ov9281_power_on(struct ov9281 *ov9281)
++{
++ int ret;
++ u32 delay_us;
++ struct device *dev = &ov9281->client->dev;
++
++ if (!IS_ERR_OR_NULL(ov9281->pins_default)) {
++ ret = pinctrl_select_state(ov9281->pinctrl,
++ ov9281->pins_default);
++ if (ret < 0)
++ dev_err(dev, "could not set pins\n");
++ }
++
++ ret = clk_prepare_enable(ov9281->xvclk);
++ if (ret < 0) {
++ dev_err(dev, "Failed to enable xvclk\n");
++ return ret;
++ }
++
++ if (!IS_ERR(ov9281->reset_gpio))
++ gpiod_set_value_cansleep(ov9281->reset_gpio, 0);
++
++ ret = regulator_bulk_enable(OV9281_NUM_SUPPLIES, ov9281->supplies);
++ if (ret < 0) {
++ dev_err(dev, "Failed to enable regulators\n");
++ goto disable_clk;
++ }
++
++ if (!IS_ERR(ov9281->reset_gpio))
++ gpiod_set_value_cansleep(ov9281->reset_gpio, 1);
++
++ usleep_range(500, 1000);
++ if (!IS_ERR(ov9281->pwdn_gpio))
++ gpiod_set_value_cansleep(ov9281->pwdn_gpio, 1);
++
++ /* 8192 cycles prior to first SCCB transaction */
++ delay_us = ov9281_cal_delay(8192);
++ usleep_range(delay_us, delay_us * 2);
++
++ return 0;
++
++disable_clk:
++ clk_disable_unprepare(ov9281->xvclk);
++
++ return ret;
++}
++
++static void __ov9281_power_off(struct ov9281 *ov9281)
++{
++ int ret;
++ struct device *dev = &ov9281->client->dev;
++
++ if (!IS_ERR(ov9281->pwdn_gpio))
++ gpiod_set_value_cansleep(ov9281->pwdn_gpio, 0);
++ clk_disable_unprepare(ov9281->xvclk);
++ if (!IS_ERR(ov9281->reset_gpio))
++ gpiod_set_value_cansleep(ov9281->reset_gpio, 0);
++ if (!IS_ERR_OR_NULL(ov9281->pins_sleep)) {
++ ret = pinctrl_select_state(ov9281->pinctrl,
++ ov9281->pins_sleep);
++ if (ret < 0)
++ dev_dbg(dev, "could not set pins\n");
++ }
++ regulator_bulk_disable(OV9281_NUM_SUPPLIES, ov9281->supplies);
++}
++
++static int ov9281_runtime_resume(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct ov9281 *ov9281 = to_ov9281(sd);
++
++ return __ov9281_power_on(ov9281);
++}
++
++static int ov9281_runtime_suspend(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct ov9281 *ov9281 = to_ov9281(sd);
++
++ __ov9281_power_off(ov9281);
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
++static int ov9281_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
++{
++ struct ov9281 *ov9281 = to_ov9281(sd);
++ struct v4l2_mbus_framefmt *try_fmt =
++ v4l2_subdev_get_try_format(sd, fh->pad, 0);
++ const struct ov9281_mode *def_mode = &supported_modes[0];
++
++ mutex_lock(&ov9281->mutex);
++ /* Initialize try_fmt */
++ try_fmt->width = def_mode->width;
++ try_fmt->height = def_mode->height;
++ try_fmt->code = MEDIA_BUS_FMT_Y10_1X10;
++ try_fmt->field = V4L2_FIELD_NONE;
++
++ mutex_unlock(&ov9281->mutex);
++ /* No crop or compose */
++
++ return 0;
++}
++#endif
++
++static const struct dev_pm_ops ov9281_pm_ops = {
++ SET_RUNTIME_PM_OPS(ov9281_runtime_suspend,
++ ov9281_runtime_resume, NULL)
++};
++
++#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
++static const struct v4l2_subdev_internal_ops ov9281_internal_ops = {
++ .open = ov9281_open,
++};
++#endif
++
++static const struct v4l2_subdev_core_ops ov9281_core_ops = {
++ .s_power = ov9281_s_power,
++ .ioctl = ov9281_ioctl,
++#ifdef CONFIG_COMPAT
++ .compat_ioctl32 = ov9281_compat_ioctl32,
++#endif
++};
++
++static const struct v4l2_subdev_video_ops ov9281_video_ops = {
++ .s_stream = ov9281_s_stream,
++ .g_frame_interval = OV9281_g_frame_interval,
++};
++
++static const struct v4l2_subdev_pad_ops ov9281_pad_ops = {
++ .enum_mbus_code = ov9281_enum_mbus_code,
++ .enum_frame_size = ov9281_enum_frame_sizes,
++ .get_fmt = ov9281_get_fmt,
++ .set_fmt = ov9281_set_fmt,
++};
++
++static const struct v4l2_subdev_ops ov9281_subdev_ops = {
++ .core = &ov9281_core_ops,
++ .video = &ov9281_video_ops,
++ .pad = &ov9281_pad_ops,
++};
++
++static int ov9281_set_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct ov9281 *ov9281 = container_of(ctrl->handler,
++ struct ov9281, ctrl_handler);
++ struct i2c_client *client = ov9281->client;
++ s64 max;
++ int ret = 0;
++
++ /* Propagate change of current control to all related controls */
++ switch (ctrl->id) {
++ case V4L2_CID_VBLANK:
++ /* Update max exposure while meeting expected vblanking */
++ max = ov9281->cur_mode->height + ctrl->val - 4;
++ __v4l2_ctrl_modify_range(ov9281->exposure,
++ ov9281->exposure->minimum, max,
++ ov9281->exposure->step,
++ ov9281->exposure->default_value);
++ break;
++ }
++
++ if (pm_runtime_get(&client->dev) <= 0)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_EXPOSURE:
++ /* 4 least significant bits of expsoure are fractional part */
++ ret = ov9281_write_reg(ov9281->client, OV9281_REG_EXPOSURE,
++ OV9281_REG_VALUE_24BIT, ctrl->val << 4);
++ break;
++ case V4L2_CID_ANALOGUE_GAIN:
++ ret = ov9281_write_reg(ov9281->client, OV9281_REG_GAIN_H,
++ OV9281_REG_VALUE_08BIT,
++ (ctrl->val >> OV9281_GAIN_H_SHIFT) & OV9281_GAIN_H_MASK);
++ ret |= ov9281_write_reg(ov9281->client, OV9281_REG_GAIN_L,
++ OV9281_REG_VALUE_08BIT,
++ ctrl->val & OV9281_GAIN_L_MASK);
++ break;
++ case V4L2_CID_VBLANK:
++ ret = ov9281_write_reg(ov9281->client, OV9281_REG_VTS,
++ OV9281_REG_VALUE_16BIT,
++ ctrl->val + ov9281->cur_mode->height);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = ov9281_enable_test_pattern(ov9281, ctrl->val);
++ break;
++ default:
++ dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
++ __func__, ctrl->id, ctrl->val);
++ break;
++ }
++
++ pm_runtime_put(&client->dev);
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov9281_ctrl_ops = {
++ .s_ctrl = ov9281_set_ctrl,
++};
++
++static int ov9281_initialize_controls(struct ov9281 *ov9281)
++{
++ const struct ov9281_mode *mode;
++ struct v4l2_ctrl_handler *handler;
++ struct v4l2_ctrl *ctrl;
++ s64 exposure_max, vblank_def;
++ u32 h_blank;
++ int ret;
++
++ handler = &ov9281->ctrl_handler;
++ mode = ov9281->cur_mode;
++ ret = v4l2_ctrl_handler_init(handler, 8);
++ if (ret)
++ return ret;
++ handler->lock = &ov9281->mutex;
++
++ ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
++ 0, 0, link_freq_menu_items);
++ if (ctrl)
++ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++
++ v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
++ 0, OV9281_PIXEL_RATE, 1, OV9281_PIXEL_RATE);
++
++ h_blank = mode->hts_def - mode->width;
++ ov9281->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
++ h_blank, h_blank, 1, h_blank);
++ if (ov9281->hblank)
++ ov9281->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++
++ vblank_def = mode->vts_def - mode->height;
++ ov9281->vblank = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops,
++ V4L2_CID_VBLANK, vblank_def,
++ OV9281_VTS_MAX - mode->height,
++ 1, vblank_def);
++
++ exposure_max = mode->vts_def - 4;
++ ov9281->exposure = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops,
++ V4L2_CID_EXPOSURE, OV9281_EXPOSURE_MIN,
++ exposure_max, OV9281_EXPOSURE_STEP,
++ mode->exp_def);
++
++ ov9281->anal_gain = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops,
++ V4L2_CID_ANALOGUE_GAIN, OV9281_GAIN_MIN,
++ OV9281_GAIN_MAX, OV9281_GAIN_STEP,
++ OV9281_GAIN_DEFAULT);
++
++ ov9281->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
++ &ov9281_ctrl_ops, V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(ov9281_test_pattern_menu) - 1,
++ 0, 0, ov9281_test_pattern_menu);
++
++ if (handler->error) {
++ ret = handler->error;
++ dev_err(&ov9281->client->dev,
++ "Failed to init controls(%d)\n", ret);
++ goto err_free_handler;
++ }
++
++ ov9281->subdev.ctrl_handler = handler;
++
++ return 0;
++
++err_free_handler:
++ v4l2_ctrl_handler_free(handler);
++
++ return ret;
++}
++
++static int ov9281_check_sensor_id(struct ov9281 *ov9281,
++ struct i2c_client *client)
++{
++ struct device *dev = &ov9281->client->dev;
++ u32 id = 0;
++ int ret;
++
++ ret = ov9281_read_reg(client, OV9281_REG_CHIP_ID,
++ OV9281_REG_VALUE_16BIT, &id);
++ if (id != CHIP_ID) {
++ dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
++ return -ENODEV;
++ }
++
++ dev_info(dev, "Detected OV%06x sensor\n", CHIP_ID);
++
++ return 0;
++}
++
++static int ov9281_configure_regulators(struct ov9281 *ov9281)
++{
++ unsigned int i;
++
++ for (i = 0; i < OV9281_NUM_SUPPLIES; i++)
++ ov9281->supplies[i].supply = ov9281_supply_names[i];
++
++ return devm_regulator_bulk_get(&ov9281->client->dev,
++ OV9281_NUM_SUPPLIES,
++ ov9281->supplies);
++}
++
++static int ov9281_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct device *dev = &client->dev;
++ struct device_node *node = dev->of_node;
++ struct ov9281 *ov9281;
++ struct v4l2_subdev *sd;
++ char facing[2];
++ int ret;
++
++ dev_info(dev, "driver version: %02x.%02x.%02x",
++ DRIVER_VERSION >> 16,
++ (DRIVER_VERSION & 0xff00) >> 8,
++ DRIVER_VERSION & 0x00ff);
++
++ ov9281 = devm_kzalloc(dev, sizeof(*ov9281), GFP_KERNEL);
++ if (!ov9281)
++ return -ENOMEM;
++
++ ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
++ &ov9281->module_index);
++ ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
++ &ov9281->module_facing);
++ ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
++ &ov9281->module_name);
++ ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
++ &ov9281->len_name);
++ if (ret) {
++ dev_err(dev, "could not get module information!\n");
++ return -EINVAL;
++ }
++
++ ov9281->client = client;
++ ov9281->cur_mode = &supported_modes[0];
++
++ ov9281->xvclk = devm_clk_get(dev, "xvclk");
++ if (IS_ERR(ov9281->xvclk)) {
++ dev_err(dev, "Failed to get xvclk\n");
++ return -EINVAL;
++ }
++ ret = clk_set_rate(ov9281->xvclk, OV9281_XVCLK_FREQ);
++ if (ret < 0) {
++ dev_err(dev, "Failed to set xvclk rate (24MHz)\n");
++ return ret;
++ }
++ if (clk_get_rate(ov9281->xvclk) != OV9281_XVCLK_FREQ)
++ dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
++
++ ov9281->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
++ if (IS_ERR(ov9281->reset_gpio))
++ dev_warn(dev, "Failed to get reset-gpios\n");
++
++ ov9281->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
++ if (IS_ERR(ov9281->pwdn_gpio))
++ dev_warn(dev, "Failed to get pwdn-gpios\n");
++
++ ov9281->pinctrl = devm_pinctrl_get(dev);
++ if (!IS_ERR(ov9281->pinctrl)) {
++ ov9281->pins_default =
++ pinctrl_lookup_state(ov9281->pinctrl,
++ OF_CAMERA_PINCTRL_STATE_DEFAULT);
++ if (IS_ERR(ov9281->pins_default))
++ dev_err(dev, "could not get default pinstate\n");
++
++ ov9281->pins_sleep =
++ pinctrl_lookup_state(ov9281->pinctrl,
++ OF_CAMERA_PINCTRL_STATE_SLEEP);
++ if (IS_ERR(ov9281->pins_sleep))
++ dev_err(dev, "could not get sleep pinstate\n");
++ } else {
++ dev_err(dev, "no pinctrl\n");
++ }
++
++ ret = ov9281_configure_regulators(ov9281);
++ if (ret) {
++ dev_err(dev, "Failed to get power regulators\n");
++ return ret;
++ }
++
++ mutex_init(&ov9281->mutex);
++
++ sd = &ov9281->subdev;
++ v4l2_i2c_subdev_init(sd, client, &ov9281_subdev_ops);
++ ret = ov9281_initialize_controls(ov9281);
++ if (ret)
++ goto err_destroy_mutex;
++
++ ret = __ov9281_power_on(ov9281);
++ if (ret)
++ goto err_free_handler;
++
++ ret = ov9281_check_sensor_id(ov9281, client);
++ if (ret)
++ goto err_power_off;
++
++#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
++ sd->internal_ops = &ov9281_internal_ops;
++ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++#endif
++#if defined(CONFIG_MEDIA_CONTROLLER)
++ ov9281->pad.flags = MEDIA_PAD_FL_SOURCE;
++ sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
++ ret = media_entity_init(&sd->entity, 1, &ov9281->pad, 0);
++ if (ret < 0)
++ goto err_power_off;
++#endif
++
++ memset(facing, 0, sizeof(facing));
++ if (strcmp(ov9281->module_facing, "back") == 0)
++ facing[0] = 'b';
++ else
++ facing[0] = 'f';
++
++ snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
++ ov9281->module_index, facing,
++ OV9281_NAME, dev_name(sd->dev));
++ ret = v4l2_async_register_subdev_sensor_common(sd);
++ if (ret) {
++ dev_err(dev, "v4l2 async register subdev failed\n");
++ goto err_clean_entity;
++ }
++
++ pm_runtime_set_active(dev);
++ pm_runtime_enable(dev);
++ pm_runtime_idle(dev);
++
++ return 0;
++
++err_clean_entity:
++#if defined(CONFIG_MEDIA_CONTROLLER)
++ media_entity_cleanup(&sd->entity);
++#endif
++err_power_off:
++ __ov9281_power_off(ov9281);
++err_free_handler:
++ v4l2_ctrl_handler_free(&ov9281->ctrl_handler);
++err_destroy_mutex:
++ mutex_destroy(&ov9281->mutex);
++
++ return ret;
++}
++
++static int ov9281_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct ov9281 *ov9281 = to_ov9281(sd);
++
++ v4l2_async_unregister_subdev(sd);
++#if defined(CONFIG_MEDIA_CONTROLLER)
++ media_entity_cleanup(&sd->entity);
++#endif
++ v4l2_ctrl_handler_free(&ov9281->ctrl_handler);
++ mutex_destroy(&ov9281->mutex);
++
++ pm_runtime_disable(&client->dev);
++ if (!pm_runtime_status_suspended(&client->dev))
++ __ov9281_power_off(ov9281);
++ pm_runtime_set_suspended(&client->dev);
++
++ return 0;
++}
++
++#if IS_ENABLED(CONFIG_OF)
++static const struct of_device_id ov9281_of_match[] = {
++ { .compatible = "ovti,ov9281" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, ov9281_of_match);
++#endif
++
++static const struct i2c_device_id ov9281_match_id[] = {
++ { "ovti,ov9281", 0 },
++ { },
++};
++
++static struct i2c_driver ov9281_i2c_driver = {
++ .driver = {
++ .name = OV9281_NAME,
++ .pm = &ov9281_pm_ops,
++ .of_match_table = of_match_ptr(ov9281_of_match),
++ },
++ .probe = &ov9281_probe,
++ .remove = &ov9281_remove,
++ .id_table = ov9281_match_id,
++};
++
++static int __init sensor_mod_init(void)
++{
++ return i2c_add_driver(&ov9281_i2c_driver);
++}
++
++static void __exit sensor_mod_exit(void)
++{
++ i2c_del_driver(&ov9281_i2c_driver);
++}
++
++device_initcall_sync(sensor_mod_init);
++module_exit(sensor_mod_exit);
++
++MODULE_DESCRIPTION("OmniVision ov9281 sensor driver");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/bcm27xx/patches-5.4/950-0871-media-i2c-ov9281-fix-mclk-issue-when-probe-multiple-.patch b/target/linux/bcm27xx/patches-5.4/950-0871-media-i2c-ov9281-fix-mclk-issue-when-probe-multiple-.patch
new file mode 100644
index 0000000000..4a2bbed249
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0871-media-i2c-ov9281-fix-mclk-issue-when-probe-multiple-.patch
@@ -0,0 +1,60 @@
+From a02d918e1bf4dc70c51b630c12182e038d0a73d2 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 14 Apr 2020 15:47:09 +0100
+Subject: [PATCH] media: i2c: ov9281: fix mclk issue when probe
+ multiple camera.
+
+Takes the ov9281 part only from the Rockchip's patch.
+
+Change-Id: I30e833baf2c1bb07d6d87ddb3b00759ab45a90e4
+Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com>
+---
+ drivers/media/i2c/ov9281.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/media/i2c/ov9281.c
++++ b/drivers/media/i2c/ov9281.c
+@@ -3,6 +3,7 @@
+ * ov9281 driver
+ *
+ * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd.
++ * V0.0X01.0X02 fix mclk issue when probe multiple camera.
+ */
+
+ #include <linux/clk.h>
+@@ -22,7 +23,7 @@
+ #include <media/v4l2-subdev.h>
+ #include <linux/pinctrl/consumer.h>
+
+-#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x0)
++#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x2)
+
+ #ifndef V4L2_CID_DIGITAL_GAIN
+ #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
+@@ -676,6 +677,12 @@ static int __ov9281_power_on(struct ov92
+ dev_err(dev, "could not set pins\n");
+ }
+
++ ret = clk_set_rate(ov9281->xvclk, OV9281_XVCLK_FREQ);
++ if (ret < 0)
++ dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
++ if (clk_get_rate(ov9281->xvclk) != OV9281_XVCLK_FREQ)
++ dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
++
+ ret = clk_prepare_enable(ov9281->xvclk);
+ if (ret < 0) {
+ dev_err(dev, "Failed to enable xvclk\n");
+@@ -1008,13 +1015,6 @@ static int ov9281_probe(struct i2c_clien
+ dev_err(dev, "Failed to get xvclk\n");
+ return -EINVAL;
+ }
+- ret = clk_set_rate(ov9281->xvclk, OV9281_XVCLK_FREQ);
+- if (ret < 0) {
+- dev_err(dev, "Failed to set xvclk rate (24MHz)\n");
+- return ret;
+- }
+- if (clk_get_rate(ov9281->xvclk) != OV9281_XVCLK_FREQ)
+- dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
+
+ ov9281->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(ov9281->reset_gpio))
diff --git a/target/linux/bcm27xx/patches-5.4/950-0872-media-i2c-ov9281-add-enum_frame_interval-function-fo.patch b/target/linux/bcm27xx/patches-5.4/950-0872-media-i2c-ov9281-add-enum_frame_interval-function-fo.patch
new file mode 100644
index 0000000000..c772521a9f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0872-media-i2c-ov9281-add-enum_frame_interval-function-fo.patch
@@ -0,0 +1,97 @@
+From c99b6817190eefc77c91567e57fc930656f205bf Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 14 Apr 2020 15:51:50 +0100
+Subject: [PATCH] media: i2c: ov9281: add enum_frame_interval
+ function for iq tool 2.2 and hal3
+
+Adds the ov9281 parts of the Rockchip patch adding enum_frame_interval to
+a large number of drivers.
+
+Change-Id: I03344cd6cf278dd7c18fce8e97479089ef185a5c
+Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com>
+---
+ drivers/media/i2c/ov9281.c | 31 ++++++++++++++++++++++++++-----
+ 1 file changed, 26 insertions(+), 5 deletions(-)
+
+--- a/drivers/media/i2c/ov9281.c
++++ b/drivers/media/i2c/ov9281.c
+@@ -4,6 +4,7 @@
+ *
+ * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd.
+ * V0.0X01.0X02 fix mclk issue when probe multiple camera.
++ * V0.0X01.0X03 add enum_frame_interval function.
+ */
+
+ #include <linux/clk.h>
+@@ -23,7 +24,7 @@
+ #include <media/v4l2-subdev.h>
+ #include <linux/pinctrl/consumer.h>
+
+-#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x2)
++#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x3)
+
+ #ifndef V4L2_CID_DIGITAL_GAIN
+ #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
+@@ -92,7 +93,7 @@ struct regval {
+ struct ov9281_mode {
+ u32 width;
+ u32 height;
+- u32 max_fps;
++ struct v4l2_fract max_fps;
+ u32 hts_def;
+ u32 vts_def;
+ u32 exp_def;
+@@ -246,7 +247,10 @@ static const struct ov9281_mode supporte
+ {
+ .width = 1280,
+ .height = 800,
+- .max_fps = 120,
++ .max_fps = {
++ .numerator = 10000,
++ .denominator = 1200000,
++ },
+ .exp_def = 0x0320,
+ .hts_def = 0x0b60,//0x2d8*4
+ .vts_def = 0x038e,
+@@ -483,8 +487,7 @@ static int OV9281_g_frame_interval(struc
+ const struct ov9281_mode *mode = ov9281->cur_mode;
+
+ mutex_lock(&ov9281->mutex);
+- fi->interval.numerator = 10000;
+- fi->interval.denominator = mode->max_fps * 10000;
++ fi->interval = mode->max_fps;
+ mutex_unlock(&ov9281->mutex);
+
+ return 0;
+@@ -778,6 +781,23 @@ static int ov9281_open(struct v4l2_subde
+ }
+ #endif
+
++static int
++ov9281_enum_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_frame_interval_enum *fie)
++{
++ if (fie->index >= ARRAY_SIZE(supported_modes))
++ return -EINVAL;
++
++ if (fie->code != MEDIA_BUS_FMT_Y10_1X10)
++ return -EINVAL;
++
++ fie->width = supported_modes[fie->index].width;
++ fie->height = supported_modes[fie->index].height;
++ fie->interval = supported_modes[fie->index].max_fps;
++ return 0;
++}
++
+ static const struct dev_pm_ops ov9281_pm_ops = {
+ SET_RUNTIME_PM_OPS(ov9281_runtime_suspend,
+ ov9281_runtime_resume, NULL)
+@@ -805,6 +825,7 @@ static const struct v4l2_subdev_video_op
+ static const struct v4l2_subdev_pad_ops ov9281_pad_ops = {
+ .enum_mbus_code = ov9281_enum_mbus_code,
+ .enum_frame_size = ov9281_enum_frame_sizes,
++ .enum_frame_interval = ov9281_enum_frame_interval,
+ .get_fmt = ov9281_get_fmt,
+ .set_fmt = ov9281_set_fmt,
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0873-media-i2c-ov9281-Fixup-for-recent-kernel-releases-an.patch b/target/linux/bcm27xx/patches-5.4/950-0873-media-i2c-ov9281-Fixup-for-recent-kernel-releases-an.patch
new file mode 100644
index 0000000000..4f3bcf35cf
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0873-media-i2c-ov9281-Fixup-for-recent-kernel-releases-an.patch
@@ -0,0 +1,693 @@
+From 898198428aa35f52c2b58c037e960dcbcc4ef9d8 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 14 Apr 2020 16:12:33 +0100
+Subject: [PATCH] media: i2c: ov9281: Fixup for recent kernel
+ releases, and remove custom code
+
+The Rockchip driver was based on a 4.4 kernel, and had several custom
+Rockchip parts.
+
+Update to 5.4 kernel APIs, with the relevant controls required by
+libcamera, and remove custom Rockchip parts.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/Kconfig | 2 +-
+ drivers/media/i2c/ov9281.c | 361 +++++++++++++------------------------
+ 2 files changed, 123 insertions(+), 240 deletions(-)
+
+--- a/drivers/media/i2c/Kconfig
++++ b/drivers/media/i2c/Kconfig
+@@ -857,7 +857,7 @@ config VIDEO_OV9640
+
+ config VIDEO_OV9281
+ tristate "OmniVision OV9281 sensor support"
+- depends on I2C && VIDEO_V4L2
++ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ depends on MEDIA_CAMERA_SUPPORT
+ help
+ This is a Video4Linux2 sensor-level driver for the OmniVision
+--- a/drivers/media/i2c/ov9281.c
++++ b/drivers/media/i2c/ov9281.c
+@@ -1,6 +1,11 @@
+ // SPDX-License-Identifier: GPL-2.0
+ /*
+- * ov9281 driver
++ * Omnivision OV9281 1280x800 global shutter image sensor driver
++ *
++ * This driver has been taken from
++ * https://github.com/rockchip-linux/kernel/blob/develop-4.4/drivers/media/i2c/ov9281.c
++ * cleaned up, made to compile against mainline kernels instead of the Rockchip
++ * vendor kernel, and the relevant controls added to work with libcamera.
+ *
+ * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd.
+ * V0.0X01.0X02 fix mclk issue when probe multiple camera.
+@@ -17,22 +22,18 @@
+ #include <linux/regulator/consumer.h>
+ #include <linux/sysfs.h>
+ #include <linux/slab.h>
+-#include <linux/rk-camera-module.h>
+ #include <media/media-entity.h>
+ #include <media/v4l2-async.h>
+ #include <media/v4l2-ctrls.h>
+ #include <media/v4l2-subdev.h>
+-#include <linux/pinctrl/consumer.h>
+-
+-#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x3)
+-
+-#ifndef V4L2_CID_DIGITAL_GAIN
+-#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
+-#endif
+
+ #define OV9281_LINK_FREQ_400MHZ 400000000
++#define OV9281_LANES 2
++#define OV9281_BITS_PER_SAMPLE 10
++
+ /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
+-#define OV9281_PIXEL_RATE (OV9281_LINK_FREQ_400MHZ * 2 * 2 / 10)
++#define OV9281_PIXEL_RATE (OV9281_LINK_FREQ_400MHZ * 2 * \
++ OV9281_LANES / OV9281_BITS_PER_SAMPLE)
+ #define OV9281_XVCLK_FREQ 24000000
+
+ #define CHIP_ID 0x9281
+@@ -63,18 +64,24 @@
+
+ #define OV9281_REG_VTS 0x380e
+
++/*
++ * OV9281 native and active pixel array size.
++ * Datasheet not available to confirm these values, so assume there are no
++ * border pixels.
++ */
++#define OV9281_NATIVE_WIDTH 1280U
++#define OV9281_NATIVE_HEIGHT 800U
++#define OV9281_PIXEL_ARRAY_LEFT 0U
++#define OV9281_PIXEL_ARRAY_TOP 0U
++#define OV9281_PIXEL_ARRAY_WIDTH 1280U
++#define OV9281_PIXEL_ARRAY_HEIGHT 800U
++
+ #define REG_NULL 0xFFFF
+
+ #define OV9281_REG_VALUE_08BIT 1
+ #define OV9281_REG_VALUE_16BIT 2
+ #define OV9281_REG_VALUE_24BIT 3
+
+-#define OV9281_LANES 2
+-#define OV9281_BITS_PER_SAMPLE 10
+-
+-#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
+-#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
+-
+ #define OV9281_NAME "ov9281"
+
+ static const char * const ov9281_supply_names[] = {
+@@ -93,10 +100,10 @@ struct regval {
+ struct ov9281_mode {
+ u32 width;
+ u32 height;
+- struct v4l2_fract max_fps;
+ u32 hts_def;
+ u32 vts_def;
+ u32 exp_def;
++ struct v4l2_rect crop;
+ const struct regval *reg_list;
+ };
+
+@@ -107,10 +114,6 @@ struct ov9281 {
+ struct gpio_desc *pwdn_gpio;
+ struct regulator_bulk_data supplies[OV9281_NUM_SUPPLIES];
+
+- struct pinctrl *pinctrl;
+- struct pinctrl_state *pins_default;
+- struct pinctrl_state *pins_sleep;
+-
+ struct v4l2_subdev subdev;
+ struct media_pad pad;
+ struct v4l2_ctrl_handler ctrl_handler;
+@@ -124,23 +127,12 @@ struct ov9281 {
+ bool streaming;
+ bool power_on;
+ const struct ov9281_mode *cur_mode;
+- u32 module_index;
+- const char *module_facing;
+- const char *module_name;
+- const char *len_name;
+ };
+
+ #define to_ov9281(sd) container_of(sd, struct ov9281, subdev)
+
+ /*
+ * Xclk 24Mhz
+- */
+-static const struct regval ov9281_global_regs[] = {
+- {REG_NULL, 0x00},
+-};
+-
+-/*
+- * Xclk 24Mhz
+ * max_framerate 120fps
+ * mipi_datarate per lane 800Mbps
+ */
+@@ -247,13 +239,15 @@ static const struct ov9281_mode supporte
+ {
+ .width = 1280,
+ .height = 800,
+- .max_fps = {
+- .numerator = 10000,
+- .denominator = 1200000,
+- },
+ .exp_def = 0x0320,
+- .hts_def = 0x0b60,//0x2d8*4
++ .hts_def = 0x05b0, /* 0x2d8*2 */
+ .vts_def = 0x038e,
++ .crop = {
++ .left = 0,
++ .top = 0,
++ .width = 1280,
++ .height = 800
++ },
+ .reg_list = ov9281_1280x800_regs,
+ },
+ };
+@@ -389,22 +383,28 @@ static int ov9281_set_fmt(struct v4l2_su
+ fmt->format.width = mode->width;
+ fmt->format.height = mode->height;
+ fmt->format.field = V4L2_FIELD_NONE;
++ fmt->format.colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->format.ycbcr_enc =
++ V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->format.colorspace);
++ fmt->format.quantization =
++ V4L2_MAP_QUANTIZATION_DEFAULT(true, fmt->format.colorspace,
++ fmt->format.ycbcr_enc);
++ fmt->format.xfer_func =
++ V4L2_MAP_XFER_FUNC_DEFAULT(fmt->format.colorspace);
++
+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+-#else
+- mutex_unlock(&ov9281->mutex);
+- return -ENOTTY;
+-#endif
+ } else {
+ ov9281->cur_mode = mode;
+ h_blank = mode->hts_def - mode->width;
+ __v4l2_ctrl_modify_range(ov9281->hblank, h_blank,
+ h_blank, 1, h_blank);
++ __v4l2_ctrl_s_ctrl(ov9281->hblank, h_blank);
+ vblank_def = mode->vts_def - mode->height;
+ __v4l2_ctrl_modify_range(ov9281->vblank, vblank_def,
+ OV9281_VTS_MAX - mode->height,
+ 1, vblank_def);
++ __v4l2_ctrl_s_ctrl(ov9281->vblank, vblank_def);
+ }
+
+ mutex_unlock(&ov9281->mutex);
+@@ -421,17 +421,21 @@ static int ov9281_get_fmt(struct v4l2_su
+
+ mutex_lock(&ov9281->mutex);
+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+-#else
+- mutex_unlock(&ov9281->mutex);
+- return -ENOTTY;
+-#endif
+ } else {
+ fmt->format.width = mode->width;
+ fmt->format.height = mode->height;
+ fmt->format.code = MEDIA_BUS_FMT_Y10_1X10;
+ fmt->format.field = V4L2_FIELD_NONE;
++ fmt->format.colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->format.ycbcr_enc =
++ V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->format.colorspace);
++ fmt->format.quantization =
++ V4L2_MAP_QUANTIZATION_DEFAULT(true,
++ fmt->format.colorspace,
++ fmt->format.ycbcr_enc);
++ fmt->format.xfer_func =
++ V4L2_MAP_XFER_FUNC_DEFAULT(fmt->format.colorspace);
+ }
+ mutex_unlock(&ov9281->mutex);
+
+@@ -442,7 +446,7 @@ static int ov9281_enum_mbus_code(struct
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+ {
+- if (code->index != 0)
++ if (code->index)
+ return -EINVAL;
+ code->code = MEDIA_BUS_FMT_Y10_1X10;
+
+@@ -480,88 +484,56 @@ static int ov9281_enable_test_pattern(st
+ OV9281_REG_VALUE_08BIT, val);
+ }
+
+-static int OV9281_g_frame_interval(struct v4l2_subdev *sd,
+- struct v4l2_subdev_frame_interval *fi)
+-{
+- struct ov9281 *ov9281 = to_ov9281(sd);
+- const struct ov9281_mode *mode = ov9281->cur_mode;
+-
+- mutex_lock(&ov9281->mutex);
+- fi->interval = mode->max_fps;
+- mutex_unlock(&ov9281->mutex);
++static const struct v4l2_rect *
++__ov9281_get_pad_crop(struct ov9281 *ov9281, struct v4l2_subdev_pad_config *cfg,
++ unsigned int pad, enum v4l2_subdev_format_whence which)
++{
++ switch (which) {
++ case V4L2_SUBDEV_FORMAT_TRY:
++ return v4l2_subdev_get_try_crop(&ov9281->subdev, cfg, pad);
++ case V4L2_SUBDEV_FORMAT_ACTIVE:
++ return &ov9281->cur_mode->crop;
++ }
+
+- return 0;
++ return NULL;
+ }
+
+-static void ov9281_get_module_inf(struct ov9281 *ov9281,
+- struct rkmodule_inf *inf)
++static int ov9281_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
+ {
+- memset(inf, 0, sizeof(*inf));
+- strlcpy(inf->base.sensor, OV9281_NAME, sizeof(inf->base.sensor));
+- strlcpy(inf->base.module, ov9281->module_name,
+- sizeof(inf->base.module));
+- strlcpy(inf->base.lens, ov9281->len_name, sizeof(inf->base.lens));
+-}
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP: {
++ struct ov9281 *ov9281 = to_ov9281(sd);
+
+-static long ov9281_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+-{
+- struct ov9281 *ov9281 = to_ov9281(sd);
+- long ret = 0;
++ mutex_lock(&ov9281->mutex);
++ sel->r = *__ov9281_get_pad_crop(ov9281, cfg, sel->pad,
++ sel->which);
++ mutex_unlock(&ov9281->mutex);
+
+- switch (cmd) {
+- case RKMODULE_GET_MODULE_INFO:
+- ov9281_get_module_inf(ov9281, (struct rkmodule_inf *)arg);
+- break;
+- default:
+- ret = -ENOIOCTLCMD;
+- break;
++ return 0;
+ }
+
+- return ret;
+-}
++ case V4L2_SEL_TGT_NATIVE_SIZE:
++ sel->r.top = 0;
++ sel->r.left = 0;
++ sel->r.width = OV9281_NATIVE_WIDTH;
++ sel->r.height = OV9281_NATIVE_HEIGHT;
+
+-#ifdef CONFIG_COMPAT
+-static long ov9281_compat_ioctl32(struct v4l2_subdev *sd,
+- unsigned int cmd, unsigned long arg)
+-{
+- void __user *up = compat_ptr(arg);
+- struct rkmodule_inf *inf;
+- struct rkmodule_awb_cfg *cfg;
+- long ret;
+-
+- switch (cmd) {
+- case RKMODULE_GET_MODULE_INFO:
+- inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+- if (!inf) {
+- ret = -ENOMEM;
+- return ret;
+- }
++ return 0;
+
+- ret = ov9281_ioctl(sd, cmd, inf);
+- if (!ret)
+- ret = copy_to_user(up, inf, sizeof(*inf));
+- kfree(inf);
+- break;
+- case RKMODULE_AWB_CFG:
+- cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+- if (!cfg) {
+- ret = -ENOMEM;
+- return ret;
+- }
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.top = OV9281_PIXEL_ARRAY_TOP;
++ sel->r.left = OV9281_PIXEL_ARRAY_LEFT;
++ sel->r.width = OV9281_PIXEL_ARRAY_WIDTH;
++ sel->r.height = OV9281_PIXEL_ARRAY_HEIGHT;
+
+- ret = copy_from_user(cfg, up, sizeof(*cfg));
+- if (!ret)
+- ret = ov9281_ioctl(sd, cmd, cfg);
+- kfree(cfg);
+- break;
+- default:
+- ret = -ENOIOCTLCMD;
+- break;
++ return 0;
+ }
+
+- return ret;
++ return -EINVAL;
+ }
+-#endif
+
+ static int __ov9281_start_stream(struct ov9281 *ov9281)
+ {
+@@ -643,12 +615,6 @@ static int ov9281_s_power(struct v4l2_su
+ pm_runtime_put_noidle(&client->dev);
+ goto unlock_and_return;
+ }
+- ret = ov9281_write_array(ov9281->client, ov9281_global_regs);
+- if (ret) {
+- v4l2_err(sd, "could not set init registers\n");
+- pm_runtime_put_noidle(&client->dev);
+- goto unlock_and_return;
+- }
+ ov9281->power_on = true;
+ } else {
+ pm_runtime_put(&client->dev);
+@@ -673,18 +639,12 @@ static int __ov9281_power_on(struct ov92
+ u32 delay_us;
+ struct device *dev = &ov9281->client->dev;
+
+- if (!IS_ERR_OR_NULL(ov9281->pins_default)) {
+- ret = pinctrl_select_state(ov9281->pinctrl,
+- ov9281->pins_default);
+- if (ret < 0)
+- dev_err(dev, "could not set pins\n");
+- }
+-
+ ret = clk_set_rate(ov9281->xvclk, OV9281_XVCLK_FREQ);
+ if (ret < 0)
+ dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
+ if (clk_get_rate(ov9281->xvclk) != OV9281_XVCLK_FREQ)
+- dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
++ dev_warn(dev, "xvclk mismatched, modes are based on 24MHz - rate is %lu\n",
++ clk_get_rate(ov9281->xvclk));
+
+ ret = clk_prepare_enable(ov9281->xvclk);
+ if (ret < 0) {
+@@ -722,20 +682,11 @@ disable_clk:
+
+ static void __ov9281_power_off(struct ov9281 *ov9281)
+ {
+- int ret;
+- struct device *dev = &ov9281->client->dev;
+-
+ if (!IS_ERR(ov9281->pwdn_gpio))
+ gpiod_set_value_cansleep(ov9281->pwdn_gpio, 0);
+ clk_disable_unprepare(ov9281->xvclk);
+ if (!IS_ERR(ov9281->reset_gpio))
+ gpiod_set_value_cansleep(ov9281->reset_gpio, 0);
+- if (!IS_ERR_OR_NULL(ov9281->pins_sleep)) {
+- ret = pinctrl_select_state(ov9281->pinctrl,
+- ov9281->pins_sleep);
+- if (ret < 0)
+- dev_dbg(dev, "could not set pins\n");
+- }
+ regulator_bulk_disable(OV9281_NUM_SUPPLIES, ov9281->supplies);
+ }
+
+@@ -759,7 +710,6 @@ static int ov9281_runtime_suspend(struct
+ return 0;
+ }
+
+-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ static int ov9281_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+ {
+ struct ov9281 *ov9281 = to_ov9281(sd);
+@@ -773,61 +723,42 @@ static int ov9281_open(struct v4l2_subde
+ try_fmt->height = def_mode->height;
+ try_fmt->code = MEDIA_BUS_FMT_Y10_1X10;
+ try_fmt->field = V4L2_FIELD_NONE;
++ try_fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ try_fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(try_fmt->colorspace);
++ try_fmt->quantization =
++ V4L2_MAP_QUANTIZATION_DEFAULT(true, try_fmt->colorspace,
++ try_fmt->ycbcr_enc);
++ try_fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(try_fmt->colorspace);
+
+ mutex_unlock(&ov9281->mutex);
+ /* No crop or compose */
+
+ return 0;
+ }
+-#endif
+-
+-static int
+-ov9281_enum_frame_interval(struct v4l2_subdev *sd,
+- struct v4l2_subdev_pad_config *cfg,
+- struct v4l2_subdev_frame_interval_enum *fie)
+-{
+- if (fie->index >= ARRAY_SIZE(supported_modes))
+- return -EINVAL;
+-
+- if (fie->code != MEDIA_BUS_FMT_Y10_1X10)
+- return -EINVAL;
+-
+- fie->width = supported_modes[fie->index].width;
+- fie->height = supported_modes[fie->index].height;
+- fie->interval = supported_modes[fie->index].max_fps;
+- return 0;
+-}
+
+ static const struct dev_pm_ops ov9281_pm_ops = {
+ SET_RUNTIME_PM_OPS(ov9281_runtime_suspend,
+ ov9281_runtime_resume, NULL)
+ };
+
+-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ static const struct v4l2_subdev_internal_ops ov9281_internal_ops = {
+ .open = ov9281_open,
+ };
+-#endif
+
+ static const struct v4l2_subdev_core_ops ov9281_core_ops = {
+ .s_power = ov9281_s_power,
+- .ioctl = ov9281_ioctl,
+-#ifdef CONFIG_COMPAT
+- .compat_ioctl32 = ov9281_compat_ioctl32,
+-#endif
+ };
+
+ static const struct v4l2_subdev_video_ops ov9281_video_ops = {
+ .s_stream = ov9281_s_stream,
+- .g_frame_interval = OV9281_g_frame_interval,
+ };
+
+ static const struct v4l2_subdev_pad_ops ov9281_pad_ops = {
+ .enum_mbus_code = ov9281_enum_mbus_code,
+ .enum_frame_size = ov9281_enum_frame_sizes,
+- .enum_frame_interval = ov9281_enum_frame_interval,
+ .get_fmt = ov9281_get_fmt,
+ .set_fmt = ov9281_set_fmt,
++ .get_selection = ov9281_get_selection,
+ };
+
+ static const struct v4l2_subdev_ops ov9281_subdev_ops = {
+@@ -868,7 +799,8 @@ static int ov9281_set_ctrl(struct v4l2_c
+ case V4L2_CID_ANALOGUE_GAIN:
+ ret = ov9281_write_reg(ov9281->client, OV9281_REG_GAIN_H,
+ OV9281_REG_VALUE_08BIT,
+- (ctrl->val >> OV9281_GAIN_H_SHIFT) & OV9281_GAIN_H_MASK);
++ (ctrl->val >> OV9281_GAIN_H_SHIFT) &
++ OV9281_GAIN_H_MASK);
+ ret |= ov9281_write_reg(ov9281->client, OV9281_REG_GAIN_L,
+ OV9281_REG_VALUE_08BIT,
+ ctrl->val & OV9281_GAIN_L_MASK);
+@@ -922,31 +854,34 @@ static int ov9281_initialize_controls(st
+
+ h_blank = mode->hts_def - mode->width;
+ ov9281->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
+- h_blank, h_blank, 1, h_blank);
++ h_blank, h_blank, 1, h_blank);
+ if (ov9281->hblank)
+ ov9281->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ vblank_def = mode->vts_def - mode->height;
+ ov9281->vblank = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops,
+- V4L2_CID_VBLANK, vblank_def,
+- OV9281_VTS_MAX - mode->height,
+- 1, vblank_def);
++ V4L2_CID_VBLANK, vblank_def,
++ OV9281_VTS_MAX - mode->height, 1,
++ vblank_def);
+
+ exposure_max = mode->vts_def - 4;
+ ov9281->exposure = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops,
+- V4L2_CID_EXPOSURE, OV9281_EXPOSURE_MIN,
+- exposure_max, OV9281_EXPOSURE_STEP,
+- mode->exp_def);
++ V4L2_CID_EXPOSURE,
++ OV9281_EXPOSURE_MIN, exposure_max,
++ OV9281_EXPOSURE_STEP,
++ mode->exp_def);
+
+ ov9281->anal_gain = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops,
+- V4L2_CID_ANALOGUE_GAIN, OV9281_GAIN_MIN,
+- OV9281_GAIN_MAX, OV9281_GAIN_STEP,
+- OV9281_GAIN_DEFAULT);
+-
+- ov9281->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
+- &ov9281_ctrl_ops, V4L2_CID_TEST_PATTERN,
+- ARRAY_SIZE(ov9281_test_pattern_menu) - 1,
+- 0, 0, ov9281_test_pattern_menu);
++ V4L2_CID_ANALOGUE_GAIN,
++ OV9281_GAIN_MIN, OV9281_GAIN_MAX,
++ OV9281_GAIN_STEP,
++ OV9281_GAIN_DEFAULT);
++
++ ov9281->test_pattern =
++ v4l2_ctrl_new_std_menu_items(handler, &ov9281_ctrl_ops,
++ V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(ov9281_test_pattern_menu) - 1,
++ 0, 0, ov9281_test_pattern_menu);
+
+ if (handler->error) {
+ ret = handler->error;
+@@ -1000,34 +935,14 @@ static int ov9281_probe(struct i2c_clien
+ const struct i2c_device_id *id)
+ {
+ struct device *dev = &client->dev;
+- struct device_node *node = dev->of_node;
+ struct ov9281 *ov9281;
+ struct v4l2_subdev *sd;
+- char facing[2];
+ int ret;
+
+- dev_info(dev, "driver version: %02x.%02x.%02x",
+- DRIVER_VERSION >> 16,
+- (DRIVER_VERSION & 0xff00) >> 8,
+- DRIVER_VERSION & 0x00ff);
+-
+ ov9281 = devm_kzalloc(dev, sizeof(*ov9281), GFP_KERNEL);
+ if (!ov9281)
+ return -ENOMEM;
+
+- ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
+- &ov9281->module_index);
+- ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
+- &ov9281->module_facing);
+- ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
+- &ov9281->module_name);
+- ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
+- &ov9281->len_name);
+- if (ret) {
+- dev_err(dev, "could not get module information!\n");
+- return -EINVAL;
+- }
+-
+ ov9281->client = client;
+ ov9281->cur_mode = &supported_modes[0];
+
+@@ -1037,31 +952,15 @@ static int ov9281_probe(struct i2c_clien
+ return -EINVAL;
+ }
+
+- ov9281->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
++ ov9281->reset_gpio = devm_gpiod_get_optional(dev, "reset",
++ GPIOD_OUT_LOW);
+ if (IS_ERR(ov9281->reset_gpio))
+ dev_warn(dev, "Failed to get reset-gpios\n");
+
+- ov9281->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
++ ov9281->pwdn_gpio = devm_gpiod_get_optional(dev, "pwdn", GPIOD_OUT_LOW);
+ if (IS_ERR(ov9281->pwdn_gpio))
+ dev_warn(dev, "Failed to get pwdn-gpios\n");
+
+- ov9281->pinctrl = devm_pinctrl_get(dev);
+- if (!IS_ERR(ov9281->pinctrl)) {
+- ov9281->pins_default =
+- pinctrl_lookup_state(ov9281->pinctrl,
+- OF_CAMERA_PINCTRL_STATE_DEFAULT);
+- if (IS_ERR(ov9281->pins_default))
+- dev_err(dev, "could not get default pinstate\n");
+-
+- ov9281->pins_sleep =
+- pinctrl_lookup_state(ov9281->pinctrl,
+- OF_CAMERA_PINCTRL_STATE_SLEEP);
+- if (IS_ERR(ov9281->pins_sleep))
+- dev_err(dev, "could not get sleep pinstate\n");
+- } else {
+- dev_err(dev, "no pinctrl\n");
+- }
+-
+ ret = ov9281_configure_regulators(ov9281);
+ if (ret) {
+ dev_err(dev, "Failed to get power regulators\n");
+@@ -1084,26 +983,16 @@ static int ov9281_probe(struct i2c_clien
+ if (ret)
+ goto err_power_off;
+
+-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ sd->internal_ops = &ov9281_internal_ops;
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+-#endif
+-#if defined(CONFIG_MEDIA_CONTROLLER)
++
+ ov9281->pad.flags = MEDIA_PAD_FL_SOURCE;
+- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
+- ret = media_entity_init(&sd->entity, 1, &ov9281->pad, 0);
++ sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&sd->entity, 1, &ov9281->pad);
+ if (ret < 0)
+ goto err_power_off;
+-#endif
+-
+- memset(facing, 0, sizeof(facing));
+- if (strcmp(ov9281->module_facing, "back") == 0)
+- facing[0] = 'b';
+- else
+- facing[0] = 'f';
+
+- snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
+- ov9281->module_index, facing,
++ snprintf(sd->name, sizeof(sd->name), "m%s %s",
+ OV9281_NAME, dev_name(sd->dev));
+ ret = v4l2_async_register_subdev_sensor_common(sd);
+ if (ret) {
+@@ -1118,9 +1007,7 @@ static int ov9281_probe(struct i2c_clien
+ return 0;
+
+ err_clean_entity:
+-#if defined(CONFIG_MEDIA_CONTROLLER)
+ media_entity_cleanup(&sd->entity);
+-#endif
+ err_power_off:
+ __ov9281_power_off(ov9281);
+ err_free_handler:
+@@ -1137,9 +1024,7 @@ static int ov9281_remove(struct i2c_clie
+ struct ov9281 *ov9281 = to_ov9281(sd);
+
+ v4l2_async_unregister_subdev(sd);
+-#if defined(CONFIG_MEDIA_CONTROLLER)
+ media_entity_cleanup(&sd->entity);
+-#endif
+ v4l2_ctrl_handler_free(&ov9281->ctrl_handler);
+ mutex_destroy(&ov9281->mutex);
+
+@@ -1151,13 +1036,11 @@ static int ov9281_remove(struct i2c_clie
+ return 0;
+ }
+
+-#if IS_ENABLED(CONFIG_OF)
+ static const struct of_device_id ov9281_of_match[] = {
+ { .compatible = "ovti,ov9281" },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, ov9281_of_match);
+-#endif
+
+ static const struct i2c_device_id ov9281_match_id[] = {
+ { "ovti,ov9281", 0 },
diff --git a/target/linux/bcm27xx/patches-5.4/950-0874-media-i2c-ov9281-Read-chip-ID-via-2-reads.patch b/target/linux/bcm27xx/patches-5.4/950-0874-media-i2c-ov9281-Read-chip-ID-via-2-reads.patch
new file mode 100644
index 0000000000..0b06442a3e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0874-media-i2c-ov9281-Read-chip-ID-via-2-reads.patch
@@ -0,0 +1,42 @@
+From 5c6b7b60d7d607b59b4208e758180d4f93be8788 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Mon, 6 Jul 2020 17:51:32 +0100
+Subject: [PATCH] media: i2c: ov9281: Read chip ID via 2 reads
+
+Vision Components have made an OV9281 module which blocks reading
+back the majority of registers to comply with NDAs, and in doing
+so doesn't allow auto-increment register reading as used when
+reading the chip ID.
+
+Use two reads and manually combine the results.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/ov9281.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/drivers/media/i2c/ov9281.c
++++ b/drivers/media/i2c/ov9281.c
+@@ -904,13 +904,17 @@ static int ov9281_check_sensor_id(struct
+ struct i2c_client *client)
+ {
+ struct device *dev = &ov9281->client->dev;
+- u32 id = 0;
++ u32 id = 0, id_msb;
+ int ret;
+
+- ret = ov9281_read_reg(client, OV9281_REG_CHIP_ID,
+- OV9281_REG_VALUE_16BIT, &id);
+- if (id != CHIP_ID) {
+- dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
++ ret = ov9281_read_reg(client, OV9281_REG_CHIP_ID + 1,
++ OV9281_REG_VALUE_08BIT, &id);
++ if (!ret)
++ ret = ov9281_read_reg(client, OV9281_REG_CHIP_ID,
++ OV9281_REG_VALUE_08BIT, &id_msb);
++ id |= (id_msb << 8);
++ if (ret || id != CHIP_ID) {
++ dev_err(dev, "Unexpected sensor id(%04x), ret(%d)\n", id, ret);
+ return -ENODEV;
+ }
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0875-dtoverlay-Add-overlay-for-Omnivision-OV9281-image-se.patch b/target/linux/bcm27xx/patches-5.4/950-0875-dtoverlay-Add-overlay-for-Omnivision-OV9281-image-se.patch
new file mode 100644
index 0000000000..c1664532ff
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0875-dtoverlay-Add-overlay-for-Omnivision-OV9281-image-se.patch
@@ -0,0 +1,157 @@
+From 489b7fc3df2013766f3c4d5f682dcc7992950293 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Mon, 6 Jul 2020 17:32:21 +0100
+Subject: [PATCH] dtoverlay: Add overlay for Omnivision OV9281 image
+ sensor
+
+Adds an overlay for the OV9281 mono imaging sensor using 2 CSI-2
+data lanes.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 8 ++
+ arch/arm/boot/dts/overlays/ov9281-overlay.dts | 110 ++++++++++++++++++
+ 3 files changed, 119 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/ov9281-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -115,6 +115,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ mpu6050.dtbo \
+ mz61581.dtbo \
+ ov5647.dtbo \
++ ov9281.dtbo \
+ papirus.dtbo \
+ pibell.dtbo \
+ piglow.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1813,6 +1813,14 @@ Load: dtoverlay=ov5647
+ Params: <None>
+
+
++Name: ov9281
++Info: Omnivision OV9281 camera module.
++ Uses Unicam 1, which is the standard camera connector on most Pi
++ variants.
++Load: dtoverlay=ov9281
++Params: <None>
++
++
+ Name: papirus
+ Info: PaPiRus ePaper Screen by Pi Supply (both HAT and pHAT)
+ Load: dtoverlay=papirus,<param>=<val>
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/ov9281-overlay.dts
+@@ -0,0 +1,110 @@
++// SPDX-License-Identifier: GPL-2.0-only
++// Definitions for OV9281 camera module on VC I2C bus
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++
++/{
++ compatible = "brcm,bcm2835";
++
++ fragment@0 {
++ target = <&i2c_csi_dsi>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ ov9281: ov9281@60 {
++ compatible = "ovti,ov9281";
++ reg = <0x60>;
++ status = "okay";
++
++ clocks = <&ov9281_clk>;
++ clock-names = "xvclk";
++
++ avdd-supply = <&ov9281_avdd>;
++ dovdd-supply = <&ov9281_dovdd>;
++ dvdd-supply = <&ov9281_dvdd>;
++
++ port {
++ ov9281_0: endpoint {
++ remote-endpoint = <&csi1_ep>;
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ clock-noncontinuous;
++ link-frequencies =
++ /bits/ 64 <456000000>;
++ };
++ };
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&csi1>;
++ __overlay__ {
++ status = "okay";
++
++ port {
++ csi1_ep: endpoint {
++ remote-endpoint = <&ov9281_0>;
++ data-lanes = <1 2>;
++ };
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&i2c0if>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@3 {
++ target-path="/";
++ __overlay__ {
++ ov9281_avdd: fixedregulator@0 {
++ compatible = "regulator-fixed";
++ regulator-name = "ov9281_avdd";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ gpio = <&gpio 41 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++ ov9281_dovdd: fixedregulator@1 {
++ compatible = "regulator-fixed";
++ regulator-name = "ov9281_dovdd";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++ ov9281_dvdd: fixedregulator@2 {
++ compatible = "regulator-fixed";
++ regulator-name = "ov9281_dvdd";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
++ };
++ ov9281_clk: ov9281-clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ };
++ };
++ };
++
++ fragment@4 {
++ target = <&i2c0mux>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@5 {
++ target-path="/__overrides__";
++ __overlay__ {
++ cam0-pwdn-ctrl = <&ov9281_avdd>,"gpio:0";
++ cam0-pwdn = <&ov9281_avdd>,"gpio:4";
++ };
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-0876-Bluetooth-hci_bcm-Fix-RTS-handling-during-startup.patch b/target/linux/bcm27xx/patches-5.4/950-0876-Bluetooth-hci_bcm-Fix-RTS-handling-during-startup.patch
new file mode 100644
index 0000000000..a288f5ed3c
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0876-Bluetooth-hci_bcm-Fix-RTS-handling-during-startup.patch
@@ -0,0 +1,33 @@
+From 44843cf006346751e42c0f4100eea7cefe61cbdf Mon Sep 17 00:00:00 2001
+From: Stefan Wahren <wahrenst@gmx.net>
+Date: Sun, 6 Oct 2019 17:28:19 +0200
+Subject: [PATCH] Bluetooth: hci_bcm: Fix RTS handling during startup
+
+commit 3347a80965b38f096b1d6f995c00c9c9e53d4b8b upstream.
+
+The RPi 4 uses the hardware handshake lines for CYW43455, but the chip
+doesn't react to HCI requests during DT probe. The reason is the inproper
+handling of the RTS line during startup. According to the startup
+signaling sequence in the CYW43455 datasheet, the hosts RTS line must
+be driven after BT_REG_ON and BT_HOST_WAKE.
+
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+---
+ drivers/bluetooth/hci_bcm.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/bluetooth/hci_bcm.c
++++ b/drivers/bluetooth/hci_bcm.c
+@@ -448,9 +448,11 @@ static int bcm_open(struct hci_uart *hu)
+
+ out:
+ if (bcm->dev) {
++ hci_uart_set_flow_control(hu, true);
+ hu->init_speed = bcm->dev->init_speed;
+ hu->oper_speed = bcm->dev->oper_speed;
+ err = bcm_gpio_set_power(bcm->dev, true);
++ hci_uart_set_flow_control(hu, false);
+ if (err)
+ goto err_unset_hu;
+ }
diff --git a/target/linux/bcm27xx/patches-5.4/950-0877-Bluetooth-hci_bcm-Add-compatible-string-for-BCM43540.patch b/target/linux/bcm27xx/patches-5.4/950-0877-Bluetooth-hci_bcm-Add-compatible-string-for-BCM43540.patch
new file mode 100644
index 0000000000..f429b15a88
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0877-Bluetooth-hci_bcm-Add-compatible-string-for-BCM43540.patch
@@ -0,0 +1,28 @@
+From 9ca6a4103585907a20b099f9627abfd7312f8f1c Mon Sep 17 00:00:00 2001
+From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+Date: Fri, 25 Oct 2019 14:54:26 -0700
+Subject: [PATCH] Bluetooth: hci_bcm: Add compatible string for
+ BCM43540
+
+commit d462af20dbfa1b9b1a831412f32d9d6757b82459 upstream.
+
+The BCM43540 chip is a 802.11 a/b/g/n/ac + Bluetooth 4.1 combo module.
+This patch adds a compatible string match to the serdev driver for the
+Bluetooth part of the chip.
+
+Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+---
+ drivers/bluetooth/hci_bcm.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/bluetooth/hci_bcm.c
++++ b/drivers/bluetooth/hci_bcm.c
+@@ -1427,6 +1427,7 @@ static const struct of_device_id bcm_blu
+ { .compatible = "brcm,bcm4345c5" },
+ { .compatible = "brcm,bcm4330-bt" },
+ { .compatible = "brcm,bcm43438-bt" },
++ { .compatible = "brcm,bcm43540-bt" },
+ { },
+ };
+ MODULE_DEVICE_TABLE(of, bcm_bluetooth_of_match);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0878-Bluetooth-btbcm-Add-entry-for-BCM4335A0-UART-bluetoo.patch b/target/linux/bcm27xx/patches-5.4/950-0878-Bluetooth-btbcm-Add-entry-for-BCM4335A0-UART-bluetoo.patch
new file mode 100644
index 0000000000..e2ad19b677
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0878-Bluetooth-btbcm-Add-entry-for-BCM4335A0-UART-bluetoo.patch
@@ -0,0 +1,58 @@
+From 9dcea546a8f8ccd054e693b3ab124f49886de2ab Mon Sep 17 00:00:00 2001
+From: Mohammad Rasim <mohammad.rasim96@gmail.com>
+Date: Wed, 20 Nov 2019 14:02:35 +0300
+Subject: [PATCH] Bluetooth: btbcm: Add entry for BCM4335A0 UART
+ bluetooth
+
+commit 1199ab4c9e1d4cdfbabd70b4aadbc8e72c691f65 upstream.
+
+This patch adds the device ID for the BCM4335A0 module
+(part of the AMPAK AP6335 WIFI/Bluetooth combo)
+
+hciconfig output:
+```
+hci1: Type: Primary Bus: UART
+ BD Address: 43:35:B0:07:1F:AC ACL MTU: 1021:8 SCO MTU: 64:1
+ UP RUNNING
+ RX bytes:5079 acl:0 sco:0 events:567 errors:0
+ TX bytes:69065 acl:0 sco:0 commands:567 errors:0
+ Features: 0xbf 0xfe 0xcf 0xff 0xdf 0xff 0x7b 0x87
+ Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
+ Link policy: RSWITCH SNIFF
+ Link mode: SLAVE ACCEPT
+ Name: 'alarm'
+ Class: 0x000000
+ Service Classes: Unspecified
+ Device Class: Miscellaneous,
+ HCI Version: 4.0 (0x6) Revision: 0x161
+ LMP Version: 4.0 (0x6) Subversion: 0x4106
+ Manufacturer: Broadcom Corporation (15)
+```
+
+Signed-off-by: Mohammad Rasim <mohammad.rasim96@gmail.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+---
+ drivers/bluetooth/btbcm.c | 1 +
+ drivers/bluetooth/hci_bcm.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/drivers/bluetooth/btbcm.c
++++ b/drivers/bluetooth/btbcm.c
+@@ -340,6 +340,7 @@ static const struct bcm_subver_table bcm
+ { 0x220e, "BCM20702A1" }, /* 001.002.014 */
+ { 0x4217, "BCM4329B1" }, /* 002.002.023 */
+ { 0x6106, "BCM4359C0" }, /* 003.001.006 */
++ { 0x4106, "BCM4335A0" }, /* 002.001.006 */
+ { }
+ };
+
+--- a/drivers/bluetooth/hci_bcm.c
++++ b/drivers/bluetooth/hci_bcm.c
+@@ -1428,6 +1428,7 @@ static const struct of_device_id bcm_blu
+ { .compatible = "brcm,bcm4330-bt" },
+ { .compatible = "brcm,bcm43438-bt" },
+ { .compatible = "brcm,bcm43540-bt" },
++ { .compatible = "brcm,bcm4335a0" },
+ { },
+ };
+ MODULE_DEVICE_TABLE(of, bcm_bluetooth_of_match);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0879-Bluetooth-hci_bcm-Disallow-set_baudrate-for-BCM4354.patch b/target/linux/bcm27xx/patches-5.4/950-0879-Bluetooth-hci_bcm-Disallow-set_baudrate-for-BCM4354.patch
new file mode 100644
index 0000000000..da8f37b3dd
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0879-Bluetooth-hci_bcm-Disallow-set_baudrate-for-BCM4354.patch
@@ -0,0 +1,115 @@
+From 4c40c6ae0510be0fc9626d1717ff4163358cbfb2 Mon Sep 17 00:00:00 2001
+From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+Date: Tue, 26 Nov 2019 08:17:29 +0100
+Subject: [PATCH] Bluetooth: hci_bcm: Disallow set_baudrate for
+ BCM4354
+
+commit 5d6f391073d5c1c903ac12be72c66b96b2ae93f4 upstream.
+
+Without updating the patchram, the BCM4354 does not support a higher
+operating speed. The normal bcm_setup follows the correct order
+(init_speed, patchram and then oper_speed) but the serdev driver will
+set the operating speed before calling the hu->setup function. Thus,
+for the BCM4354, don't set the operating speed before patchram.
+
+Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
+---
+ drivers/bluetooth/hci_bcm.c | 31 +++++++++++++++++++++++++++++--
+ 1 file changed, 29 insertions(+), 2 deletions(-)
+
+--- a/drivers/bluetooth/hci_bcm.c
++++ b/drivers/bluetooth/hci_bcm.c
+@@ -48,6 +48,14 @@
+ #define BCM_NUM_SUPPLIES 2
+
+ /**
++ * struct bcm_device_data - device specific data
++ * @no_early_set_baudrate: Disallow set baudrate before driver setup()
++ */
++struct bcm_device_data {
++ bool no_early_set_baudrate;
++};
++
++/**
+ * struct bcm_device - device driver resources
+ * @serdev_hu: HCI UART controller struct
+ * @list: bcm_device_list node
+@@ -79,6 +87,7 @@
+ * @hu: pointer to HCI UART controller struct,
+ * used to disable flow control during runtime suspend and system sleep
+ * @is_suspended: whether flow control is currently disabled
++ * @no_early_set_baudrate: don't set_baudrate before setup()
+ */
+ struct bcm_device {
+ /* Must be the first member, hci_serdev.c expects this. */
+@@ -113,6 +122,7 @@ struct bcm_device {
+ struct hci_uart *hu;
+ bool is_suspended;
+ #endif
++ bool no_early_set_baudrate;
+ };
+
+ /* generic bcm uart resources */
+@@ -450,7 +460,13 @@ out:
+ if (bcm->dev) {
+ hci_uart_set_flow_control(hu, true);
+ hu->init_speed = bcm->dev->init_speed;
+- hu->oper_speed = bcm->dev->oper_speed;
++
++ /* If oper_speed is set, ldisc/serdev will set the baudrate
++ * before calling setup()
++ */
++ if (!bcm->dev->no_early_set_baudrate)
++ hu->oper_speed = bcm->dev->oper_speed;
++
+ err = bcm_gpio_set_power(bcm->dev, true);
+ hci_uart_set_flow_control(hu, false);
+ if (err)
+@@ -568,6 +584,8 @@ static int bcm_setup(struct hci_uart *hu
+ /* Operational speed if any */
+ if (hu->oper_speed)
+ speed = hu->oper_speed;
++ else if (bcm->dev && bcm->dev->oper_speed)
++ speed = bcm->dev->oper_speed;
+ else if (hu->proto->oper_speed)
+ speed = hu->proto->oper_speed;
+ else
+@@ -1377,6 +1395,7 @@ static struct platform_driver bcm_driver
+ static int bcm_serdev_probe(struct serdev_device *serdev)
+ {
+ struct bcm_device *bcmdev;
++ const struct bcm_device_data *data;
+ int err;
+
+ bcmdev = devm_kzalloc(&serdev->dev, sizeof(*bcmdev), GFP_KERNEL);
+@@ -1411,6 +1430,10 @@ static int bcm_serdev_probe(struct serde
+ if (err)
+ dev_err(&serdev->dev, "Failed to power down\n");
+
++ data = device_get_match_data(bcmdev->dev);
++ if (data)
++ bcmdev->no_early_set_baudrate = data->no_early_set_baudrate;
++
+ return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto);
+ }
+
+@@ -1422,12 +1445,16 @@ static void bcm_serdev_remove(struct ser
+ }
+
+ #ifdef CONFIG_OF
++static struct bcm_device_data bcm4354_device_data = {
++ .no_early_set_baudrate = true,
++};
++
+ static const struct of_device_id bcm_bluetooth_of_match[] = {
+ { .compatible = "brcm,bcm20702a1" },
+ { .compatible = "brcm,bcm4345c5" },
+ { .compatible = "brcm,bcm4330-bt" },
+ { .compatible = "brcm,bcm43438-bt" },
+- { .compatible = "brcm,bcm43540-bt" },
++ { .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data },
+ { .compatible = "brcm,bcm4335a0" },
+ { },
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0880-Bluetooth-btbcm-Support-pcm-configuration.patch b/target/linux/bcm27xx/patches-5.4/950-0880-Bluetooth-btbcm-Support-pcm-configuration.patch
new file mode 100644
index 0000000000..2d40e7f5ac
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0880-Bluetooth-btbcm-Support-pcm-configuration.patch
@@ -0,0 +1,124 @@
+From 6631d2076af26d2b5b6a3a2f17e8a33de48abcac Mon Sep 17 00:00:00 2001
+From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+Date: Tue, 26 Nov 2019 08:17:30 +0100
+Subject: [PATCH] Bluetooth: btbcm: Support pcm configuration
+
+commit 528379902337102b0264fe5343eafb3d6c59fa45 upstream.
+
+Add BCM vendor specific command to configure PCM parameters. The new
+vendor opcode allows us to set the sco routing, the pcm interface rate,
+and a few other pcm specific options (frame sync, sync mode, and clock
+mode). See broadcom-bluetooth.txt in Documentation for more information
+about valid values for those settings.
+
+Here is an example trace where this opcode was used to configure
+a BCM4354:
+
+ < HCI Command: Vendor (0x3f|0x001c) plen 5
+ 01 02 00 01 01
+ > HCI Event: Command Complete (0x0e) plen 4
+ Vendor (0x3f|0x001c) ncmd 1
+ Status: Success (0x00)
+
+We can read back the values as well with ocf 0x001d to confirm the
+values that were set:
+ $ hcitool cmd 0x3f 0x001d
+ < HCI Command: ogf 0x3f, ocf 0x001d, plen 0
+ > HCI Event: 0x0e plen 9
+ 01 1D FC 00 01 02 00 01 01
+
+Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
+---
+ drivers/bluetooth/btbcm.c | 46 +++++++++++++++++++++++++++++++++++++++
+ drivers/bluetooth/btbcm.h | 16 ++++++++++++++
+ 2 files changed, 62 insertions(+)
+
+--- a/drivers/bluetooth/btbcm.c
++++ b/drivers/bluetooth/btbcm.c
+@@ -105,6 +105,52 @@ int btbcm_set_bdaddr(struct hci_dev *hde
+ }
+ EXPORT_SYMBOL_GPL(btbcm_set_bdaddr);
+
++int btbcm_read_pcm_int_params(struct hci_dev *hdev,
++ struct bcm_set_pcm_int_params *params)
++{
++ struct sk_buff *skb;
++ int err = 0;
++
++ skb = __hci_cmd_sync(hdev, 0xfc1d, 0, NULL, HCI_INIT_TIMEOUT);
++ if (IS_ERR(skb)) {
++ err = PTR_ERR(skb);
++ bt_dev_err(hdev, "BCM: Read PCM int params failed (%d)", err);
++ return err;
++ }
++
++ if (skb->len != 6 || skb->data[0]) {
++ bt_dev_err(hdev, "BCM: Read PCM int params length mismatch");
++ kfree_skb(skb);
++ return -EIO;
++ }
++
++ if (params)
++ memcpy(params, skb->data + 1, 5);
++
++ kfree_skb(skb);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(btbcm_read_pcm_int_params);
++
++int btbcm_write_pcm_int_params(struct hci_dev *hdev,
++ const struct bcm_set_pcm_int_params *params)
++{
++ struct sk_buff *skb;
++ int err;
++
++ skb = __hci_cmd_sync(hdev, 0xfc1c, 5, params, HCI_INIT_TIMEOUT);
++ if (IS_ERR(skb)) {
++ err = PTR_ERR(skb);
++ bt_dev_err(hdev, "BCM: Write PCM int params failed (%d)", err);
++ return err;
++ }
++ kfree_skb(skb);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(btbcm_write_pcm_int_params);
++
+ int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
+ {
+ const struct hci_command_hdr *cmd;
+--- a/drivers/bluetooth/btbcm.h
++++ b/drivers/bluetooth/btbcm.h
+@@ -54,6 +54,10 @@ struct bcm_set_pcm_format_params {
+ int btbcm_check_bdaddr(struct hci_dev *hdev);
+ int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
+ int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw);
++int btbcm_read_pcm_int_params(struct hci_dev *hdev,
++ struct bcm_set_pcm_int_params *params);
++int btbcm_write_pcm_int_params(struct hci_dev *hdev,
++ const struct bcm_set_pcm_int_params *params);
+
+ int btbcm_setup_patchram(struct hci_dev *hdev);
+ int btbcm_setup_apple(struct hci_dev *hdev);
+@@ -73,6 +77,18 @@ static inline int btbcm_set_bdaddr(struc
+ {
+ return -EOPNOTSUPP;
+ }
++
++int btbcm_read_pcm_int_params(struct hci_dev *hdev,
++ struct bcm_set_pcm_int_params *params)
++{
++ return -EOPNOTSUPP;
++}
++
++int btbcm_write_pcm_int_params(struct hci_dev *hdev,
++ const struct bcm_set_pcm_int_params *params)
++{
++ return -EOPNOTSUPP;
++}
+
+ static inline int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
+ {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0881-Bluetooth-hci_bcm-Support-pcm-params-in-dts.patch b/target/linux/bcm27xx/patches-5.4/950-0881-Bluetooth-hci_bcm-Support-pcm-params-in-dts.patch
new file mode 100644
index 0000000000..fa2de56bfe
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0881-Bluetooth-hci_bcm-Support-pcm-params-in-dts.patch
@@ -0,0 +1,74 @@
+From 8b4d7321625cc8403a9ce7f050bd8d1b4ef7446d Mon Sep 17 00:00:00 2001
+From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+Date: Tue, 26 Nov 2019 08:17:32 +0100
+Subject: [PATCH] Bluetooth: hci_bcm: Support pcm params in dts
+
+commit eb762b94111b646b4f116ebfdbfcadbad14e12b3 upstream.
+
+BCM chips may require configuration of PCM to operate correctly and
+there is a vendor specific HCI command to do this. Add support in the
+hci_bcm driver to parse this from devicetree and configure the chip.
+
+Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
+---
+ drivers/bluetooth/hci_bcm.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+--- a/drivers/bluetooth/hci_bcm.c
++++ b/drivers/bluetooth/hci_bcm.c
+@@ -123,6 +123,7 @@ struct bcm_device {
+ bool is_suspended;
+ #endif
+ bool no_early_set_baudrate;
++ u8 pcm_int_params[5];
+ };
+
+ /* generic bcm uart resources */
+@@ -597,6 +598,16 @@ static int bcm_setup(struct hci_uart *hu
+ host_set_baudrate(hu, speed);
+ }
+
++ /* PCM parameters if provided */
++ if (bcm->dev && bcm->dev->pcm_int_params[0] != 0xff) {
++ struct bcm_set_pcm_int_params params;
++
++ btbcm_read_pcm_int_params(hu->hdev, &params);
++
++ memcpy(&params, bcm->dev->pcm_int_params, 5);
++ btbcm_write_pcm_int_params(hu->hdev, &params);
++ }
++
+ finalize:
+ release_firmware(fw);
+
+@@ -1134,6 +1145,8 @@ static int bcm_acpi_probe(struct bcm_dev
+ static int bcm_of_probe(struct bcm_device *bdev)
+ {
+ device_property_read_u32(bdev->dev, "max-speed", &bdev->oper_speed);
++ device_property_read_u8_array(bdev->dev, "brcm,bt-pcm-int-params",
++ bdev->pcm_int_params, 5);
+ return 0;
+ }
+
+@@ -1149,6 +1162,9 @@ static int bcm_probe(struct platform_dev
+ dev->dev = &pdev->dev;
+ dev->irq = platform_get_irq(pdev, 0);
+
++ /* Initialize routing field to an unused value */
++ dev->pcm_int_params[0] = 0xff;
++
+ if (has_acpi_companion(&pdev->dev)) {
+ ret = bcm_acpi_probe(dev);
+ if (ret)
+@@ -1409,6 +1425,9 @@ static int bcm_serdev_probe(struct serde
+ bcmdev->serdev_hu.serdev = serdev;
+ serdev_device_set_drvdata(serdev, bcmdev);
+
++ /* Initialize routing field to an unused value */
++ bcmdev->pcm_int_params[0] = 0xff;
++
+ if (has_acpi_companion(&serdev->dev))
+ err = bcm_acpi_probe(bcmdev);
+ else
diff --git a/target/linux/bcm27xx/patches-5.4/950-0882-Bluetooth-hci_bcm-Drive-RTS-only-for-BCM43438.patch b/target/linux/bcm27xx/patches-5.4/950-0882-Bluetooth-hci_bcm-Drive-RTS-only-for-BCM43438.patch
new file mode 100644
index 0000000000..507f21ab66
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0882-Bluetooth-hci_bcm-Drive-RTS-only-for-BCM43438.patch
@@ -0,0 +1,92 @@
+From b2e19dbff471eb6b9b39ff8f21c8d38e4fac8fe6 Mon Sep 17 00:00:00 2001
+From: Stefan Wahren <wahrenst@gmx.net>
+Date: Wed, 1 Jan 2020 15:01:34 +0100
+Subject: [PATCH] Bluetooth: hci_bcm: Drive RTS only for BCM43438
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+commit e601daed271e9eb1b923972a0a1af65f8c7bb77b upstream.
+
+The commit 3347a80965b3 ("Bluetooth: hci_bcm: Fix RTS handling during
+startup") is causing at least a regression for AP6256 on Orange Pi 3.
+So do the RTS line handing during startup only on the necessary platform.
+
+Fixes: 3347a80965b3 ("Bluetooth: hci_bcm: Fix RTS handling during startup")
+Reported-by: Ondřej Jirman <megous@megous.com>
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+---
+ drivers/bluetooth/hci_bcm.c | 21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+--- a/drivers/bluetooth/hci_bcm.c
++++ b/drivers/bluetooth/hci_bcm.c
+@@ -53,6 +53,7 @@
+ */
+ struct bcm_device_data {
+ bool no_early_set_baudrate;
++ bool drive_rts_on_open;
+ };
+
+ /**
+@@ -123,6 +124,7 @@ struct bcm_device {
+ bool is_suspended;
+ #endif
+ bool no_early_set_baudrate;
++ bool drive_rts_on_open;
+ u8 pcm_int_params[5];
+ };
+
+@@ -459,7 +461,9 @@ static int bcm_open(struct hci_uart *hu)
+
+ out:
+ if (bcm->dev) {
+- hci_uart_set_flow_control(hu, true);
++ if (bcm->dev->drive_rts_on_open)
++ hci_uart_set_flow_control(hu, true);
++
+ hu->init_speed = bcm->dev->init_speed;
+
+ /* If oper_speed is set, ldisc/serdev will set the baudrate
+@@ -469,7 +473,10 @@ out:
+ hu->oper_speed = bcm->dev->oper_speed;
+
+ err = bcm_gpio_set_power(bcm->dev, true);
+- hci_uart_set_flow_control(hu, false);
++
++ if (bcm->dev->drive_rts_on_open)
++ hci_uart_set_flow_control(hu, false);
++
+ if (err)
+ goto err_unset_hu;
+ }
+@@ -1450,8 +1457,10 @@ static int bcm_serdev_probe(struct serde
+ dev_err(&serdev->dev, "Failed to power down\n");
+
+ data = device_get_match_data(bcmdev->dev);
+- if (data)
++ if (data) {
+ bcmdev->no_early_set_baudrate = data->no_early_set_baudrate;
++ bcmdev->drive_rts_on_open = data->drive_rts_on_open;
++ }
+
+ return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto);
+ }
+@@ -1468,11 +1477,15 @@ static struct bcm_device_data bcm4354_de
+ .no_early_set_baudrate = true,
+ };
+
++static struct bcm_device_data bcm43438_device_data = {
++ .drive_rts_on_open = true,
++};
++
+ static const struct of_device_id bcm_bluetooth_of_match[] = {
+ { .compatible = "brcm,bcm20702a1" },
+ { .compatible = "brcm,bcm4345c5" },
+ { .compatible = "brcm,bcm4330-bt" },
+- { .compatible = "brcm,bcm43438-bt" },
++ { .compatible = "brcm,bcm43438-bt", .data = &bcm43438_device_data },
+ { .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data },
+ { .compatible = "brcm,bcm4335a0" },
+ { },
diff --git a/target/linux/bcm27xx/patches-5.4/950-0883-Enhances-the-DAC-driver-to-control-the-optional-head.patch b/target/linux/bcm27xx/patches-5.4/950-0883-Enhances-the-DAC-driver-to-control-the-optional-head.patch
new file mode 100644
index 0000000000..128906026d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0883-Enhances-the-DAC-driver-to-control-the-optional-head.patch
@@ -0,0 +1,134 @@
+From defa915bf0acf6ab5e56997a6733546c33f87682 Mon Sep 17 00:00:00 2001
+From: Joerg Schambacher <joerg@i2audio.com>
+Date: Tue, 7 Jul 2020 15:09:06 +0200
+Subject: [PATCH] Enhances the DAC+ driver to control the optional
+ headphone amplifier
+
+Probes on the I2C bus for TPA6130A2, if successful, it sets DT-parameter
+'status' from 'disabled' to 'okay' using change_sets to enable
+the headphone control.
+
+Signed-off-by: Joerg Schambacher joerg@i2audio.com
+---
+ sound/soc/bcm/Kconfig | 1 +
+ sound/soc/bcm/hifiberry_dacplus.c | 68 ++++++++++++++++++++++++++++++-
+ 2 files changed, 67 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/bcm/Kconfig
++++ b/sound/soc/bcm/Kconfig
+@@ -38,6 +38,7 @@ config SND_BCM2708_SOC_HIFIBERRY_DACPLUS
+ tristate "Support for HifiBerry DAC+"
+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
+ select SND_SOC_PCM512x
++ select SND_SOC_TPA6130A2
+ select COMMON_CLK_HIFIBERRY_DACPRO
+ help
+ Say Y or M if you want to add support for HifiBerry DAC+.
+--- a/sound/soc/bcm/hifiberry_dacplus.c
++++ b/sound/soc/bcm/hifiberry_dacplus.c
+@@ -4,6 +4,7 @@
+ * Author: Daniel Matuschek, Stuart MacLean <stuart@hifiberry.com>
+ * Copyright 2014-2015
+ * based on code by Florian Meier <florian.meier@koalo.de>
++ * Headphone added by Joerg Schambacher, joerg@i2audio.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+@@ -24,6 +25,7 @@
+ #include <linux/of.h>
+ #include <linux/slab.h>
+ #include <linux/delay.h>
++#include <linux/i2c.h>
+
+ #include <sound/core.h>
+ #include <sound/pcm.h>
+@@ -177,8 +179,7 @@ static int snd_rpi_hifiberry_dacplus_ini
+ else
+ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x08, 0x08);
+
+- if (digital_gain_0db_limit)
+- {
++ if (digital_gain_0db_limit) {
+ int ret;
+ struct snd_soc_card *card = rtd->card;
+
+@@ -292,6 +293,15 @@ static struct snd_soc_dai_link snd_rpi_h
+ },
+ };
+
++/* aux device for optional headphone amp */
++static struct snd_soc_aux_dev hifiberry_dacplus_aux_devs[] = {
++ {
++ .dlc = {
++ .name = "tpa6130a2.1-0060",
++ },
++ },
++};
++
+ /* audio machine driver */
+ static struct snd_soc_card snd_rpi_hifiberry_dacplus = {
+ .name = "snd_rpi_hifiberry_dacplus",
+@@ -301,9 +311,63 @@ static struct snd_soc_card snd_rpi_hifib
+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplus_dai),
+ };
+
++static int hb_hp_detect(void)
++{
++ struct i2c_adapter *adap = i2c_get_adapter(1);
++ int ret;
++
++ struct i2c_client tpa_i2c_client = {
++ .addr = 0x60,
++ .adapter = adap,
++ };
++
++ ret = i2c_smbus_read_byte(&tpa_i2c_client) >= 0;
++ i2c_put_adapter(adap);
++ return ret;
++};
++
++static struct property tpa_enable_prop = {
++ .name = "status",
++ .length = 4 + 1, /* length 'okay' + 1 */
++ .value = "okay",
++ };
++
+ static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev)
+ {
+ int ret = 0;
++ struct snd_soc_card *card = &snd_rpi_hifiberry_dacplus;
++ int len;
++ struct device_node *tpa_node;
++ struct property *tpa_prop;
++ struct of_changeset ocs;
++
++ /* probe for head phone amp */
++ if (hb_hp_detect()) {
++ card->aux_dev = hifiberry_dacplus_aux_devs;
++ card->num_aux_devs =
++ ARRAY_SIZE(hifiberry_dacplus_aux_devs);
++ tpa_node = of_find_compatible_node(NULL, NULL, "ti,tpa6130a2");
++ tpa_prop = of_find_property(tpa_node, "status", &len);
++
++ if (strcmp((char *)tpa_prop->value, "okay")) {
++ /* and activate headphone using change_sets */
++ dev_info(&pdev->dev, "activating headphone amplifier");
++ of_changeset_init(&ocs);
++ ret = of_changeset_update_property(&ocs, tpa_node,
++ &tpa_enable_prop);
++ if (ret) {
++ dev_err(&pdev->dev,
++ "cannot activate headphone amplifier\n");
++ return -ENODEV;
++ }
++ ret = of_changeset_apply(&ocs);
++ if (ret) {
++ dev_err(&pdev->dev,
++ "cannot activate headphone amplifier\n");
++ return -ENODEV;
++ }
++ }
++ }
+
+ snd_rpi_hifiberry_dacplus.dev = &pdev->dev;
+ if (pdev->dev.of_node) {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0884-ARM-dts-hifiberry-dacplus-headphone-amp-support.patch b/target/linux/bcm27xx/patches-5.4/950-0884-ARM-dts-hifiberry-dacplus-headphone-amp-support.patch
new file mode 100644
index 0000000000..937d1040d0
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0884-ARM-dts-hifiberry-dacplus-headphone-amp-support.patch
@@ -0,0 +1,24 @@
+From 3295a6b483ea507f8e5d19a806b7db1da1f5a567 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 8 Jul 2020 17:33:06 +0100
+Subject: [PATCH] ARM: dts: hifiberry-dacplus headphone amp support
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts
++++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts
+@@ -39,6 +39,11 @@
+ CPVDD-supply = <&vdd_3v3_reg>;
+ status = "okay";
+ };
++ hpamp: hpamp@60 {
++ compatible = "ti,tpa6130a2";
++ reg = <0x60>;
++ status = "disabled";
++ };
+ };
+ };
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0885-media-i2c-imx290-Explicitly-set-v-h-blank-on-mode-ch.patch b/target/linux/bcm27xx/patches-5.4/950-0885-media-i2c-imx290-Explicitly-set-v-h-blank-on-mode-ch.patch
new file mode 100644
index 0000000000..751f46db35
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0885-media-i2c-imx290-Explicitly-set-v-h-blank-on-mode-ch.patch
@@ -0,0 +1,46 @@
+From 0a47c61cee411b3ada4413f6cebae8cdb06f062e Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 7 Jul 2020 10:31:53 +0100
+Subject: [PATCH] media: i2c: imx290: Explicitly set v&h blank on
+ mode change
+
+__v4l2_ctrl_modify_range only updates the current value should
+it be invalid within the new range. That can leave modes producing
+odd frame rates.
+
+Explicitly update the HBLANK and VBLANK values so that on mode
+change we revert to the default frame rate for the mode.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/imx290.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -796,17 +796,23 @@ static int imx290_set_fmt(struct v4l2_su
+ __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate,
+ imx290_calc_pixel_rate(imx290));
+
+- if (imx290->hblank)
++ if (imx290->hblank) {
+ __v4l2_ctrl_modify_range(imx290->hblank,
+ imx290->hmax_min - mode->width,
+ IMX290_HMAX_MAX - mode->width,
+ 1, mode->hmax - mode->width);
+- if (imx290->vblank)
++ __v4l2_ctrl_s_ctrl(imx290->hblank,
++ mode->hmax - mode->width);
++ }
++ if (imx290->vblank) {
+ __v4l2_ctrl_modify_range(imx290->vblank,
+ mode->vmax - mode->height,
+ IMX290_VMAX_MAX - mode->height,
+ 1,
+ mode->vmax - mode->height);
++ __v4l2_ctrl_s_ctrl(imx290->vblank,
++ mode->vmax - mode->height);
++ }
+ if (imx290->exposure)
+ __v4l2_ctrl_modify_range(imx290->exposure,
+ mode->vmax - mode->height,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0886-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch b/target/linux/bcm27xx/patches-5.4/950-0886-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch
new file mode 100644
index 0000000000..86680af234
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0886-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch
@@ -0,0 +1,156 @@
+From a191c6d6e5180f54ecf16adda61988a16ce9fe48 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 7 Jul 2020 11:23:48 +0100
+Subject: [PATCH] media: i2c: imx290: Add support for g_selection to
+ report cropping
+
+Userspace needs to know the cropping arrangements for each mode,
+so expose this through g_selection.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/imx290.c | 84 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 84 insertions(+)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -61,6 +61,13 @@ enum imx290_clk_index {
+ #define IMX290_PGCTRL_THRU BIT(1)
+ #define IMX290_PGCTRL_MODE(n) ((n) << 4)
+
++#define IMX290_NATIVE_WIDTH 1945U
++#define IMX290_NATIVE_HEIGHT 1109U
++#define IMX290_PIXEL_ARRAY_LEFT 4U
++#define IMX290_PIXEL_ARRAY_TOP 12U
++#define IMX290_PIXEL_ARRAY_WIDTH 1937U
++#define IMX290_PIXEL_ARRAY_HEIGHT 1097U
++
+ static const char * const imx290_supply_name[] = {
+ "vdda",
+ "vddd",
+@@ -80,6 +87,7 @@ struct imx290_mode {
+ u32 hmax;
+ u32 vmax;
+ u8 link_freq_index;
++ struct v4l2_rect crop;
+
+ const struct imx290_regval *data;
+ u32 data_size;
+@@ -384,6 +392,12 @@ static const struct imx290_mode imx290_m
+ .hmax = 0x1130,
+ .vmax = 0x0465,
+ .link_freq_index = FREQ_INDEX_1080P,
++ .crop = {
++ .left = 4 + 8,
++ .top = 12 + 8,
++ .width = 1920,
++ .height = 1080,
++ },
+ .data = imx290_1080p_settings,
+ .data_size = ARRAY_SIZE(imx290_1080p_settings),
+ .clk_data = {
+@@ -398,6 +412,12 @@ static const struct imx290_mode imx290_m
+ .hmax = 0x19c8,
+ .vmax = 0x02ee,
+ .link_freq_index = FREQ_INDEX_720P,
++ .crop = {
++ .left = 4 + 8 + 320,
++ .top = 12 + 8 + 180,
++ .width = 1280,
++ .height = 720,
++ },
+ .data = imx290_720p_settings,
+ .data_size = ARRAY_SIZE(imx290_720p_settings),
+ .clk_data = {
+@@ -415,6 +435,12 @@ static const struct imx290_mode imx290_m
+ .hmax = 0x0898,
+ .vmax = 0x0465,
+ .link_freq_index = FREQ_INDEX_1080P,
++ .crop = {
++ .left = 4 + 8,
++ .top = 12 + 8,
++ .width = 1920,
++ .height = 1080,
++ },
+ .data = imx290_1080p_settings,
+ .data_size = ARRAY_SIZE(imx290_1080p_settings),
+ .clk_data = {
+@@ -429,6 +455,12 @@ static const struct imx290_mode imx290_m
+ .hmax = 0x0ce4,
+ .vmax = 0x02ee,
+ .link_freq_index = FREQ_INDEX_720P,
++ .crop = {
++ .left = 4 + 8 + 320,
++ .top = 12 + 8 + 180,
++ .width = 1280,
++ .height = 720,
++ },
+ .data = imx290_720p_settings,
+ .data_size = ARRAY_SIZE(imx290_720p_settings),
+ .clk_data = {
+@@ -875,6 +907,57 @@ static int imx290_write_current_format(s
+ return 0;
+ }
+
++static const struct v4l2_rect *
++__imx290_get_pad_crop(struct imx290 *imx290, struct v4l2_subdev_pad_config *cfg,
++ unsigned int pad, enum v4l2_subdev_format_whence which)
++{
++ switch (which) {
++ case V4L2_SUBDEV_FORMAT_TRY:
++ return v4l2_subdev_get_try_crop(&imx290->sd, cfg, pad);
++ case V4L2_SUBDEV_FORMAT_ACTIVE:
++ return &imx290->current_mode->crop;
++ }
++
++ return NULL;
++}
++
++static int imx290_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP: {
++ struct imx290 *imx290 = to_imx290(sd);
++
++ mutex_lock(&imx290->lock);
++ sel->r = *__imx290_get_pad_crop(imx290, cfg, sel->pad,
++ sel->which);
++ mutex_unlock(&imx290->lock);
++
++ return 0;
++ }
++
++ case V4L2_SEL_TGT_NATIVE_SIZE:
++ sel->r.top = 0;
++ sel->r.left = 0;
++ sel->r.width = IMX290_NATIVE_WIDTH;
++ sel->r.height = IMX290_NATIVE_HEIGHT;
++
++ return 0;
++
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.top = IMX290_PIXEL_ARRAY_TOP;
++ sel->r.left = IMX290_PIXEL_ARRAY_LEFT;
++ sel->r.width = IMX290_PIXEL_ARRAY_WIDTH;
++ sel->r.height = IMX290_PIXEL_ARRAY_HEIGHT;
++
++ return 0;
++ }
++
++ return -EINVAL;
++}
++
+ /* Start streaming */
+ static int imx290_start_streaming(struct imx290 *imx290)
+ {
+@@ -1073,6 +1156,7 @@ static const struct v4l2_subdev_pad_ops
+ .enum_frame_size = imx290_enum_frame_size,
+ .get_fmt = imx290_get_fmt,
+ .set_fmt = imx290_set_fmt,
++ .get_selection = imx290_get_selection,
+ };
+
+ static const struct v4l2_subdev_ops imx290_subdev_ops = {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0887-media-i2c-imx290-Set-the-colorspace-fields-in-the-fo.patch b/target/linux/bcm27xx/patches-5.4/950-0887-media-i2c-imx290-Set-the-colorspace-fields-in-the-fo.patch
new file mode 100644
index 0000000000..28c43cda52
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0887-media-i2c-imx290-Set-the-colorspace-fields-in-the-fo.patch
@@ -0,0 +1,31 @@
+From b02ddac32c2bcd8894dac22de7ef1fb80a4dfe1a Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 7 Jul 2020 11:51:26 +0100
+Subject: [PATCH] media: i2c: imx290: Set the colorspace fields in
+ the format
+
+The colorspace fields were left untouched in imx290_set_fmt
+which lead to a v4l2-compliance failure.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/imx290.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -813,6 +813,14 @@ static int imx290_set_fmt(struct v4l2_su
+
+ fmt->format.code = imx290->formats[i].code;
+ fmt->format.field = V4L2_FIELD_NONE;
++ fmt->format.colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->format.ycbcr_enc =
++ V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->format.colorspace);
++ fmt->format.quantization =
++ V4L2_MAP_QUANTIZATION_DEFAULT(true, fmt->format.colorspace,
++ fmt->format.ycbcr_enc);
++ fmt->format.xfer_func =
++ V4L2_MAP_XFER_FUNC_DEFAULT(fmt->format.colorspace);
+
+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+ format = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0888-media-bcm2835-unicam-Reinstate-V4L2_CAP_READWRITE-in.patch b/target/linux/bcm27xx/patches-5.4/950-0888-media-bcm2835-unicam-Reinstate-V4L2_CAP_READWRITE-in.patch
new file mode 100644
index 0000000000..5b2b280b1e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0888-media-bcm2835-unicam-Reinstate-V4L2_CAP_READWRITE-in.patch
@@ -0,0 +1,28 @@
+From 6253cd2eee555c6b2779667cc41ee1d75aa85034 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 7 Jul 2020 14:23:40 +0100
+Subject: [PATCH] media: bcm2835-unicam: Reinstate V4L2_CAP_READWRITE
+ in the caps
+
+v4l2-compliance throws a failure if the device doesn't advertise
+V4L2_CAP_READWRITE but allows read or write operations.
+We do support read, so reinstate the flag.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/platform/bcm2835/bcm2835-unicam.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -2416,8 +2416,8 @@ static int register_node(struct unicam_d
+ vdev->queue = q;
+ vdev->lock = &node->lock;
+ vdev->device_caps = (pad_id == IMAGE_PAD) ?
+- (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING) :
+- (V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING);
++ V4L2_CAP_VIDEO_CAPTURE : V4L2_CAP_META_CAPTURE;
++ vdev->device_caps |= V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
+
+ /* Define the device names */
+ snprintf(vdev->name, sizeof(vdev->name), "%s-%s", UNICAM_MODULE_NAME,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0889-media-bcm2835-unicam-Ensure-type-is-VIDEO_CAPTURE-in.patch b/target/linux/bcm27xx/patches-5.4/950-0889-media-bcm2835-unicam-Ensure-type-is-VIDEO_CAPTURE-in.patch
new file mode 100644
index 0000000000..1e8407fca8
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0889-media-bcm2835-unicam-Ensure-type-is-VIDEO_CAPTURE-in.patch
@@ -0,0 +1,36 @@
+From 470e49cf5ee0b77e6812595ca396e34af8ae67b4 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 7 Jul 2020 14:52:43 +0100
+Subject: [PATCH] media: bcm2835-unicam: Ensure type is VIDEO_CAPTURE
+ in [g|s]_selection
+
+[g|s]_selection pass in a buffer type that needs to be validated
+before passing on to the sensor subdev.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/platform/bcm2835/bcm2835-unicam.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -1880,6 +1880,9 @@ static int unicam_s_selection(struct fil
+ .r = sel->r,
+ };
+
++ if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++
+ return v4l2_subdev_call(dev->sensor, pad, set_selection, NULL, &sdsel);
+ }
+
+@@ -1894,6 +1897,9 @@ static int unicam_g_selection(struct fil
+ };
+ int ret;
+
++ if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++
+ ret = v4l2_subdev_call(dev->sensor, pad, get_selection, NULL, &sdsel);
+ if (!ret)
+ sel->r = sdsel.r;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0890-dtoverlays-Create-an-overlay-for-the-Omnivision-OV72.patch b/target/linux/bcm27xx/patches-5.4/950-0890-dtoverlays-Create-an-overlay-for-the-Omnivision-OV72.patch
new file mode 100644
index 0000000000..6a4da8f814
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0890-dtoverlays-Create-an-overlay-for-the-Omnivision-OV72.patch
@@ -0,0 +1,157 @@
+From 870de3bc0e80a9b79b470a45636437a0078041c1 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 7 Jul 2020 16:12:05 +0100
+Subject: [PATCH] dtoverlays: Create an overlay for the Omnivision
+ OV7251 sensor
+
+Adds an overlay for the OV7251 VGA global shutter sensor.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 8 ++
+ arch/arm/boot/dts/overlays/ov7251-overlay.dts | 111 ++++++++++++++++++
+ 3 files changed, 120 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/ov7251-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -115,6 +115,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ mpu6050.dtbo \
+ mz61581.dtbo \
+ ov5647.dtbo \
++ ov7251.dtbo \
+ ov9281.dtbo \
+ papirus.dtbo \
+ pibell.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1813,6 +1813,14 @@ Load: dtoverlay=ov5647
+ Params: <None>
+
+
++Name: ov7251
++Info: Omnivision OV7251 camera module.
++ Uses Unicam 1, which is the standard camera connector on most Pi
++ variants.
++Load: dtoverlay=ov7251
++Params: <None>
++
++
+ Name: ov9281
+ Info: Omnivision OV9281 camera module.
+ Uses Unicam 1, which is the standard camera connector on most Pi
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/ov7251-overlay.dts
+@@ -0,0 +1,111 @@
++// SPDX-License-Identifier: GPL-2.0-only
++// Definitions for OV7251 camera module on VC I2C bus
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++
++/{
++ compatible = "brcm,bcm2835";
++
++ fragment@0 {
++ target = <&i2c_csi_dsi>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ ov7251: ov7251@60 {
++ compatible = "ovti,ov7251";
++ reg = <0x60>;
++ status = "okay";
++
++ clocks = <&ov7251_clk>;
++ clock-names = "xclk";
++ clock-frequency = <24000000>;
++
++ vdddo-supply = <&ov7251_dovdd>;
++ vdda-supply = <&ov7251_avdd>;
++ vddd-supply = <&ov7251_dvdd>;
++
++ enable-gpios = <&gpio 41 GPIO_ACTIVE_HIGH>;
++
++ port {
++ ov7251_0: endpoint {
++ remote-endpoint = <&csi1_ep>;
++ clock-lanes = <0>;
++ data-lanes = <1>;
++ clock-noncontinuous;
++ link-frequencies =
++ /bits/ 64 <456000000>;
++ };
++ };
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&csi1>;
++ __overlay__ {
++ status = "okay";
++
++ port {
++ csi1_ep: endpoint {
++ remote-endpoint = <&ov7251_0>;
++ data-lanes = <1>;
++ };
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&i2c0if>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@3 {
++ target-path="/";
++ __overlay__ {
++ ov7251_avdd: fixedregulator@0 {
++ compatible = "regulator-fixed";
++ regulator-name = "ov7251_avdd";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ };
++ ov7251_dovdd: fixedregulator@1 {
++ compatible = "regulator-fixed";
++ regulator-name = "ov7251_dovdd";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++ ov7251_dvdd: fixedregulator@2 {
++ compatible = "regulator-fixed";
++ regulator-name = "ov7251_dvdd";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
++ };
++ ov7251_clk: ov7251-clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ };
++ };
++ };
++
++ fragment@4 {
++ target = <&i2c0mux>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@5 {
++ target-path="/__overrides__";
++ __overlay__ {
++ cam0-pwdn-ctrl = <&ov7251>,"enable-gpios:0";
++ cam0-pwdn = <&ov7251>,"enable-gpios:4";
++ };
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-0891-vc4_hdmi-Set-HDMI_MAI_FMT.patch b/target/linux/bcm27xx/patches-5.4/950-0891-vc4_hdmi-Set-HDMI_MAI_FMT.patch
new file mode 100644
index 0000000000..2c305a0bff
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0891-vc4_hdmi-Set-HDMI_MAI_FMT.patch
@@ -0,0 +1,124 @@
+From c9ba62745ba17d21542db28bf7dc28a39e19f7c2 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 10 Mar 2020 22:21:15 +0000
+Subject: [PATCH] vc4_hdmi: Set HDMI_MAI_FMT
+
+The hardware uses this for generating the right audio
+data island packets when using formats other than PCM
+
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 47 ++++++++++++++++++++++++++++++++++
+ drivers/gpu/drm/vc4/vc4_regs.h | 31 ++++++++++++++++++++++
+ 2 files changed, 78 insertions(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -917,6 +917,45 @@ static void vc4_hdmi_audio_shutdown(stru
+ vc4_hdmi->audio.substream = NULL;
+ }
+
++static int sample_rate_to_mai_fmt(int samplerate)
++{
++ switch(samplerate)
++ {
++ case 8000:
++ return VC4_HDMI_MAI_SAMPLE_RATE_8000;
++ case 11025:
++ return VC4_HDMI_MAI_SAMPLE_RATE_11025;
++ case 12000:
++ return VC4_HDMI_MAI_SAMPLE_RATE_12000;
++ case 16000:
++ return VC4_HDMI_MAI_SAMPLE_RATE_16000;
++ case 22050:
++ return VC4_HDMI_MAI_SAMPLE_RATE_22050;
++ case 24000:
++ return VC4_HDMI_MAI_SAMPLE_RATE_24000;
++ case 32000:
++ return VC4_HDMI_MAI_SAMPLE_RATE_32000;
++ case 44100:
++ return VC4_HDMI_MAI_SAMPLE_RATE_44100;
++ case 48000:
++ return VC4_HDMI_MAI_SAMPLE_RATE_48000;
++ case 64000:
++ return VC4_HDMI_MAI_SAMPLE_RATE_64000;
++ case 88200:
++ return VC4_HDMI_MAI_SAMPLE_RATE_88200;
++ case 96000:
++ return VC4_HDMI_MAI_SAMPLE_RATE_96000;
++ case 128000:
++ return VC4_HDMI_MAI_SAMPLE_RATE_128000;
++ case 176400:
++ return VC4_HDMI_MAI_SAMPLE_RATE_176400;
++ case 192000:
++ return VC4_HDMI_MAI_SAMPLE_RATE_192000;
++ default:
++ return VC4_HDMI_MAI_SAMPLE_RATE_NOT_INDICATED;
++ }
++}
++
+ /* HDMI audio codec callbacks */
+ static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+@@ -926,6 +965,8 @@ static int vc4_hdmi_audio_hw_params(stru
+ struct device *dev = &vc4_hdmi->pdev->dev;
+ u32 audio_packet_config, channel_mask;
+ u32 channel_map;
++ u32 mai_audio_format;
++ u32 mai_sample_rate;
+
+ if (substream != vc4_hdmi->audio.substream)
+ return -EINVAL;
+@@ -946,6 +987,12 @@ static int vc4_hdmi_audio_hw_params(stru
+
+ vc4_hdmi_audio_set_mai_clock(vc4_hdmi);
+
++ mai_sample_rate = sample_rate_to_mai_fmt(vc4_hdmi->audio.samplerate);
++ mai_audio_format = VC4_HDMI_MAI_FORMAT_PCM;
++ HDMI_WRITE(HDMI_MAI_FMT,
++ VC4_SET_FIELD(mai_sample_rate, VC4_HDMI_MAI_FORMAT_SAMPLE_RATE) |
++ VC4_SET_FIELD(mai_audio_format, VC4_HDMI_MAI_FORMAT_AUDIO_FORMAT));
++
+ /* The B frame identifier should match the value used by alsa-lib (8) */
+ audio_packet_config =
+ VC4_HDMI_AUDIO_PACKET_ZERO_DATA_ON_SAMPLE_FLAT |
+--- a/drivers/gpu/drm/vc4/vc4_regs.h
++++ b/drivers/gpu/drm/vc4/vc4_regs.h
+@@ -516,6 +516,37 @@
+ # define VC4_HDMI_AUDIO_PACKET_CEA_MASK_MASK VC4_MASK(7, 0)
+ # define VC4_HDMI_AUDIO_PACKET_CEA_MASK_SHIFT 0
+
++
++# define VC4_HDMI_MAI_FORMAT_AUDIO_FORMAT_MASK VC4_MASK(23, 16)
++# define VC4_HDMI_MAI_FORMAT_AUDIO_FORMAT_SHIFT 16
++
++enum {
++ VC4_HDMI_MAI_FORMAT_PCM = 2,
++ VC4_HDMI_MAI_FORMAT_HBR = 200,
++};
++
++# define VC4_HDMI_MAI_FORMAT_SAMPLE_RATE_MASK VC4_MASK(15, 8)
++# define VC4_HDMI_MAI_FORMAT_SAMPLE_RATE_SHIFT 8
++
++enum {
++ VC4_HDMI_MAI_SAMPLE_RATE_NOT_INDICATED = 0,
++ VC4_HDMI_MAI_SAMPLE_RATE_8000 = 1,
++ VC4_HDMI_MAI_SAMPLE_RATE_11025 = 2,
++ VC4_HDMI_MAI_SAMPLE_RATE_12000 = 3,
++ VC4_HDMI_MAI_SAMPLE_RATE_16000 = 4,
++ VC4_HDMI_MAI_SAMPLE_RATE_22050 = 5,
++ VC4_HDMI_MAI_SAMPLE_RATE_24000 = 6,
++ VC4_HDMI_MAI_SAMPLE_RATE_32000 = 7,
++ VC4_HDMI_MAI_SAMPLE_RATE_44100 = 8,
++ VC4_HDMI_MAI_SAMPLE_RATE_48000 = 9,
++ VC4_HDMI_MAI_SAMPLE_RATE_64000 = 10,
++ VC4_HDMI_MAI_SAMPLE_RATE_88200 = 11,
++ VC4_HDMI_MAI_SAMPLE_RATE_96000 = 12,
++ VC4_HDMI_MAI_SAMPLE_RATE_128000 = 13,
++ VC4_HDMI_MAI_SAMPLE_RATE_176400 = 14,
++ VC4_HDMI_MAI_SAMPLE_RATE_192000 = 15,
++};
++
+ # define VC4_HDMI_RAM_PACKET_ENABLE BIT(16)
+
+ /* When set, the CTS_PERIOD counts based on MAI bus sync pulse instead
diff --git a/target/linux/bcm27xx/patches-5.4/950-0892-drm-vc4-add-iec958-controls-to-vc4_hdmi.patch b/target/linux/bcm27xx/patches-5.4/950-0892-drm-vc4-add-iec958-controls-to-vc4_hdmi.patch
new file mode 100644
index 0000000000..bc5aacad88
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0892-drm-vc4-add-iec958-controls-to-vc4_hdmi.patch
@@ -0,0 +1,119 @@
+From 209a350d81cded4ac83c31088d9e941c6497eb0e Mon Sep 17 00:00:00 2001
+From: Matthias Reichl <hias@horus.com>
+Date: Tue, 17 Mar 2020 12:12:22 +0100
+Subject: [PATCH] drm/vc4: add iec958 controls to vc4_hdmi
+
+Although vc4 get an IEC958 formatted stream passed in from userspace
+the driver needs the info from the channel status bits to properly
+set up the hardware, eg for HBR passthrough.
+
+Add iec958 controls so the channel status bits can be passed in
+from userspace.
+
+Signed-off-by: Matthias Reichl <hias@horus.com>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 60 ++++++++++++++++++++++++++++++++++
+ drivers/gpu/drm/vc4/vc4_hdmi.h | 2 ++
+ 2 files changed, 62 insertions(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -43,6 +43,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/rational.h>
+ #include <linux/reset.h>
++#include <sound/asoundef.h>
+ #include <sound/dmaengine_pcm.h>
+ #include <sound/pcm_drm_eld.h>
+ #include <sound/pcm_params.h>
+@@ -1106,6 +1107,47 @@ static int vc4_hdmi_audio_eld_ctl_get(st
+ return 0;
+ }
+
++static int vc4_spdif_info(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_info *uinfo)
++{
++ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
++ uinfo->count = 1;
++ return 0;
++}
++
++static int vc4_spdif_playback_get(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
++ struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component);
++
++ memcpy(ucontrol->value.iec958.status, vc4_hdmi->audio.iec_status,
++ sizeof(vc4_hdmi->audio.iec_status));
++
++ return 0;
++}
++
++static int vc4_spdif_playback_put(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
++ struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component);
++
++ memcpy(vc4_hdmi->audio.iec_status, ucontrol->value.iec958.status,
++ sizeof(vc4_hdmi->audio.iec_status));
++
++ return 0;
++}
++
++static int vc4_spdif_mask_get(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ memset(ucontrol->value.iec958.status, 0xff,
++ FIELD_SIZEOF(struct vc4_hdmi_audio, iec_status));
++
++ return 0;
++}
++
+ static const struct snd_kcontrol_new vc4_hdmi_audio_controls[] = {
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+@@ -1115,6 +1157,19 @@ static const struct snd_kcontrol_new vc4
+ .info = vc4_hdmi_audio_eld_ctl_info,
+ .get = vc4_hdmi_audio_eld_ctl_get,
+ },
++ {
++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
++ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
++ .info = vc4_spdif_info,
++ .get = vc4_spdif_playback_get,
++ .put = vc4_spdif_playback_put,
++ },
++ {
++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
++ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
++ .info = vc4_spdif_info,
++ .get = vc4_spdif_mask_get,
++ },
+ };
+
+ static const struct snd_soc_dapm_widget vc4_hdmi_audio_widgets[] = {
+@@ -1235,6 +1290,11 @@ static int vc4_hdmi_audio_init(struct vc
+ vc4_hdmi->audio.dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ vc4_hdmi->audio.dma_data.maxburst = 2;
+
++ vc4_hdmi->audio.iec_status[0] = IEC958_AES0_CON_NOT_COPYRIGHT;
++ vc4_hdmi->audio.iec_status[1] =
++ IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER;
++ vc4_hdmi->audio.iec_status[3] = IEC958_AES3_CON_FS_48000;
++
+ ret = devm_snd_dmaengine_pcm_register(dev, &pcm_conf, 0);
+ if (ret) {
+ dev_err(dev, "Could not register PCM component: %d\n", ret);
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
+@@ -115,6 +115,8 @@ struct vc4_hdmi_audio {
+ struct snd_pcm_substream *substream;
+
+ bool streaming;
++
++ unsigned char iec_status[4];
+ };
+
+ /* General HDMI hardware state. */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0893-drm-vc4-move-setup-from-hw_params-to-prepare.patch b/target/linux/bcm27xx/patches-5.4/950-0893-drm-vc4-move-setup-from-hw_params-to-prepare.patch
new file mode 100644
index 0000000000..1e63b34a3a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0893-drm-vc4-move-setup-from-hw_params-to-prepare.patch
@@ -0,0 +1,56 @@
+From 18b1ff043d713b6b3669a8746062f2faeb6c3557 Mon Sep 17 00:00:00 2001
+From: Matthias Reichl <hias@horus.com>
+Date: Thu, 19 Mar 2020 20:00:35 +0100
+Subject: [PATCH] drm/vc4: move setup from hw_params to prepare
+
+Configuring HDMI audio registers in prepare allows us to take
+IEC958 bits into account which are set by the alsa hook after
+the hw_params call.
+
+Signed-off-by: Matthias Reichl <hias@horus.com>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -958,8 +958,7 @@ static int sample_rate_to_mai_fmt(int sa
+ }
+
+ /* HDMI audio codec callbacks */
+-static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
+- struct snd_pcm_hw_params *params,
++static int vc4_hdmi_audio_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+ {
+ struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
+@@ -972,12 +971,15 @@ static int vc4_hdmi_audio_hw_params(stru
+ if (substream != vc4_hdmi->audio.substream)
+ return -EINVAL;
+
+- dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
+- params_rate(params), params_width(params),
+- params_channels(params));
++ dev_dbg(dev, "%s: %u Hz, %d bit, %d channels AES0=%02x\n",
++ __func__,
++ substream->runtime->rate,
++ snd_pcm_format_width(substream->runtime->format),
++ substream->runtime->channels,
++ vc4_hdmi->audio.iec_status[0]);
+
+- vc4_hdmi->audio.channels = params_channels(params);
+- vc4_hdmi->audio.samplerate = params_rate(params);
++ vc4_hdmi->audio.channels = substream->runtime->channels;
++ vc4_hdmi->audio.samplerate = substream->runtime->rate;
+
+ HDMI_WRITE(HDMI_MAI_CTL,
+ VC4_HD_MAI_CTL_RESET |
+@@ -1196,7 +1198,7 @@ static const struct snd_soc_component_dr
+ static const struct snd_soc_dai_ops vc4_hdmi_audio_dai_ops = {
+ .startup = vc4_hdmi_audio_startup,
+ .shutdown = vc4_hdmi_audio_shutdown,
+- .hw_params = vc4_hdmi_audio_hw_params,
++ .prepare = vc4_hdmi_audio_prepare,
+ .set_fmt = vc4_hdmi_audio_set_fmt,
+ .trigger = vc4_hdmi_audio_trigger,
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0894-drm-vc4-enable-HBR-MAI-format-on-HBR-streams.patch b/target/linux/bcm27xx/patches-5.4/950-0894-drm-vc4-enable-HBR-MAI-format-on-HBR-streams.patch
new file mode 100644
index 0000000000..823e9ebab5
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0894-drm-vc4-enable-HBR-MAI-format-on-HBR-streams.patch
@@ -0,0 +1,25 @@
+From 52beca6270b034cce84a738c71d36ffff7088389 Mon Sep 17 00:00:00 2001
+From: Dom Cobley <popcornmix@gmail.com>
+Date: Fri, 10 Jul 2020 11:51:16 +0100
+Subject: [PATCH] drm/vc4: enable HBR MAI format on HBR streams
+
+Signed-off-by: Matthias Reichl <hias@horus.com>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -991,7 +991,11 @@ static int vc4_hdmi_audio_prepare(struct
+ vc4_hdmi_audio_set_mai_clock(vc4_hdmi);
+
+ mai_sample_rate = sample_rate_to_mai_fmt(vc4_hdmi->audio.samplerate);
+- mai_audio_format = VC4_HDMI_MAI_FORMAT_PCM;
++ if (vc4_hdmi->audio.iec_status[0] & IEC958_AES0_NONAUDIO &&
++ vc4_hdmi->audio.channels == 8)
++ mai_audio_format = VC4_HDMI_MAI_FORMAT_HBR;
++ else
++ mai_audio_format = VC4_HDMI_MAI_FORMAT_PCM;
+ HDMI_WRITE(HDMI_MAI_FMT,
+ VC4_SET_FIELD(mai_sample_rate, VC4_HDMI_MAI_FORMAT_SAMPLE_RATE) |
+ VC4_SET_FIELD(mai_audio_format, VC4_HDMI_MAI_FORMAT_AUDIO_FORMAT));
diff --git a/target/linux/bcm27xx/patches-5.4/950-0895-vc4_hdmi-Remove-firmware-logic-for-MAI-threshold-set.patch b/target/linux/bcm27xx/patches-5.4/950-0895-vc4_hdmi-Remove-firmware-logic-for-MAI-threshold-set.patch
new file mode 100644
index 0000000000..e08ceca15a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0895-vc4_hdmi-Remove-firmware-logic-for-MAI-threshold-set.patch
@@ -0,0 +1,47 @@
+From 5f22fca663178a49bbb72058ea9225d35b3d155d Mon Sep 17 00:00:00 2001
+From: Dom Cobley <popcornmix@gmail.com>
+Date: Thu, 25 Jun 2020 18:48:40 +0100
+Subject: [PATCH] vc4_hdmi: Remove firmware logic for MAI threshold
+ setting
+
+This was a workaround for bugs in hardware on earlier Pi models
+and wasn't totally successful.
+
+It makes audio quality worse on a Pi4 at the higher sample rates
+
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 22 ++++++----------------
+ 1 file changed, 6 insertions(+), 16 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -1010,22 +1010,12 @@ static int vc4_hdmi_audio_prepare(struct
+ audio_packet_config |= VC4_SET_FIELD(channel_mask,
+ VC4_HDMI_AUDIO_PACKET_CEA_MASK);
+
+- /* Set the MAI threshold. This logic mimics the firmware's. */
+- if (vc4_hdmi->audio.samplerate > 96000) {
+- HDMI_WRITE(HDMI_MAI_THR,
+- VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQHIGH) |
+- VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQLOW));
+- } else if (vc4_hdmi->audio.samplerate > 48000) {
+- HDMI_WRITE(HDMI_MAI_THR,
+- VC4_SET_FIELD(0x14, VC4_HD_MAI_THR_DREQHIGH) |
+- VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQLOW));
+- } else {
+- HDMI_WRITE(HDMI_MAI_THR,
+- VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICHIGH) |
+- VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICLOW) |
+- VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQHIGH) |
+- VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQLOW));
+- }
++ /* Set the MAI threshold */
++ HDMI_WRITE(HDMI_MAI_THR,
++ VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICHIGH) |
++ VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICLOW) |
++ VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQHIGH) |
++ VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQLOW));
+
+ HDMI_WRITE(HDMI_MAI_CONFIG,
+ VC4_HDMI_MAI_CONFIG_BIT_REVERSE |
diff --git a/target/linux/bcm27xx/patches-5.4/950-0896-vc_hdmi-Set-VC4_HDMI_MAI_CONFIG_FORMAT_REVERSE.patch b/target/linux/bcm27xx/patches-5.4/950-0896-vc_hdmi-Set-VC4_HDMI_MAI_CONFIG_FORMAT_REVERSE.patch
new file mode 100644
index 0000000000..6fca81a53d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0896-vc_hdmi-Set-VC4_HDMI_MAI_CONFIG_FORMAT_REVERSE.patch
@@ -0,0 +1,24 @@
+From 203c14fa37c25a7d92c4f433ae918c6a7ce4f4db Mon Sep 17 00:00:00 2001
+From: Dom Cobley <popcornmix@gmail.com>
+Date: Tue, 30 Jun 2020 11:23:49 +0100
+Subject: [PATCH] vc_hdmi: Set VC4_HDMI_MAI_CONFIG_FORMAT_REVERSE
+
+Without this bit set, HDMI_MAI_FORMAT doesn't pick up
+the format and samplerate from DVP_CFG_MAI0_FMT and you
+can't get HDMI_HDMI_13_AUDIO_STATUS_1 to indicate HBR mode
+
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -1019,6 +1019,7 @@ static int vc4_hdmi_audio_prepare(struct
+
+ HDMI_WRITE(HDMI_MAI_CONFIG,
+ VC4_HDMI_MAI_CONFIG_BIT_REVERSE |
++ VC4_HDMI_MAI_CONFIG_FORMAT_REVERSE |
+ VC4_SET_FIELD(channel_mask, VC4_HDMI_MAI_CHANNEL_MASK));
+
+ channel_map = vc4_hdmi->variant->channel_map(vc4_hdmi, channel_mask);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0897-dts-Enable-NO_WAIT_RESP-for-hdmi-audio-dma.patch b/target/linux/bcm27xx/patches-5.4/950-0897-dts-Enable-NO_WAIT_RESP-for-hdmi-audio-dma.patch
new file mode 100644
index 0000000000..7e84dc41aa
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0897-dts-Enable-NO_WAIT_RESP-for-hdmi-audio-dma.patch
@@ -0,0 +1,45 @@
+From 2318f056a6c740f66fdeb6b9f47cea319dcdeb20 Mon Sep 17 00:00:00 2001
+From: Dom Cobley <popcornmix@gmail.com>
+Date: Thu, 2 Jul 2020 19:36:08 +0100
+Subject: [PATCH] dts: Enable NO_WAIT_RESP for hdmi audio dma
+
+Without this set, DVP_CFG_MAI0_CTL indicates occasional
+DLATE errors when configured to 8 channel 192kHz
+
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+---
+ arch/arm/boot/dts/bcm2711-rpi.dtsi | 4 ++--
+ arch/arm/boot/dts/bcm2835-common.dtsi | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi
+@@ -74,7 +74,7 @@
+ clock-names = "hdmi";
+ resets = <&dvp 0>;
+ ddc = <&ddc0>;
+- dmas = <&dma 10>;
++ dmas = <&dma (10|(1<<27))>;
+ dma-names = "audio-rx";
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+@@ -114,7 +114,7 @@
+ clocks = <&firmware_clocks 13>;
+ clock-names = "hdmi";
+ resets = <&dvp 1>;
+- dmas = <&dma 17>;
++ dmas = <&dma (17|(1<<27))>;
+ dma-names = "audio-rx";
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+--- a/arch/arm/boot/dts/bcm2835-common.dtsi
++++ b/arch/arm/boot/dts/bcm2835-common.dtsi
+@@ -117,7 +117,7 @@
+ clocks = <&clocks BCM2835_PLLH_PIX>,
+ <&clocks BCM2835_CLOCK_HSM>;
+ clock-names = "pixel", "hdmi";
+- dmas = <&dma 17>;
++ dmas = <&dma (17|(1<<27))>;
+ dma-names = "audio-rx";
+ status = "disabled";
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0898-SQUASH-dts-Further-simplify-firmware-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0898-SQUASH-dts-Further-simplify-firmware-clocks.patch
new file mode 100644
index 0000000000..eea0166476
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0898-SQUASH-dts-Further-simplify-firmware-clocks.patch
@@ -0,0 +1,69 @@
+From af629960be92b1548d0b3c15b6e082930403fbae Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 10 Jul 2020 16:57:43 +0100
+Subject: [PATCH] SQUASH: dts: Further simplify firmware clocks
+
+All Pi platforms will use the firmware clocks driver, so declare it in
+the most common place - bcm2835-rpi.dtsi.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2709-rpi.dtsi | 7 -------
+ arch/arm/boot/dts/bcm2711-rpi.dtsi | 7 -------
+ arch/arm/boot/dts/bcm2835-rpi.dtsi | 5 +++++
+ arch/arm/boot/dts/bcm2836-rpi.dtsi | 7 -------
+ 4 files changed, 5 insertions(+), 21 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2709-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2709-rpi.dtsi
+@@ -3,10 +3,3 @@
+ &vchiq {
+ compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq";
+ };
+-
+-&firmware {
+- firmware_clocks: clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- #clock-cells = <1>;
+- };
+-};
+--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi
+@@ -309,10 +309,3 @@
+ &hvs {
+ clocks = <&firmware_clocks 4>;
+ };
+-
+-&firmware {
+- firmware_clocks: clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- #clock-cells = <1>;
+- };
+-};
+--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
+@@ -16,6 +16,11 @@
+ compatible = "raspberrypi,bcm2835-firmware", "simple-bus";
+ mboxes = <&mailbox>;
+ dma-ranges;
++
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <1>;
++ };
+ };
+
+ power: power {
+--- a/arch/arm/boot/dts/bcm2836-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2836-rpi.dtsi
+@@ -4,10 +4,3 @@
+ &vchiq {
+ compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq";
+ };
+-
+-&firmware {
+- firmware_clocks: clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- #clock-cells = <1>;
+- };
+-};
diff --git a/target/linux/bcm27xx/patches-5.4/950-0899-media-bcm2835-unicam-Set-VPU-min-clock-freq-to-250Mh.patch b/target/linux/bcm27xx/patches-5.4/950-0899-media-bcm2835-unicam-Set-VPU-min-clock-freq-to-250Mh.patch
new file mode 100644
index 0000000000..788606cd8b
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0899-media-bcm2835-unicam-Set-VPU-min-clock-freq-to-250Mh.patch
@@ -0,0 +1,154 @@
+From 09c1533f7f5dabd79aa2018083d1b71d26cd7eda Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Mon, 11 May 2020 13:02:22 +0100
+Subject: [PATCH] media: bcm2835: unicam: Set VPU min clock freq to
+ 250Mhz.
+
+When streaming with Unicam, the VPU must have a clock frequency of at
+least 250Mhz. Otherwise, the input fifos could overrun, causing
+image corruption.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm270x.dtsi | 10 ++--
+ .../media/platform/bcm2835/bcm2835-unicam.c | 49 +++++++++++++++++--
+ 2 files changed, 50 insertions(+), 9 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm270x.dtsi
++++ b/arch/arm/boot/dts/bcm270x.dtsi
+@@ -88,8 +88,9 @@
+ reg = <0x7e800000 0x800>,
+ <0x7e802000 0x4>;
+ interrupts = <2 6>;
+- clocks = <&clocks BCM2835_CLOCK_CAM0>;
+- clock-names = "lp";
++ clocks = <&clocks BCM2835_CLOCK_CAM0>,
++ <&firmware_clocks 4>;
++ clock-names = "lp", "vpu";
+ power-domains = <&power RPI_POWER_DOMAIN_UNICAM0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+@@ -102,8 +103,9 @@
+ reg = <0x7e801000 0x800>,
+ <0x7e802004 0x4>;
+ interrupts = <2 7>;
+- clocks = <&clocks BCM2835_CLOCK_CAM1>;
+- clock-names = "lp";
++ clocks = <&clocks BCM2835_CLOCK_CAM1>,
++ <&firmware_clocks 4>;
++ clock-names = "lp", "vpu";
+ power-domains = <&power RPI_POWER_DOMAIN_UNICAM1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -89,6 +89,11 @@ MODULE_PARM_DESC(debug, "Debug level 0-3
+ v4l2_err(&(dev)->v4l2_dev, fmt, ##arg)
+
+ /*
++ * Unicam must request a minimum of 250Mhz from the VPU clock.
++ * Otherwise the input FIFOs overrun and cause image corruption.
++ */
++#define MIN_VPU_CLOCK_RATE (250 * 1000 * 1000)
++/*
+ * To protect against a dodgy sensor driver never returning an error from
+ * enum_mbus_code, set a maximum index value to be used.
+ */
+@@ -417,8 +422,10 @@ struct unicam_device {
+ void __iomem *base;
+ /* clock gating base address */
+ void __iomem *clk_gate_base;
+- /* clock handle */
++ /* lp clock handle */
+ struct clk *clock;
++ /* vpu clock handle */
++ struct clk *vpu_clock;
+ /* V4l2 device */
+ struct v4l2_device v4l2_dev;
+ struct media_device mdev;
+@@ -1674,16 +1681,28 @@ static int unicam_start_streaming(struct
+ unicam_dbg(1, dev, "Running with %u data lanes\n",
+ dev->active_data_lanes);
+
+- ret = clk_set_rate(dev->clock, 100 * 1000 * 1000);
++ ret = clk_set_min_rate(dev->vpu_clock, MIN_VPU_CLOCK_RATE);
++ if (ret) {
++ unicam_err(dev, "failed to set up VPU clock\n");
++ goto err_pm_put;
++ }
++
++ ret = clk_prepare_enable(dev->vpu_clock);
+ if (ret) {
+- unicam_err(dev, "failed to set up clock\n");
++ unicam_err(dev, "Failed to enable VPU clock: %d\n", ret);
+ goto err_pm_put;
+ }
+
++ ret = clk_set_rate(dev->clock, 100 * 1000 * 1000);
++ if (ret) {
++ unicam_err(dev, "failed to set up CSI clock\n");
++ goto err_vpu_clock;
++ }
++
+ ret = clk_prepare_enable(dev->clock);
+ if (ret) {
+ unicam_err(dev, "Failed to enable CSI clock: %d\n", ret);
+- goto err_pm_put;
++ goto err_vpu_clock;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(dev->node); i++) {
+@@ -1717,6 +1736,11 @@ static int unicam_start_streaming(struct
+ err_disable_unicam:
+ unicam_disable(dev);
+ clk_disable_unprepare(dev->clock);
++err_vpu_clock:
++ ret = clk_set_min_rate(dev->vpu_clock, 0);
++ if (ret)
++ unicam_err(dev, "failed to reset the VPU clock\n");
++ clk_disable_unprepare(dev->vpu_clock);
+ err_pm_put:
+ unicam_runtime_put(dev);
+ err_streaming:
+@@ -1734,6 +1758,8 @@ static void unicam_stop_streaming(struct
+ node->streaming = false;
+
+ if (node->pad_id == IMAGE_PAD) {
++ int ret;
++
+ /*
+ * Stop streaming the sensor and disable the peripheral.
+ * We cannot continue streaming embedded data with the
+@@ -1743,6 +1769,12 @@ static void unicam_stop_streaming(struct
+ unicam_err(dev, "stream off failed in subdev\n");
+
+ unicam_disable(dev);
++
++ ret = clk_set_min_rate(dev->vpu_clock, 0);
++ if (ret)
++ unicam_err(dev, "failed to reset the min VPU clock\n");
++
++ clk_disable_unprepare(dev->vpu_clock);
+ clk_disable_unprepare(dev->clock);
+ unicam_runtime_put(dev);
+
+@@ -2742,11 +2774,18 @@ static int unicam_probe(struct platform_
+
+ unicam->clock = devm_clk_get(&pdev->dev, "lp");
+ if (IS_ERR(unicam->clock)) {
+- unicam_err(unicam, "Failed to get clock\n");
++ unicam_err(unicam, "Failed to get lp clock\n");
+ ret = PTR_ERR(unicam->clock);
+ goto err_unicam_put;
+ }
+
++ unicam->vpu_clock = devm_clk_get(&pdev->dev, "vpu");
++ if (IS_ERR(unicam->vpu_clock)) {
++ unicam_err(unicam, "Failed to get vpu clock\n");
++ ret = PTR_ERR(unicam->vpu_clock);
++ goto err_unicam_put;
++ }
++
+ ret = platform_get_irq(pdev, 0);
+ if (ret <= 0) {
+ dev_err(&pdev->dev, "No IRQ resource\n");
diff --git a/target/linux/bcm27xx/patches-5.4/950-0900-dt-bindings-bcm2835-unicam-Update-documentation-with.patch b/target/linux/bcm27xx/patches-5.4/950-0900-dt-bindings-bcm2835-unicam-Update-documentation-with.patch
new file mode 100644
index 0000000000..c8b53d6955
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0900-dt-bindings-bcm2835-unicam-Update-documentation-with.patch
@@ -0,0 +1,38 @@
+From f747c5b5f35490ff177b8327ff1f7299f7d0bf4a Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Mon, 11 May 2020 13:06:27 +0100
+Subject: [PATCH] dt-bindings: bcm2835-unicam: Update documentation
+ with new clock params
+
+Update the documentation to reflect the new "VPU" clock needed
+by the bcm2835-unicam driver.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ .../devicetree/bindings/media/bcm2835-unicam.txt | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/Documentation/devicetree/bindings/media/bcm2835-unicam.txt
++++ b/Documentation/devicetree/bindings/media/bcm2835-unicam.txt
+@@ -20,7 +20,7 @@ Required properties:
+ - interrupts : should contain the IRQ line for this Unicam instance.
+ - clocks : list of clock specifiers, corresponding to entries in
+ clock-names property.
+-- clock-names : must contain an "lp" entry, matching entries in the
++- clock-names : must contain "lp" and "vpu" entries, matching entries in the
+ clocks property.
+
+ Unicam supports a single port node. It should contain one 'port' child node
+@@ -46,9 +46,9 @@ Example:
+ reg = <0x7e801000 0x800>,
+ <0x7e802004 0x4>;
+ interrupts = <2 7>;
+- clocks = <&clocks BCM2835_CLOCK_CAM1>;
+- clock-names = "lp";
+-
++ clocks = <&clocks BCM2835_CLOCK_CAM1>,
++ <&firmware_clocks 4>;
++ clock-names = "lp", "vpu";
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&tc358743_0>;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0901-correct-SND_SOC_DAILINK_DEFS.patch b/target/linux/bcm27xx/patches-5.4/950-0901-correct-SND_SOC_DAILINK_DEFS.patch
new file mode 100644
index 0000000000..6823283d0f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0901-correct-SND_SOC_DAILINK_DEFS.patch
@@ -0,0 +1,21 @@
+From b27a6e98851f8889f8d9059bfebb91014ac7b057 Mon Sep 17 00:00:00 2001
+From: AMuszkat <ariel.muszkat@gmail.com>
+Date: Tue, 14 Jul 2020 17:51:03 +0200
+Subject: [PATCH] correct SND_SOC_DAILINK_DEFS
+
+Signed-off-by: AMuszkat <ariel.muszkat@gmail.com>
+---
+ sound/soc/bcm/rpi-simple-soundcard.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/bcm/rpi-simple-soundcard.c
++++ b/sound/soc/bcm/rpi-simple-soundcard.c
+@@ -235,7 +235,7 @@ static struct snd_rpi_simple_drvdata drv
+
+ SND_SOC_DAILINK_DEFS(merus_amp,
+ DAILINK_COMP_ARRAY(COMP_EMPTY()),
+- DAILINK_COMP_ARRAY(COMP_CODEC("ma120x0p-amp", "ma120x0p.1-0020")),
++ DAILINK_COMP_ARRAY(COMP_CODEC("ma120x0p.1-0020","ma120x0p-amp")),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+ static struct snd_soc_dai_link snd_merus_amp_dai[] = {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0902-media-dt-bindings-video-interfaces-Document-orientat.patch b/target/linux/bcm27xx/patches-5.4/950-0902-media-dt-bindings-video-interfaces-Document-orientat.patch
new file mode 100644
index 0000000000..de2fd156dd
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0902-media-dt-bindings-video-interfaces-Document-orientat.patch
@@ -0,0 +1,43 @@
+From cc7d8104a44cf0ad67081f9ad0efd0e260a2379b Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo@jmondi.org>
+Date: Sat, 9 May 2020 11:04:44 +0200
+Subject: [PATCH] media: dt-bindings: video-interfaces: Document
+ 'orientation' property
+
+Add the 'orientation' device property, used to specify the device mounting
+position. The property is particularly meaningful for mobile devices
+with a well defined usage orientation.
+
+Reviewed-by: Rob Herring <robh@kernel.org>
+Acked-by: Tomasz Figa <tfiga@chromium.org>
+Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+Commit cabc918e5b877ed547e5b6463f5ea6e3ac4edbb3 upstream
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+---
+ .../devicetree/bindings/media/video-interfaces.txt | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/Documentation/devicetree/bindings/media/video-interfaces.txt
++++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
+@@ -89,6 +89,17 @@ Optional properties
+ but a number of degrees counter clockwise. Typical values are 0 and 180
+ (upside down).
+
++- orientation: The orientation of a device (typically an image sensor or a flash
++ LED) describing its mounting position relative to the usage orientation of the
++ system where the device is installed on.
++ Possible values are:
++ 0 - Front. The device is mounted on the front facing side of the system.
++ For mobile devices such as smartphones, tablets and laptops the front side is
++ the user facing side.
++ 1 - Back. The device is mounted on the back side of the system, which is
++ defined as the opposite side of the front facing one.
++ 2 - External. The device is not attached directly to the system but is
++ attached in a way that allows it to move freely.
+
+ Optional endpoint properties
+ ----------------------------
diff --git a/target/linux/bcm27xx/patches-5.4/950-0903-media-dt-bindings-video-interface-Replace-rotation-d.patch b/target/linux/bcm27xx/patches-5.4/950-0903-media-dt-bindings-video-interface-Replace-rotation-d.patch
new file mode 100644
index 0000000000..a070c2a897
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0903-media-dt-bindings-video-interface-Replace-rotation-d.patch
@@ -0,0 +1,390 @@
+From 1af1c75a6965dd975d40e904e921d9f07395ffcb Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo@jmondi.org>
+Date: Sat, 9 May 2020 11:04:45 +0200
+Subject: [PATCH] media: dt-bindings: video-interface: Replace
+ 'rotation' description
+
+Replace the 'rotation' property description by providing a definition
+relative to the camera sensor pixel array coordinate system and the
+captured scene.
+
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+Commit 915bd31ce9ed328535e5ecf3ca730c5764ec1a38 upstream
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+---
+ .../bindings/media/video-interfaces.txt | 359 +++++++++++++++++-
+ 1 file changed, 356 insertions(+), 3 deletions(-)
+
+--- a/Documentation/devicetree/bindings/media/video-interfaces.txt
++++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
+@@ -85,9 +85,362 @@ Optional properties
+
+ - lens-focus: A phandle to the node of the focus lens controller.
+
+-- rotation: The device, typically an image sensor, is not mounted upright,
+- but a number of degrees counter clockwise. Typical values are 0 and 180
+- (upside down).
++- rotation: The camera rotation is expressed as the angular difference in
++ degrees between two reference systems, one relative to the camera module, and
++ one defined on the external world scene to be captured when projected on the
++ image sensor pixel array.
++
++ A camera sensor has a 2-dimensional reference system 'Rc' defined by
++ its pixel array read-out order. The origin is set to the first pixel
++ being read out, the X-axis points along the column read-out direction
++ towards the last columns, and the Y-axis along the row read-out
++ direction towards the last row.
++
++ A typical example for a sensor with a 2592x1944 pixel array matrix
++ observed from the front is:
++
++ 2591 X-axis 0
++ <------------------------+ 0
++ .......... ... ..........!
++ .......... ... ..........! Y-axis
++ ... !
++ .......... ... ..........!
++ .......... ... ..........! 1943
++ V
++
++ The external world scene reference system 'Rs' is a 2-dimensional
++ reference system on the focal plane of the camera module. The origin is
++ placed on the top-left corner of the visible scene, the X-axis points
++ towards the right, and the Y-axis points towards the bottom of the
++ scene. The top, bottom, left and right directions are intentionally not
++ defined and depend on the environment in which the camera is used.
++
++ A typical example of a (very common) picture of a shark swimming from
++ left to right, as seen from the camera, is:
++
++ 0 X-axis
++ 0 +------------------------------------->
++ !
++ !
++ !
++ ! |\____)\___
++ ! ) _____ __`<
++ ! |/ )/
++ !
++ !
++ !
++ V
++ Y-axis
++
++ with the reference system 'Rs' placed on the camera focal plane:
++
++ ¸.·˙!
++ ¸.·˙ !
++ _ ¸.·˙ !
++ +-/ \-+¸.·˙ !
++ | (o) | ! Camera focal plane
++ +-----+˙·.¸ !
++ ˙·.¸ !
++ ˙·.¸ !
++ ˙·.¸!
++
++ When projected on the sensor's pixel array, the image and the associated
++ reference system 'Rs' are typically (but not always) inverted, due to
++ the camera module's lens optical inversion effect.
++
++ Assuming the above represented scene of the swimming shark, the lens
++ inversion projects the scene and its reference system onto the sensor
++ pixel array, seen from the front of the camera sensor, as follows:
++
++ Y-axis
++ ^
++ !
++ !
++ !
++ ! |\_____)\__
++ ! ) ____ ___.<
++ ! |/ )/
++ !
++ !
++ !
++ 0 +------------------------------------->
++ 0 X-axis
++
++ Note the shark being upside-down.
++
++ The resulting projected reference system is named 'Rp'.
++
++ The camera rotation property is then defined as the angular difference
++ in the counter-clockwise direction between the camera reference system
++ 'Rc' and the projected scene reference system 'Rp'. It is expressed in
++ degrees as a number in the range [0, 360[.
++
++ Examples
++
++ 0 degrees camera rotation:
++
++
++ Y-Rp
++ ^
++ Y-Rc !
++ ^ !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! 0 +------------------------------------->
++ ! 0 X-Rp
++ 0 +------------------------------------->
++ 0 X-Rc
++
++
++ X-Rc 0
++ <------------------------------------+ 0
++ X-Rp 0 !
++ <------------------------------------+ 0 !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! V
++ ! Y-Rc
++ V
++ Y-Rp
++
++ 90 degrees camera rotation:
++
++ 0 Y-Rc
++ 0 +-------------------->
++ ! Y-Rp
++ ! ^
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! 0 +------------------------------------->
++ ! 0 X-Rp
++ !
++ !
++ !
++ !
++ V
++ X-Rc
++
++ 180 degrees camera rotation:
++
++ 0
++ <------------------------------------+ 0
++ X-Rc !
++ Y-Rp !
++ ^ !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! V
++ ! Y-Rc
++ 0 +------------------------------------->
++ 0 X-Rp
++
++ 270 degrees camera rotation:
++
++ 0 Y-Rc
++ 0 +-------------------->
++ ! 0
++ ! <-----------------------------------+ 0
++ ! X-Rp !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! !
++ ! V
++ ! Y-Rp
++ !
++ !
++ !
++ !
++ V
++ X-Rc
++
++
++ Example one - Webcam
++
++ A camera module installed on the user facing part of a laptop screen
++ casing used for video calls. The captured images are meant to be
++ displayed in landscape mode (width > height) on the laptop screen.
++
++ The camera is typically mounted upside-down to compensate the lens
++ optical inversion effect:
++
++ Y-Rp
++ Y-Rc ^
++ ^ !
++ ! !
++ ! ! |\_____)\__
++ ! ! ) ____ ___.<
++ ! ! |/ )/
++ ! !
++ ! !
++ ! !
++ ! 0 +------------------------------------->
++ ! 0 X-Rp
++ 0 +------------------------------------->
++ 0 X-Rc
++
++ The two reference systems are aligned, the resulting camera rotation is
++ 0 degrees, no rotation correction needs to be applied to the resulting
++ image once captured to memory buffers to correctly display it to users:
++
++ +--------------------------------------+
++ ! !
++ ! !
++ ! !
++ ! |\____)\___ !
++ ! ) _____ __`< !
++ ! |/ )/ !
++ ! !
++ ! !
++ ! !
++ +--------------------------------------+
++
++ If the camera sensor is not mounted upside-down to compensate for the
++ lens optical inversion, the two reference systems will not be aligned,
++ with 'Rp' being rotated 180 degrees relatively to 'Rc':
++
++
++ X-Rc 0
++ <------------------------------------+ 0
++ !
++ Y-Rp !
++ ^ !
++ ! !
++ ! |\_____)\__ !
++ ! ) ____ ___.< !
++ ! |/ )/ !
++ ! !
++ ! !
++ ! V
++ ! Y-Rc
++ 0 +------------------------------------->
++ 0 X-Rp
++
++ The image once captured to memory will then be rotated by 180 degrees:
++
++ +--------------------------------------+
++ ! !
++ ! !
++ ! !
++ ! __/(_____/| !
++ ! >.___ ____ ( !
++ ! \( \| !
++ ! !
++ ! !
++ ! !
++ +--------------------------------------+
++
++ A software rotation correction of 180 degrees should be applied to
++ correctly display the image:
++
++ +--------------------------------------+
++ ! !
++ ! !
++ ! !
++ ! |\____)\___ !
++ ! ) _____ __`< !
++ ! |/ )/ !
++ ! !
++ ! !
++ ! !
++ +--------------------------------------+
++
++ Example two - Phone camera
++
++ A camera installed on the back side of a mobile device facing away from
++ the user. The captured images are meant to be displayed in portrait mode
++ (height > width) to match the device screen orientation and the device
++ usage orientation used when taking the picture.
++
++ The camera sensor is typically mounted with its pixel array longer side
++ aligned to the device longer side, upside-down mounted to compensate for
++ the lens optical inversion effect:
++
++ 0 Y-Rc
++ 0 +-------------------->
++ ! Y-Rp
++ ! ^
++ ! !
++ ! !
++ ! !
++ ! ! |\_____)\__
++ ! ! ) ____ ___.<
++ ! ! |/ )/
++ ! !
++ ! !
++ ! !
++ ! 0 +------------------------------------->
++ ! 0 X-Rp
++ !
++ !
++ !
++ !
++ V
++ X-Rc
++
++ The two reference systems are not aligned and the 'Rp' reference
++ system is rotated by 90 degrees in the counter-clockwise direction
++ relatively to the 'Rc' reference system.
++
++ The image once captured to memory will be rotated:
++
++ +-------------------------------------+
++ | _ _ |
++ | \ / |
++ | | | |
++ | | | |
++ | | > |
++ | < | |
++ | | | |
++ | . |
++ | V |
++ +-------------------------------------+
++
++ A correction of 90 degrees in counter-clockwise direction has to be
++ applied to correctly display the image in portrait mode on the device
++ screen:
++
++ +--------------------+
++ | |
++ | |
++ | |
++ | |
++ | |
++ | |
++ | |\____)\___ |
++ | ) _____ __`< |
++ | |/ )/ |
++ | |
++ | |
++ | |
++ | |
++ | |
++ +--------------------+
+
+ - orientation: The orientation of a device (typically an image sensor or a flash
+ LED) describing its mounting position relative to the usage orientation of the
diff --git a/target/linux/bcm27xx/patches-5.4/950-0904-media-v4l2-ctrl-Document-V4L2_CID_CAMERA_ORIENTATION.patch b/target/linux/bcm27xx/patches-5.4/950-0904-media-v4l2-ctrl-Document-V4L2_CID_CAMERA_ORIENTATION.patch
new file mode 100644
index 0000000000..9516e653ab
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0904-media-v4l2-ctrl-Document-V4L2_CID_CAMERA_ORIENTATION.patch
@@ -0,0 +1,61 @@
+From 16a7ef36055e414560143ebcb95113f9513ca49d Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo@jmondi.org>
+Date: Sat, 9 May 2020 11:04:46 +0200
+Subject: [PATCH] media: v4l2-ctrl: Document
+ V4L2_CID_CAMERA_ORIENTATION
+
+Add documentation for the V4L2_CID_CAMERA_ORIENTATION camera
+control. The newly added read-only control reports the camera device
+orientation relative to the usage orientation of the system the camera
+is installed on.
+
+Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+Commit 9397a83f40183eeafd5c787af2240ed0d6b26daa upstream
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+---
+ .../media/uapi/v4l/ext-ctrls-camera.rst | 30 +++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+--- a/Documentation/media/uapi/v4l/ext-ctrls-camera.rst
++++ b/Documentation/media/uapi/v4l/ext-ctrls-camera.rst
+@@ -510,6 +510,36 @@ enum v4l2_scene_mode -
+ value down. A value of zero stops the motion if one is in progress
+ and has no effect otherwise.
+
++``V4L2_CID_CAMERA_ORIENTATION (menu)``
++ This read-only control describes the camera orientation by reporting its
++ mounting position on the device where the camera is installed. The control
++ value is constant and not modifiable by software. This control is
++ particularly meaningful for devices which have a well defined orientation,
++ such as phones, laptops and portable devices since the control is expressed
++ as a position relative to the device's intended usage orientation. For
++ example, a camera installed on the user-facing side of a phone, a tablet or
++ a laptop device is said to be have ``V4L2_CAMERA_ORIENTATION_FRONT``
++ orientation, while a camera installed on the opposite side of the front one
++ is said to be have ``V4L2_CAMERA_ORIENTATION_BACK`` orientation. Camera
++ sensors not directly attached to the device, or attached in a way that
++ allows them to move freely, such as webcams and digital cameras, are said to
++ have the ``V4L2_CAMERA_ORIENTATION_EXTERNAL`` orientation.
++
++
++
++.. flat-table::
++ :header-rows: 0
++ :stub-columns: 0
++
++ * - ``V4L2_CAMERA_ORIENTATION_FRONT``
++ - The camera is oriented towards the user facing side of the device.
++ * - ``V4L2_CAMERA_ORIENTATION_BACK``
++ - The camera is oriented towards the back facing side of the device.
++ * - ``V4L2_CAMERA_ORIENTATION_EXTERNAL``
++ - The camera is not directly attached to the device and is freely movable.
++
++
++
+ .. [#f1]
+ This control may be changed to a menu control in the future, if more
+ options are required.
diff --git a/target/linux/bcm27xx/patches-5.4/950-0905-media-v4l2-ctrl-Document-V4L2_CID_CAMERA_SENSOR_ROTA.patch b/target/linux/bcm27xx/patches-5.4/950-0905-media-v4l2-ctrl-Document-V4L2_CID_CAMERA_SENSOR_ROTA.patch
new file mode 100644
index 0000000000..9be7e6a368
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0905-media-v4l2-ctrl-Document-V4L2_CID_CAMERA_SENSOR_ROTA.patch
@@ -0,0 +1,151 @@
+From 00d84a43c7042b55e81d0818b0d1a6e44c6f79b5 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo@jmondi.org>
+Date: Sat, 9 May 2020 11:04:47 +0200
+Subject: [PATCH] media: v4l2-ctrl: Document
+ V4L2_CID_CAMERA_SENSOR_ROTATION
+
+Add documentation for the V4L2_CID_CAMERA_SENSOR_ROTATION camera
+control. The newly added read-only control reports the rotation
+correction to be applied to images before displaying them to the user.
+
+Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+Commit 9926c2248740a632b0629fd8c07d0fc361dc15cc upstream
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+---
+ .../media/uapi/v4l/ext-ctrls-camera.rst | 121 ++++++++++++++++++
+ 1 file changed, 121 insertions(+)
+
+--- a/Documentation/media/uapi/v4l/ext-ctrls-camera.rst
++++ b/Documentation/media/uapi/v4l/ext-ctrls-camera.rst
+@@ -540,6 +540,127 @@ enum v4l2_scene_mode -
+
+
+
++``V4L2_CID_CAMERA_SENSOR_ROTATION (integer)``
++ This read-only control describes the rotation correction in degrees in the
++ counter-clockwise direction to be applied to the captured images once
++ captured to memory to compensate for the camera sensor mounting rotation.
++
++ For a precise definition of the sensor mounting rotation refer to the
++ extensive description of the 'rotation' properties in the device tree
++ bindings file 'video-interfaces.txt'.
++
++ A few examples are below reported, using a shark swimming from left to
++ right in front of the user as the example scene to capture. ::
++
++ 0 X-axis
++ 0 +------------------------------------->
++ !
++ !
++ !
++ ! |\____)\___
++ ! ) _____ __`<
++ ! |/ )/
++ !
++ !
++ !
++ V
++ Y-axis
++
++ Example one - Webcam
++
++ Assuming you can bring your laptop with you while swimming with sharks,
++ the camera module of the laptop is installed on the user facing part of a
++ laptop screen casing, and is typically used for video calls. The captured
++ images are meant to be displayed in landscape mode (width > height) on the
++ laptop screen.
++
++ The camera is typically mounted upside-down to compensate the lens optical
++ inversion effect. In this case the value of the
++ V4L2_CID_CAMERA_SENSOR_ROTATION control is 0, no rotation is required to
++ display images correctly to the user.
++
++ If the camera sensor is not mounted upside-down it is required to compensate
++ the lens optical inversion effect and the value of the
++ V4L2_CID_CAMERA_SENSOR_ROTATION control is 180 degrees, as images will
++ result rotated when captured to memory. ::
++
++ +--------------------------------------+
++ ! !
++ ! !
++ ! !
++ ! __/(_____/| !
++ ! >.___ ____ ( !
++ ! \( \| !
++ ! !
++ ! !
++ ! !
++ +--------------------------------------+
++
++ A software rotation correction of 180 degrees has to be applied to correctly
++ display the image on the user screen. ::
++
++ +--------------------------------------+
++ ! !
++ ! !
++ ! !
++ ! |\____)\___ !
++ ! ) _____ __`< !
++ ! |/ )/ !
++ ! !
++ ! !
++ ! !
++ +--------------------------------------+
++
++ Example two - Phone camera
++
++ It is more handy to go and swim with sharks with only your mobile phone
++ with you and take pictures with the camera that is installed on the back
++ side of the device, facing away from the user. The captured images are meant
++ to be displayed in portrait mode (height > width) to match the device screen
++ orientation and the device usage orientation used when taking the picture.
++
++ The camera sensor is typically mounted with its pixel array longer side
++ aligned to the device longer side, upside-down mounted to compensate for
++ the lens optical inversion effect.
++
++ The images once captured to memory will be rotated and the value of the
++ V4L2_CID_CAMERA_SENSOR_ROTATION will report a 90 degree rotation. ::
++
++
++ +-------------------------------------+
++ | _ _ |
++ | \ / |
++ | | | |
++ | | | |
++ | | > |
++ | < | |
++ | | | |
++ | . |
++ | V |
++ +-------------------------------------+
++
++ A correction of 90 degrees in counter-clockwise direction has to be
++ applied to correctly display the image in portrait mode on the device
++ screen. ::
++
++ +--------------------+
++ | |
++ | |
++ | |
++ | |
++ | |
++ | |
++ | |\____)\___ |
++ | ) _____ __`< |
++ | |/ )/ |
++ | |
++ | |
++ | |
++ | |
++ | |
++ +--------------------+
++
++
+ .. [#f1]
+ This control may be changed to a menu control in the future, if more
+ options are required.
diff --git a/target/linux/bcm27xx/patches-5.4/950-0906-media-v4l2-ctrls-Add-camera-orientation-and-rotation.patch b/target/linux/bcm27xx/patches-5.4/950-0906-media-v4l2-ctrls-Add-camera-orientation-and-rotation.patch
new file mode 100644
index 0000000000..921b08ee7c
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0906-media-v4l2-ctrls-Add-camera-orientation-and-rotation.patch
@@ -0,0 +1,89 @@
+From d25d713f7bfe272cbeaac90769eb88fee382b2e9 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo@jmondi.org>
+Date: Sat, 9 May 2020 11:04:48 +0200
+Subject: [PATCH] media: v4l2-ctrls: Add camera orientation and
+ rotation
+
+Add support for the newly defined V4L2_CID_CAMERA_ORIENTATION
+and V4L2_CID_CAMERA_SENSOR_ROTATION read-only controls used to report
+the camera device mounting position and orientation respectively.
+
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+Commit 926645d43fd43622a2b056471a2cf41cc19cbf4c upstream
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+---
+ drivers/media/v4l2-core/v4l2-ctrls.c | 13 +++++++++++++
+ include/uapi/linux/v4l2-controls.h | 7 +++++++
+ 2 files changed, 20 insertions(+)
+
+--- a/drivers/media/v4l2-core/v4l2-ctrls.c
++++ b/drivers/media/v4l2-core/v4l2-ctrls.c
+@@ -577,6 +577,12 @@ const char * const *v4l2_ctrl_get_menu(u
+ "Annex B Start Code",
+ NULL,
+ };
++ static const char * const camera_orientation[] = {
++ "Front",
++ "Back",
++ "External",
++ NULL,
++ };
+
+ switch (id) {
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+@@ -702,6 +708,8 @@ const char * const *v4l2_ctrl_get_menu(u
+ return hevc_decode_mode;
+ case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE:
+ return hevc_start_code;
++ case V4L2_CID_CAMERA_ORIENTATION:
++ return camera_orientation;
+ default:
+ return NULL;
+ }
+@@ -1015,6 +1023,8 @@ const char *v4l2_ctrl_get_name(u32 id)
+ case V4L2_CID_PAN_SPEED: return "Pan, Speed";
+ case V4L2_CID_TILT_SPEED: return "Tilt, Speed";
+ case V4L2_CID_UNIT_CELL_SIZE: return "Unit Cell Size";
++ case V4L2_CID_CAMERA_ORIENTATION: return "Camera Orientation";
++ case V4L2_CID_CAMERA_SENSOR_ROTATION: return "Camera Sensor Rotation";
+
+ /* FM Radio Modulator controls */
+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */
+@@ -1288,6 +1298,7 @@ void v4l2_ctrl_fill(u32 id, const char *
+ case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE:
+ case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE:
+ case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE:
++ case V4L2_CID_CAMERA_ORIENTATION:
+ *type = V4L2_CTRL_TYPE_MENU;
+ break;
+ case V4L2_CID_LINK_FREQ:
+@@ -1480,6 +1491,8 @@ void v4l2_ctrl_fill(u32 id, const char *
+ case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT:
+ case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM:
+ case V4L2_CID_RDS_RX_MUSIC_SPEECH:
++ case V4L2_CID_CAMERA_ORIENTATION:
++ case V4L2_CID_CAMERA_SENSOR_ROTATION:
+ *flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ break;
+ case V4L2_CID_RF_TUNER_PLL_LOCK:
+--- a/include/uapi/linux/v4l2-controls.h
++++ b/include/uapi/linux/v4l2-controls.h
+@@ -917,6 +917,13 @@ enum v4l2_auto_focus_range {
+ #define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE+32)
+ #define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE+33)
+
++#define V4L2_CID_CAMERA_ORIENTATION (V4L2_CID_CAMERA_CLASS_BASE+34)
++#define V4L2_CAMERA_ORIENTATION_FRONT 0
++#define V4L2_CAMERA_ORIENTATION_BACK 1
++#define V4L2_CAMERA_ORIENTATION_EXTERNAL 2
++
++#define V4L2_CID_CAMERA_SENSOR_ROTATION (V4L2_CID_CAMERA_CLASS_BASE+35)
++
+ /* FM Modulator class control IDs */
+
+ #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
diff --git a/target/linux/bcm27xx/patches-5.4/950-0907-media-v4l2-fwnode-Add-helper-to-parse-device-propert.patch b/target/linux/bcm27xx/patches-5.4/950-0907-media-v4l2-fwnode-Add-helper-to-parse-device-propert.patch
new file mode 100644
index 0000000000..d0d21fc7f2
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0907-media-v4l2-fwnode-Add-helper-to-parse-device-propert.patch
@@ -0,0 +1,138 @@
+From 1cc9056759e1f500de5e401afd4b0acff90cc653 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo@jmondi.org>
+Date: Sat, 9 May 2020 11:04:49 +0200
+Subject: [PATCH] media: v4l2-fwnode: Add helper to parse device
+ properties
+
+Add an helper function to parse common device properties in the same
+way as v4l2_fwnode_endpoint_parse() parses common endpoint properties.
+
+Parse the 'rotation' and 'orientation' properties from the firmware
+interface.
+
+Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+Commit 344897ef1d9b33e246b64e255d807ca6c053f349 upstream
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+---
+ drivers/media/v4l2-core/v4l2-fwnode.c | 42 ++++++++++++++++++++++++
+ include/media/v4l2-fwnode.h | 47 +++++++++++++++++++++++++++
+ 2 files changed, 89 insertions(+)
+
+--- a/drivers/media/v4l2-core/v4l2-fwnode.c
++++ b/drivers/media/v4l2-core/v4l2-fwnode.c
+@@ -599,6 +599,48 @@ void v4l2_fwnode_put_link(struct v4l2_fw
+ }
+ EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link);
+
++int v4l2_fwnode_device_parse(struct device *dev,
++ struct v4l2_fwnode_device_properties *props)
++{
++ struct fwnode_handle *fwnode = dev_fwnode(dev);
++ u32 val;
++ int ret;
++
++ memset(props, 0, sizeof(*props));
++
++ props->orientation = V4L2_FWNODE_PROPERTY_UNSET;
++ ret = fwnode_property_read_u32(fwnode, "orientation", &val);
++ if (!ret) {
++ switch (val) {
++ case V4L2_FWNODE_ORIENTATION_FRONT:
++ case V4L2_FWNODE_ORIENTATION_BACK:
++ case V4L2_FWNODE_ORIENTATION_EXTERNAL:
++ break;
++ default:
++ dev_warn(dev, "Unsupported device orientation: %u\n", val);
++ return -EINVAL;
++ }
++
++ props->orientation = val;
++ dev_dbg(dev, "device orientation: %u\n", val);
++ }
++
++ props->rotation = V4L2_FWNODE_PROPERTY_UNSET;
++ ret = fwnode_property_read_u32(fwnode, "rotation", &val);
++ if (!ret) {
++ if (val >= 360) {
++ dev_warn(dev, "Unsupported device rotation: %u\n", val);
++ return -EINVAL;
++ }
++
++ props->rotation = val;
++ dev_dbg(dev, "device rotation: %u\n", val);
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(v4l2_fwnode_device_parse);
++
+ static int
+ v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev,
+ struct v4l2_async_notifier *notifier,
+--- a/include/media/v4l2-fwnode.h
++++ b/include/media/v4l2-fwnode.h
+@@ -110,6 +110,36 @@ struct v4l2_fwnode_endpoint {
+ };
+
+ /**
++ * V4L2_FWNODE_PROPERTY_UNSET - identify a non initialized property
++ *
++ * All properties in &struct v4l2_fwnode_device_properties are initialized
++ * to this value.
++ */
++#define V4L2_FWNODE_PROPERTY_UNSET (-1U)
++
++/**
++ * enum v4l2_fwnode_orientation - possible device orientation
++ * @V4L2_FWNODE_ORIENTATION_FRONT: device installed on the front side
++ * @V4L2_FWNODE_ORIENTATION_BACK: device installed on the back side
++ * @V4L2_FWNODE_ORIENTATION_EXTERNAL: device externally located
++ */
++enum v4l2_fwnode_orientation {
++ V4L2_FWNODE_ORIENTATION_FRONT,
++ V4L2_FWNODE_ORIENTATION_BACK,
++ V4L2_FWNODE_ORIENTATION_EXTERNAL
++};
++
++/**
++ * struct v4l2_fwnode_device_properties - fwnode device properties
++ * @orientation: device orientation. See &enum v4l2_fwnode_orientation
++ * @rotation: device rotation
++ */
++struct v4l2_fwnode_device_properties {
++ enum v4l2_fwnode_orientation orientation;
++ unsigned int rotation;
++};
++
++/**
+ * struct v4l2_fwnode_link - a link between two endpoints
+ * @local_node: pointer to device_node of this endpoint
+ * @local_port: identifier of the port this endpoint belongs to
+@@ -234,6 +264,23 @@ int v4l2_fwnode_parse_link(struct fwnode
+ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link);
+
+ /**
++ * v4l2_fwnode_device_parse() - parse fwnode device properties
++ * @dev: pointer to &struct device
++ * @props: pointer to &struct v4l2_fwnode_device_properties where to store the
++ * parsed properties values
++ *
++ * This function parses and validates the V4L2 fwnode device properties from the
++ * firmware interface, and fills the @struct v4l2_fwnode_device_properties
++ * provided by the caller.
++ *
++ * Return:
++ * % 0 on success
++ * %-EINVAL if a parsed property value is not valid
++ */
++int v4l2_fwnode_device_parse(struct device *dev,
++ struct v4l2_fwnode_device_properties *props);
++
++/**
+ * typedef parse_endpoint_func - Driver's callback function to be called on
+ * each V4L2 fwnode endpoint.
+ *
diff --git a/target/linux/bcm27xx/patches-5.4/950-0908-media-v4l2-ctrls-Add-helper-to-register-properties.patch b/target/linux/bcm27xx/patches-5.4/950-0908-media-v4l2-ctrls-Add-helper-to-register-properties.patch
new file mode 100644
index 0000000000..a76de95bf3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0908-media-v4l2-ctrls-Add-helper-to-register-properties.patch
@@ -0,0 +1,114 @@
+From 67429ff939ad15a313663a05461d7a07d209449f Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo@jmondi.org>
+Date: Sat, 9 May 2020 11:04:52 +0200
+Subject: [PATCH] media: v4l2-ctrls: Add helper to register
+ properties
+
+Add an helper function to v4l2-ctrls to register controls associated
+with a device property.
+
+Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+Commit e0a360630debdf12355d9ec9f1417172c3fa6756 upstream
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+---
+ drivers/media/v4l2-core/v4l2-ctrls.c | 40 ++++++++++++++++++++++++++++
+ include/media/v4l2-ctrls.h | 26 ++++++++++++++++++
+ 2 files changed, 66 insertions(+)
+
+--- a/drivers/media/v4l2-core/v4l2-ctrls.c
++++ b/drivers/media/v4l2-core/v4l2-ctrls.c
+@@ -17,6 +17,7 @@
+ #include <media/v4l2-ctrls.h>
+ #include <media/v4l2-event.h>
+ #include <media/v4l2-dev.h>
++#include <media/v4l2-fwnode.h>
+
+ #define dprintk(vdev, fmt, arg...) do { \
+ if (!WARN_ON(!(vdev)) && ((vdev)->dev_debug & V4L2_DEV_DEBUG_CTRL)) \
+@@ -4577,3 +4578,42 @@ __poll_t v4l2_ctrl_poll(struct file *fil
+ return 0;
+ }
+ EXPORT_SYMBOL(v4l2_ctrl_poll);
++
++int v4l2_ctrl_new_fwnode_properties(struct v4l2_ctrl_handler *hdl,
++ const struct v4l2_ctrl_ops *ctrl_ops,
++ const struct v4l2_fwnode_device_properties *p)
++{
++ if (p->orientation != V4L2_FWNODE_PROPERTY_UNSET) {
++ u32 orientation_ctrl;
++
++ switch (p->orientation) {
++ case V4L2_FWNODE_ORIENTATION_FRONT:
++ orientation_ctrl = V4L2_CAMERA_ORIENTATION_FRONT;
++ break;
++ case V4L2_FWNODE_ORIENTATION_BACK:
++ orientation_ctrl = V4L2_CAMERA_ORIENTATION_BACK;
++ break;
++ case V4L2_FWNODE_ORIENTATION_EXTERNAL:
++ orientation_ctrl = V4L2_CAMERA_ORIENTATION_EXTERNAL;
++ break;
++ default:
++ return -EINVAL;
++ }
++ if (!v4l2_ctrl_new_std_menu(hdl, ctrl_ops,
++ V4L2_CID_CAMERA_ORIENTATION,
++ V4L2_CAMERA_ORIENTATION_EXTERNAL, 0,
++ orientation_ctrl))
++ return hdl->error;
++ }
++
++ if (p->rotation != V4L2_FWNODE_PROPERTY_UNSET) {
++ if (!v4l2_ctrl_new_std(hdl, ctrl_ops,
++ V4L2_CID_CAMERA_SENSOR_ROTATION,
++ p->rotation, p->rotation, 1,
++ p->rotation))
++ return hdl->error;
++ }
++
++ return hdl->error;
++}
++EXPORT_SYMBOL(v4l2_ctrl_new_fwnode_properties);
+--- a/include/media/v4l2-ctrls.h
++++ b/include/media/v4l2-ctrls.h
+@@ -29,6 +29,7 @@ struct v4l2_ctrl_handler;
+ struct v4l2_ctrl_helper;
+ struct v4l2_ctrl;
+ struct video_device;
++struct v4l2_fwnode_device_properties;
+ struct v4l2_subdev;
+ struct v4l2_subscribed_event;
+ struct v4l2_fh;
+@@ -1379,4 +1380,29 @@ int v4l2_ctrl_subdev_subscribe_event(str
+ */
+ int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd);
+
++/**
++ * v4l2_ctrl_new_fwnode_properties() - Register controls for the device
++ * properties
++ *
++ * @hdl: pointer to &struct v4l2_ctrl_handler to register controls on
++ * @ctrl_ops: pointer to &struct v4l2_ctrl_ops to register controls with
++ * @p: pointer to &struct v4l2_fwnode_device_properties
++ *
++ * This function registers controls associated to device properties, using the
++ * property values contained in @p parameter, if the property has been set to
++ * a value.
++ *
++ * Currently the following v4l2 controls are parsed and registered:
++ * - V4L2_CID_CAMERA_ORIENTATION
++ * - V4L2_CID_CAMERA_SENSOR_ROTATION;
++ *
++ * Controls already registered by the caller with the @hdl control handler are
++ * not overwritten. Callers should register the controls they want to handle
++ * themselves before calling this function.
++ *
++ * Return: 0 on success, a negative error code on failure.
++ */
++int v4l2_ctrl_new_fwnode_properties(struct v4l2_ctrl_handler *hdl,
++ const struct v4l2_ctrl_ops *ctrl_ops,
++ const struct v4l2_fwnode_device_properties *p);
+ #endif
diff --git a/target/linux/bcm27xx/patches-5.4/950-0909-media-i2c-ov5647-Parse-and-register-properties.patch b/target/linux/bcm27xx/patches-5.4/950-0909-media-i2c-ov5647-Parse-and-register-properties.patch
new file mode 100644
index 0000000000..ac7d70c392
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0909-media-i2c-ov5647-Parse-and-register-properties.patch
@@ -0,0 +1,49 @@
+From 4b738c3d5c0f2719642b9515cece7fbfce9dc108 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Sat, 4 Jul 2020 01:45:08 +0300
+Subject: [PATCH] media: i2c: ov5647: Parse and register properties
+
+Parse device properties and register controls for them using the V4L2
+fwnode properties helpers.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+---
+ drivers/media/i2c/ov5647.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/i2c/ov5647.c
++++ b/drivers/media/i2c/ov5647.c
+@@ -1501,6 +1501,7 @@ static int ov5647_probe(struct i2c_clien
+ struct device_node *np = client->dev.of_node;
+ u32 xclk_freq;
+ int hblank, exposure_max, exposure_def;
++ struct v4l2_fwnode_device_properties props;
+
+ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
+ if (!sensor)
+@@ -1534,7 +1535,7 @@ static int ov5647_probe(struct i2c_clien
+ mutex_init(&sensor->lock);
+
+ /* Initialise controls. */
+- v4l2_ctrl_handler_init(&sensor->ctrls, 7);
++ v4l2_ctrl_handler_init(&sensor->ctrls, 9);
+ v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
+ V4L2_CID_AUTOGAIN,
+ 0, /* min */
+@@ -1598,6 +1599,16 @@ static int ov5647_probe(struct i2c_clien
+ __func__, ret);
+ goto error;
+ }
++
++ ret = v4l2_fwnode_device_parse(&client->dev, &props);
++ if (ret)
++ goto error;
++
++ ret = v4l2_ctrl_new_fwnode_properties(&sensor->ctrls, &ov5647_ctrl_ops,
++ &props);
++ if (ret)
++ goto error;
++
+ sensor->sd.ctrl_handler = &sensor->ctrls;
+
+ /* Write out the register set over I2C on stream-on. */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0910-media-i2c-imx219-Parse-and-register-properties.patch b/target/linux/bcm27xx/patches-5.4/950-0910-media-i2c-imx219-Parse-and-register-properties.patch
new file mode 100644
index 0000000000..dc5584e847
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0910-media-i2c-imx219-Parse-and-register-properties.patch
@@ -0,0 +1,51 @@
+From db0889b08409484160a9082bc0b5f39877fe9591 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo@jmondi.org>
+Date: Sat, 9 May 2020 11:04:55 +0200
+Subject: [PATCH] media: i2c: imx219: Parse and register properties
+
+Parse device properties and register controls for them using the newly
+introduced helpers.
+
+Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+Commit ad3a44cbd1b2e1559c6b93e80dc0c9c29632969a upstream
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+---
+ drivers/media/i2c/imx219.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/i2c/imx219.c
++++ b/drivers/media/i2c/imx219.c
+@@ -1348,11 +1348,12 @@ static int imx219_init_controls(struct i
+ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
+ struct v4l2_ctrl_handler *ctrl_hdlr;
+ unsigned int height = imx219->mode->height;
++ struct v4l2_fwnode_device_properties props;
+ int exposure_max, exposure_def, hblank;
+ int i, ret;
+
+ ctrl_hdlr = &imx219->ctrl_handler;
+- ret = v4l2_ctrl_handler_init(ctrl_hdlr, 9);
++ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 11);
+ if (ret)
+ return ret;
+
+@@ -1431,6 +1432,15 @@ static int imx219_init_controls(struct i
+ goto error;
+ }
+
++ ret = v4l2_fwnode_device_parse(&client->dev, &props);
++ if (ret)
++ goto error;
++
++ ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx219_ctrl_ops,
++ &props);
++ if (ret)
++ goto error;
++
+ imx219->sd.ctrl_handler = ctrl_hdlr;
+
+ return 0;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0911-media-i2c-imx477-Parse-and-register-properties.patch b/target/linux/bcm27xx/patches-5.4/950-0911-media-i2c-imx477-Parse-and-register-properties.patch
new file mode 100644
index 0000000000..fe022c9b57
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0911-media-i2c-imx477-Parse-and-register-properties.patch
@@ -0,0 +1,45 @@
+From df12dbc41bbdb2b949eb395088f9d6b197d9db8a Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Sat, 4 Jul 2020 01:45:08 +0300
+Subject: [PATCH] media: i2c: imx477: Parse and register properties
+
+Parse device properties and register controls for them using the V4L2
+fwnode properties helpers.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+---
+ drivers/media/i2c/imx477.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/i2c/imx477.c
++++ b/drivers/media/i2c/imx477.c
+@@ -1957,11 +1957,12 @@ static int imx477_init_controls(struct i
+ {
+ struct v4l2_ctrl_handler *ctrl_hdlr;
+ struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd);
++ struct v4l2_fwnode_device_properties props;
+ unsigned int i;
+ int ret;
+
+ ctrl_hdlr = &imx477->ctrl_handler;
+- ret = v4l2_ctrl_handler_init(ctrl_hdlr, 14);
++ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 16);
+ if (ret)
+ return ret;
+
+@@ -2045,6 +2046,15 @@ static int imx477_init_controls(struct i
+ goto error;
+ }
+
++ ret = v4l2_fwnode_device_parse(&client->dev, &props);
++ if (ret)
++ goto error;
++
++ ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx477_ctrl_ops,
++ &props);
++ if (ret)
++ goto error;
++
+ imx477->sd.ctrl_handler = ctrl_hdlr;
+
+ /* Setup exposure and frame/line length limits. */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0912-dt-dtoverlays-ov5647-Add-parameter-to-set-camera-mod.patch b/target/linux/bcm27xx/patches-5.4/950-0912-dt-dtoverlays-ov5647-Add-parameter-to-set-camera-mod.patch
new file mode 100644
index 0000000000..23a2fb9c26
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0912-dt-dtoverlays-ov5647-Add-parameter-to-set-camera-mod.patch
@@ -0,0 +1,49 @@
+From 7d2efa734da00de05c8a58688da28cf1e380ef3a Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Sat, 4 Jul 2020 03:04:38 +0300
+Subject: [PATCH] dt/dtoverlays: ov5647: Add parameter to set camera
+ module rotation
+
+Add a rotation DT overlay parameter to allow specifying the camera
+module mounting rotation.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+---
+ arch/arm/boot/dts/overlays/README | 5 +++--
+ arch/arm/boot/dts/overlays/ov5647-overlay.dts | 6 ++++++
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1809,8 +1809,9 @@ Name: ov5647
+ Info: Omnivision OV5647 camera module.
+ Uses Unicam 1, which is the standard camera connector on most Pi
+ variants.
+-Load: dtoverlay=ov5647
+-Params: <None>
++Load: dtoverlay=ov5647,<param>=<val>
++Params: rotation Mounting rotation of the camera sensor (0 or
++ 180, default 0)
+
+
+ Name: ov7251
+--- a/arch/arm/boot/dts/overlays/ov5647-overlay.dts
++++ b/arch/arm/boot/dts/overlays/ov5647-overlay.dts
+@@ -21,6 +21,8 @@
+ pwdn-gpios = <&gpio 41 1>, <&gpio 32 1>;
+ clocks = <&ov5647_clk>;
+
++ rotation = <0>;
++
+ port {
+ ov5647_0: endpoint {
+ remote-endpoint = <&csi1_ep>;
+@@ -83,4 +85,8 @@
+ };
+ };
+ };
++
++ __overrides__ {
++ rotation = <&ov5647>,"rotation:0";
++ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0913-dt-dtoverlays-imx219-Add-parameter-to-set-camera-mod.patch b/target/linux/bcm27xx/patches-5.4/950-0913-dt-dtoverlays-imx219-Add-parameter-to-set-camera-mod.patch
new file mode 100644
index 0000000000..be22dd3316
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0913-dt-dtoverlays-imx219-Add-parameter-to-set-camera-mod.patch
@@ -0,0 +1,50 @@
+From 30fbdcf8d58658860e43c0396cb50c5d4ade2dc5 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Sat, 4 Jul 2020 03:04:38 +0300
+Subject: [PATCH] dt/dtoverlays: imx219: Add parameter to set camera
+ module rotation
+
+Add a rotation DT overlay parameter to allow specifying the camera
+module mounting rotation. Set the default rotation to 180 as the module
+is typically mounted upside-down.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+---
+ arch/arm/boot/dts/overlays/README | 5 +++--
+ arch/arm/boot/dts/overlays/imx219-overlay.dts | 6 ++++++
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1433,8 +1433,9 @@ Name: imx219
+ Info: Sony IMX219 camera module.
+ Uses Unicam 1, which is the standard camera connector on most Pi
+ variants.
+-Load: dtoverlay=imx219
+-Params: <None>
++Load: dtoverlay=imx219,<param>=<val>
++Params: rotation Mounting rotation of the camera sensor (0 or
++ 180, default 180)
+
+
+ Name: imx290
+--- a/arch/arm/boot/dts/overlays/imx219-overlay.dts
++++ b/arch/arm/boot/dts/overlays/imx219-overlay.dts
+@@ -27,6 +27,8 @@
+ VDIG-supply = <&imx219_vdig>; /* 1.8v */
+ VDDL-supply = <&imx219_vddl>; /* 1.2v */
+
++ rotation = <180>;
++
+ port {
+ imx219_0: endpoint {
+ remote-endpoint = <&csi1_ep>;
+@@ -110,4 +112,8 @@
+ cam0-pwdn = <&imx219_vana>,"gpio:4";
+ };
+ };
++
++ __overrides__ {
++ rotation = <&imx219>,"rotation:0";
++ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0914-dt-dtoverlays-imx477-Add-parameter-to-set-camera-mod.patch b/target/linux/bcm27xx/patches-5.4/950-0914-dt-dtoverlays-imx477-Add-parameter-to-set-camera-mod.patch
new file mode 100644
index 0000000000..11a5d3da98
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0914-dt-dtoverlays-imx477-Add-parameter-to-set-camera-mod.patch
@@ -0,0 +1,50 @@
+From afed51afadb2f5d43e093c969bdf6535b2ea0ad3 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Sat, 4 Jul 2020 03:04:38 +0300
+Subject: [PATCH] dt/dtoverlays: imx477: Add parameter to set camera
+ module rotation
+
+Add a rotation DT overlay parameter to allow specifying the camera
+module mounting rotation. Set the default rotation to 180 as the module
+is typically mounted upside-down.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+---
+ arch/arm/boot/dts/overlays/README | 5 +++--
+ arch/arm/boot/dts/overlays/imx477-overlay.dts | 6 ++++++
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1458,8 +1458,9 @@ Name: imx477
+ Info: Sony IMX477 camera module.
+ Uses Unicam 1, which is the standard camera connector on most Pi
+ variants.
+-Load: dtoverlay=imx477
+-Params: <None>
++Load: dtoverlay=imx477,<param>=<val>
++Params: rotation Mounting rotation of the camera sensor (0 or
++ 180, default 180)
+
+
+ Name: iqaudio-codec
+--- a/arch/arm/boot/dts/overlays/imx477-overlay.dts
++++ b/arch/arm/boot/dts/overlays/imx477-overlay.dts
+@@ -27,6 +27,8 @@
+ VDIG-supply = <&imx477_vdig>; /* 1.05v */
+ VDDL-supply = <&imx477_vddl>; /* 1.8v */
+
++ rotation = <180>;
++
+ port {
+ imx477_0: endpoint {
+ remote-endpoint = <&csi1_ep>;
+@@ -110,4 +112,8 @@
+ cam0-pwdn = <&imx477_vana>,"gpio:4";
+ };
+ };
++
++ __overrides__ {
++ rotation = <&imx477>,"rotation:0";
++ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0915-drm-vc4-Add-DRM_MODE_FLAG_DBLCLK-support-to-vc4-fkms.patch b/target/linux/bcm27xx/patches-5.4/950-0915-drm-vc4-Add-DRM_MODE_FLAG_DBLCLK-support-to-vc4-fkms.patch
new file mode 100644
index 0000000000..a7a1d91290
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0915-drm-vc4-Add-DRM_MODE_FLAG_DBLCLK-support-to-vc4-fkms.patch
@@ -0,0 +1,54 @@
+From 16349a9b271d331a496a482f46f41a3e1db56891 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 16 Jul 2020 12:02:47 +0100
+Subject: [PATCH] drm/vc4: Add DRM_MODE_FLAG_DBLCLK support to
+ vc4-fkms
+
+480i and several other modes use DRM_MODE_FLAG_DBLCLK and pixel
+replication.
+
+Add in flags for that so that FKMS can select CEA modes 6 & 7.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -158,6 +158,8 @@ struct set_timings {
+ #define TIMINGS_FLAGS_RGB_LIMITED BIT(8)
+ /* DVI monitor, therefore disable infoframes. Not set corresponds to HDMI. */
+ #define TIMINGS_FLAGS_DVI BIT(9)
++/* Double clock */
++#define TIMINGS_FLAGS_DBL_CLK BIT(10)
+ };
+
+ struct mailbox_set_mode {
+@@ -946,6 +948,8 @@ static void vc4_crtc_mode_set_nofb(struc
+
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ mb.timings.flags |= TIMINGS_FLAGS_INTERLACE;
++ if (mode->flags & DRM_MODE_FLAG_DBLCLK)
++ mb.timings.flags |= TIMINGS_FLAGS_DBL_CLK;
+
+ mb.timings.video_id_code = frame.avi.video_code;
+
+@@ -1104,11 +1108,16 @@ vc4_crtc_mode_valid(struct drm_crtc *crt
+ */
+ if (fkms->bcm2711 &&
+ (vc4_crtc->display_number == 2 || vc4_crtc->display_number == 7) &&
++ !(mode->flags & DRM_MODE_FLAG_DBLCLK) &&
+ ((mode->hdisplay | /* active */
+ (mode->hsync_start - mode->hdisplay) | /* front porch */
+ (mode->hsync_end - mode->hsync_start) | /* sync pulse */
+- (mode->htotal - mode->hsync_end)) & 1)) /* back porch */
++ (mode->htotal - mode->hsync_end)) & 1)) /* back porch */ {
++ DRM_DEBUG_KMS("[CRTC:%d] Odd timing rejected %u %u %u %u.\n",
++ crtc->base.id, mode->hdisplay, mode->hsync_start,
++ mode->hsync_end, mode->htotal);
+ return MODE_H_ILLEGAL;
++ }
+
+ return MODE_OK;
+ }
diff --git a/target/linux/bcm27xx/patches-5.4/950-0916-leds-Add-the-actpwr-trigger.patch b/target/linux/bcm27xx/patches-5.4/950-0916-leds-Add-the-actpwr-trigger.patch
new file mode 100644
index 0000000000..2f0aaa0006
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0916-leds-Add-the-actpwr-trigger.patch
@@ -0,0 +1,236 @@
+From 6586d75915287dd336b71e17826f037be7926ebe Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 13 Jul 2020 10:33:19 +0100
+Subject: [PATCH] leds: Add the actpwr trigger
+
+The actpwr trigger is a meta trigger that cycles between an inverted
+mmc0 and default-on. It is written in a way that could fairly easily
+be generalised to support alternative sets of source triggers.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/leds/trigger/Kconfig | 11 ++
+ drivers/leds/trigger/Makefile | 1 +
+ drivers/leds/trigger/ledtrig-actpwr.c | 191 ++++++++++++++++++++++++++
+ 3 files changed, 203 insertions(+)
+ create mode 100644 drivers/leds/trigger/ledtrig-actpwr.c
+
+--- a/drivers/leds/trigger/Kconfig
++++ b/drivers/leds/trigger/Kconfig
+@@ -151,4 +151,15 @@ config LEDS_TRIGGER_AUDIO
+ the audio mute and mic-mute changes.
+ If unsure, say N
+
++config LEDS_TRIGGER_ACTPWR
++ tristate "ACT/PWR Input Trigger"
++ depends on LEDS_TRIGGERS
++ help
++ This trigger is intended for platforms that have one software-
++ controllable LED and no dedicated activity or power LEDs, hence the
++ need to make the one LED perform both functions. It cycles between
++ default-on and an inverted mmc0 every 500ms, guaranteeing that it is
++ on for at least half of the time.
++ If unsure, say N.
++
+ endif # LEDS_TRIGGERS
+--- a/drivers/leds/trigger/Makefile
++++ b/drivers/leds/trigger/Makefile
+@@ -16,3 +16,4 @@ obj-$(CONFIG_LEDS_TRIGGER_PANIC) += ledt
+ obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o
+ obj-$(CONFIG_LEDS_TRIGGER_PATTERN) += ledtrig-pattern.o
+ obj-$(CONFIG_LEDS_TRIGGER_AUDIO) += ledtrig-audio.o
++obj-$(CONFIG_LEDS_TRIGGER_ACTPWR) += ledtrig-actpwr.o
+--- /dev/null
++++ b/drivers/leds/trigger/ledtrig-actpwr.c
+@@ -0,0 +1,191 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Activity/power trigger
++ *
++ * Copyright (C) 2020 Raspberry Pi (Trading) Ltd.
++ *
++ * Based on Atsushi Nemoto's ledtrig-heartbeat.c, although there may be
++ * nothing left of the original now.
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/timer.h>
++#include <linux/leds.h>
++#include "../leds.h"
++
++enum {
++ TRIG_ACT,
++ TRIG_PWR,
++
++ TRIG_COUNT
++};
++
++struct actpwr_trig_src {
++ const char *name;
++ int interval;
++ bool invert;
++};
++
++struct actpwr_vled {
++ struct led_classdev cdev;
++ struct actpwr_trig_data *parent;
++ enum led_brightness value;
++ unsigned int interval;
++ bool invert;
++};
++
++struct actpwr_trig_data {
++ struct led_trigger trig;
++ struct actpwr_vled virt_leds[TRIG_COUNT];
++ struct actpwr_vled *active;
++ struct timer_list timer;
++ int next_active;
++};
++
++static int actpwr_trig_activate(struct led_classdev *led_cdev);
++static void actpwr_trig_deactivate(struct led_classdev *led_cdev);
++
++static const struct actpwr_trig_src actpwr_trig_sources[TRIG_COUNT] = {
++ [TRIG_ACT] = { "mmc0", 500, true },
++ [TRIG_PWR] = { "default-on", 500, false },
++};
++
++static struct actpwr_trig_data actpwr_data = {
++ {
++ .name = "actpwr",
++ .activate = actpwr_trig_activate,
++ .deactivate = actpwr_trig_deactivate,
++ }
++};
++
++static void actpwr_brightness_set(struct led_classdev *led_cdev,
++ enum led_brightness value)
++{
++ struct actpwr_vled *vled = container_of(led_cdev, struct actpwr_vled,
++ cdev);
++ struct actpwr_trig_data *trig = vled->parent;
++
++ if (vled->invert)
++ value = !value;
++ vled->value = value;
++
++ if (vled == trig->active)
++ led_trigger_event(&trig->trig, value);
++}
++
++static int actpwr_brightness_set_blocking(struct led_classdev *led_cdev,
++ enum led_brightness value)
++{
++ actpwr_brightness_set(led_cdev, value);
++ return 0;
++}
++
++static enum led_brightness actpwr_brightness_get(struct led_classdev *led_cdev)
++{
++ struct actpwr_vled *vled = container_of(led_cdev, struct actpwr_vled,
++ cdev);
++
++ return vled->value;
++}
++
++static void actpwr_trig_cycle(struct timer_list *t)
++{
++ struct actpwr_trig_data *trig = &actpwr_data;
++ struct actpwr_vled *active;
++ enum led_brightness value;
++
++ active = &trig->virt_leds[trig->next_active];
++ trig->active = active;
++ trig->next_active = (trig->next_active + 1) % TRIG_COUNT;
++
++ led_trigger_event(&trig->trig, active->value);
++
++ mod_timer(&trig->timer, jiffies + msecs_to_jiffies(active->interval));
++}
++
++static int actpwr_trig_activate(struct led_classdev *led_cdev)
++{
++ struct actpwr_trig_data *trig = &actpwr_data;
++
++ /* Start the timer if this is the first LED */
++ if (!trig->active)
++ actpwr_trig_cycle(&trig->timer);
++ else
++ led_set_brightness_nosleep(led_cdev, trig->active->value);
++
++ return 0;
++}
++
++static void actpwr_trig_deactivate(struct led_classdev *led_cdev)
++{
++ struct actpwr_trig_data *trig = &actpwr_data;
++
++ if (list_empty(&trig->trig.led_cdevs)) {
++ del_timer_sync(&trig->timer);
++ trig->active = NULL;
++ }
++}
++
++static int __init actpwr_trig_init(void)
++{
++ struct actpwr_trig_data *trig = &actpwr_data;
++ int ret = 0;
++ int i;
++
++ timer_setup(&trig->timer, actpwr_trig_cycle, 0);
++
++ /* Register one "LED" for each source trigger */
++ for (i = 0; i < TRIG_COUNT; i++)
++ {
++ struct actpwr_vled *vled = &trig->virt_leds[i];
++ struct led_classdev *cdev = &vled->cdev;
++ const struct actpwr_trig_src *src = &actpwr_trig_sources[i];
++
++ vled->parent = trig;
++ vled->interval = src->interval;
++ vled->invert = src->invert;
++ cdev->name = src->name;
++ cdev->brightness_set = actpwr_brightness_set;
++ cdev->brightness_set_blocking = actpwr_brightness_set_blocking;
++ cdev->brightness_get = actpwr_brightness_get;
++ cdev->default_trigger = src->name;
++ ret = led_classdev_register(NULL, cdev);
++ if (ret)
++ goto error_classdev;
++ }
++
++ ret = led_trigger_register(&trig->trig);
++ if (ret)
++ goto error_classdev;
++
++ return 0;
++
++error_classdev:
++ while (i > 0)
++ {
++ i--;
++ led_classdev_unregister(&trig->virt_leds[i].cdev);
++ }
++
++ return ret;
++}
++
++static void __exit actpwr_trig_exit(void)
++{
++ int i;
++
++ led_trigger_unregister(&actpwr_data.trig);
++ for (i = 0; i < TRIG_COUNT; i++)
++ {
++ led_classdev_unregister(&actpwr_data.virt_leds[i].cdev);
++ }
++}
++
++module_init(actpwr_trig_init);
++module_exit(actpwr_trig_exit);
++
++MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>");
++MODULE_DESCRIPTION("ACT/PWR LED trigger");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/bcm27xx/patches-5.4/950-0917-ARM-dts-Select-the-actpwr-LED-trigger-on-Zeroes.patch b/target/linux/bcm27xx/patches-5.4/950-0917-ARM-dts-Select-the-actpwr-LED-trigger-on-Zeroes.patch
new file mode 100644
index 0000000000..02f425a9b1
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0917-ARM-dts-Select-the-actpwr-LED-trigger-on-Zeroes.patch
@@ -0,0 +1,41 @@
+From 990bc7c8a234a0f446a7d56067b1a9f8348e0f35 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 16 Jul 2020 18:19:58 +0100
+Subject: [PATCH] ARM: dts: Select the actpwr LED trigger on Zeroes
+
+The new "actpwr" LED trigger guarantees that the combined PWR and ACT
+LED is on for at least half of every second. Under heavy SD card
+load it emits a steady 1Hz square wave.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 4 ++--
+ arch/arm/boot/dts/bcm2708-rpi-zero.dts | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts
+@@ -144,8 +144,8 @@
+ &leds {
+ act_led: act {
+ label = "led0";
+- linux,default-trigger = "mmc0";
+- gpios = <&gpio 47 0>;
++ linux,default-trigger = "actpwr";
++ gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+--- a/arch/arm/boot/dts/bcm2708-rpi-zero.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts
+@@ -98,8 +98,8 @@
+ &leds {
+ act_led: act {
+ label = "led0";
+- linux,default-trigger = "mmc0";
+- gpios = <&gpio 47 0>;
++ linux,default-trigger = "actpwr";
++ gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
+ };
+ };
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0918-staging-vc04_services-isp-Rework-lens-shading-to-tak.patch b/target/linux/bcm27xx/patches-5.4/950-0918-staging-vc04_services-isp-Rework-lens-shading-to-tak.patch
new file mode 100644
index 0000000000..8748214797
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0918-staging-vc04_services-isp-Rework-lens-shading-to-tak.patch
@@ -0,0 +1,87 @@
+From 7504f92483407233d9093e164d8f001db5c374e5 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 8 May 2020 22:05:29 +0100
+Subject: [PATCH] staging: vc04_services: isp: Rework lens shading to
+ take a dmabuf
+
+This removes the need for the client to use vcsm at all.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../bcm2835-isp/bcm2835-v4l2-isp.c | 36 +++++++++++++++++--
+ include/uapi/linux/bcm2835-isp.h | 4 +--
+ 2 files changed, 35 insertions(+), 5 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
+@@ -21,6 +21,8 @@
+ #include "vchiq-mmal/mmal-parameters.h"
+ #include "vchiq-mmal/mmal-vchiq.h"
+
++#include "vc-sm-cma/vc_sm_knl.h"
++
+ #include "bcm2835_isp_ctrls.h"
+ #include "bcm2835_isp_fmts.h"
+
+@@ -722,10 +724,38 @@ static int bcm2835_isp_s_ctrl(struct v4l
+ sizeof(struct bcm2835_isp_custom_ccm));
+ break;
+ case V4L2_CID_USER_BCM2835_ISP_LENS_SHADING:
+- ret = set_isp_param(node, MMAL_PARAMETER_LENS_SHADING_OVERRIDE,
+- ctrl->p_new.p_u8,
+- sizeof(struct bcm2835_isp_lens_shading));
++ {
++ struct bcm2835_isp_lens_shading ls;
++ struct dma_buf *dmabuf;
++ void *vcsm_handle;
++
++ memcpy(&ls, ctrl->p_new.p_u8,
++ sizeof(struct bcm2835_isp_lens_shading));
++
++ dmabuf = dma_buf_get(ls.dmabuf);
++ if (!dmabuf)
++ return -EINVAL;
++
++ ret = vc_sm_cma_import_dmabuf(dmabuf,
++ &vcsm_handle);
++ if (ret) {
++ dma_buf_put(dmabuf);
++ return -EINVAL;
++ }
++
++ ls.dmabuf = vc_sm_cma_int_handle(vcsm_handle);
++ if (ls.dmabuf)
++ ret = set_isp_param(node,
++ MMAL_PARAMETER_LENS_SHADING_OVERRIDE,
++ &ls,
++ sizeof(struct bcm2835_isp_lens_shading));
++ else
++ ret = -EINVAL;
++
++ vc_sm_cma_free(vcsm_handle);
++ dma_buf_put(dmabuf);
+ break;
++ }
+ case V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL:
+ ret = set_isp_param(node, MMAL_PARAMETER_BLACK_LEVEL,
+ ctrl->p_new.p_u8,
+--- a/include/uapi/linux/bcm2835-isp.h
++++ b/include/uapi/linux/bcm2835-isp.h
+@@ -108,7 +108,7 @@ enum bcm2835_isp_gain_format {
+ * @grid_stride: Row to row distance (in grid cells) between grid cells
+ * in the same horizontal location.
+ * @grid_height: Height of lens shading tables in grid cells.
+- * @mem_handle_table: Memory handle to the tables.
++ * @dmabuf: dmabuf file handle containing the table.
+ * @ref_transform: Reference transform - unsupported, please pass zero.
+ * @corner_sampled: Whether the gains are sampled at the corner points
+ * of the grid cells or in the cell centres.
+@@ -120,7 +120,7 @@ struct bcm2835_isp_lens_shading {
+ __u32 grid_width;
+ __u32 grid_stride;
+ __u32 grid_height;
+- __u32 mem_handle_table;
++ __s32 dmabuf;
+ __u32 ref_transform;
+ __u32 corner_sampled;
+ __u32 gain_format;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0919-Mute-bug-fix-for-the-Audioinjector.net-isolated-soun.patch b/target/linux/bcm27xx/patches-5.4/950-0919-Mute-bug-fix-for-the-Audioinjector.net-isolated-soun.patch
new file mode 100644
index 0000000000..10fe757577
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0919-Mute-bug-fix-for-the-Audioinjector.net-isolated-soun.patch
@@ -0,0 +1,64 @@
+From 11a2b192e0a8b7514895f9f6b7451f4c6ddd0a22 Mon Sep 17 00:00:00 2001
+From: Matt Flax <flatmax@flatmax.org>
+Date: Fri, 17 Jul 2020 09:17:36 +1000
+Subject: [PATCH] Mute bug fix for the Audioinjector.net isolated
+ soundcard.
+
+---
+ .../bcm/audioinjector-isolated-soundcard.c | 26 +++----------------
+ 1 file changed, 3 insertions(+), 23 deletions(-)
+
+--- a/sound/soc/bcm/audioinjector-isolated-soundcard.c
++++ b/sound/soc/bcm/audioinjector-isolated-soundcard.c
+@@ -42,41 +42,20 @@ static int audioinjector_isolated_dai_in
+ int ret=snd_soc_dai_set_sysclk(rtd->codec_dai, 0, 24576000, 0);
+ if (ret)
+ return ret;
+-
+ return snd_soc_dai_set_bclk_ratio(rtd->cpu_dai, 64);
+ }
+
+ static int audioinjector_isolated_startup(struct snd_pcm_substream *substream)
+ {
+ snd_pcm_hw_constraint_list(substream->runtime, 0,
+- SNDRV_PCM_HW_PARAM_RATE, &audioinjector_isolated_constraints);
+-
+- return 0;
+-}
++ SNDRV_PCM_HW_PARAM_RATE, &audioinjector_isolated_constraints);
+
+-static int audioinjector_isolated_trigger(struct snd_pcm_substream *substream,
+- int cmd){
+-
+- switch (cmd) {
+- case SNDRV_PCM_TRIGGER_STOP:
+- case SNDRV_PCM_TRIGGER_SUSPEND:
+- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+- gpiod_set_value(mute_gpio, 0);
+- break;
+- case SNDRV_PCM_TRIGGER_START:
+- case SNDRV_PCM_TRIGGER_RESUME:
+- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+- gpiod_set_value(mute_gpio, 1);
+- break;
+- default:
+- return -EINVAL;
+- }
++ gpiod_set_value(mute_gpio, 1);
+ return 0;
+ }
+
+ static struct snd_soc_ops audioinjector_isolated_ops = {
+ .startup = audioinjector_isolated_startup,
+- .trigger = audioinjector_isolated_trigger,
+ };
+
+ SND_SOC_DAILINK_DEFS(audioinjector_isolated,
+@@ -153,6 +132,7 @@ static int audioinjector_isolated_probe(
+ dev_err(&pdev->dev, "mute gpio not found in dt overlay\n");
+ return PTR_ERR(mute_gpio);
+ }
++ gpiod_set_value(mute_gpio, 0);
+ }
+
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0920-vc4-Report-channel-mapping-back-to-userspace.patch b/target/linux/bcm27xx/patches-5.4/950-0920-vc4-Report-channel-mapping-back-to-userspace.patch
new file mode 100644
index 0000000000..8c4e1012bf
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0920-vc4-Report-channel-mapping-back-to-userspace.patch
@@ -0,0 +1,504 @@
+From 058328afcdd3d5c9531cfac8b980d0c0db75856f Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Mon, 20 Apr 2020 18:00:38 +0100
+Subject: [PATCH] vc4: Report channel mapping back to userspace
+
+This follows logic in hdmi-codec.c to use speaker layout
+from ELD to choose a suitable speaker mapping based on
+number of channels requested and signal that in audio
+infoframe and report this back to userspace.
+
+This allows apps like speaker-test and kodi to get the
+output to the right speakers.
+
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 415 +++++++++++++++++++++++++++++++++
+ drivers/gpu/drm/vc4/vc4_hdmi.h | 3 +
+ 2 files changed, 418 insertions(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -48,6 +48,7 @@
+ #include <sound/pcm_drm_eld.h>
+ #include <sound/pcm_params.h>
+ #include <sound/soc.h>
++#include <sound/tlv.h>
+ #include "media/cec.h"
+ #include "vc4_drv.h"
+ #include "vc4_hdmi.h"
+@@ -82,6 +83,311 @@
+ #define CEC_CLOCK_FREQ 40000
+ #define VC4_HSM_CLOCK 163682864
+
++#define HDMI_CODEC_CHMAP_IDX_UNKNOWN -1
++
++/*
++ * CEA speaker placement for HDMI 1.4:
++ *
++ * FL FLC FC FRC FR FRW
++ *
++ * LFE
++ *
++ * RL RLC RC RRC RR
++ *
++ * Speaker placement has to be extended to support HDMI 2.0
++ */
++enum hdmi_codec_cea_spk_placement {
++ FL = BIT(0), /* Front Left */
++ FC = BIT(1), /* Front Center */
++ FR = BIT(2), /* Front Right */
++ FLC = BIT(3), /* Front Left Center */
++ FRC = BIT(4), /* Front Right Center */
++ RL = BIT(5), /* Rear Left */
++ RC = BIT(6), /* Rear Center */
++ RR = BIT(7), /* Rear Right */
++ RLC = BIT(8), /* Rear Left Center */
++ RRC = BIT(9), /* Rear Right Center */
++ LFE = BIT(10), /* Low Frequency Effect */
++};
++
++/*
++ * cea Speaker allocation structure
++ */
++struct hdmi_codec_cea_spk_alloc {
++ const int ca_id;
++ unsigned int n_ch;
++ unsigned long mask;
++};
++
++/* Channel maps stereo HDMI */
++static const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = {
++ { .channels = 2,
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
++ { }
++};
++
++/* Channel maps for multi-channel playbacks, up to 8 n_ch */
++static const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = {
++ { .channels = 2, /* CA_ID 0x00 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
++ { .channels = 4, /* CA_ID 0x01 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_NA } },
++ { .channels = 4, /* CA_ID 0x02 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FC } },
++ { .channels = 4, /* CA_ID 0x03 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_FC } },
++ { .channels = 6, /* CA_ID 0x04 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
++ { .channels = 6, /* CA_ID 0x05 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
++ { .channels = 6, /* CA_ID 0x06 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
++ { .channels = 6, /* CA_ID 0x07 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
++ { .channels = 6, /* CA_ID 0x08 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
++ { .channels = 6, /* CA_ID 0x09 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
++ { .channels = 6, /* CA_ID 0x0A */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
++ { .channels = 6, /* CA_ID 0x0B */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
++ { .channels = 8, /* CA_ID 0x0C */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
++ { .channels = 8, /* CA_ID 0x0D */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
++ { .channels = 8, /* CA_ID 0x0E */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
++ { .channels = 8, /* CA_ID 0x0F */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
++ { .channels = 8, /* CA_ID 0x10 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
++ { .channels = 8, /* CA_ID 0x11 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
++ { .channels = 8, /* CA_ID 0x12 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
++ { .channels = 8, /* CA_ID 0x13 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
++ { .channels = 8, /* CA_ID 0x14 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
++ { .channels = 8, /* CA_ID 0x15 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
++ { .channels = 8, /* CA_ID 0x16 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
++ { .channels = 8, /* CA_ID 0x17 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
++ { .channels = 8, /* CA_ID 0x18 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
++ { .channels = 8, /* CA_ID 0x19 */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
++ { .channels = 8, /* CA_ID 0x1A */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
++ { .channels = 8, /* CA_ID 0x1B */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
++ { .channels = 8, /* CA_ID 0x1C */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
++ { .channels = 8, /* CA_ID 0x1D */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
++ { .channels = 8, /* CA_ID 0x1E */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
++ { .channels = 8, /* CA_ID 0x1F */
++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
++ { }
++};
++
++/*
++ * hdmi_codec_channel_alloc: speaker configuration available for CEA
++ *
++ * This is an ordered list that must match with hdmi_codec_8ch_chmaps struct
++ * The preceding ones have better chances to be selected by
++ * hdmi_codec_get_ch_alloc_table_idx().
++ */
++static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
++ { .ca_id = 0x00, .n_ch = 2,
++ .mask = FL | FR},
++ /* 2.1 */
++ { .ca_id = 0x01, .n_ch = 4,
++ .mask = FL | FR | LFE},
++ /* Dolby Surround */
++ { .ca_id = 0x02, .n_ch = 4,
++ .mask = FL | FR | FC },
++ /* surround51 */
++ { .ca_id = 0x0b, .n_ch = 6,
++ .mask = FL | FR | LFE | FC | RL | RR},
++ /* surround40 */
++ { .ca_id = 0x08, .n_ch = 6,
++ .mask = FL | FR | RL | RR },
++ /* surround41 */
++ { .ca_id = 0x09, .n_ch = 6,
++ .mask = FL | FR | LFE | RL | RR },
++ /* surround50 */
++ { .ca_id = 0x0a, .n_ch = 6,
++ .mask = FL | FR | FC | RL | RR },
++ /* 6.1 */
++ { .ca_id = 0x0f, .n_ch = 8,
++ .mask = FL | FR | LFE | FC | RL | RR | RC },
++ /* surround71 */
++ { .ca_id = 0x13, .n_ch = 8,
++ .mask = FL | FR | LFE | FC | RL | RR | RLC | RRC },
++ /* others */
++ { .ca_id = 0x03, .n_ch = 8,
++ .mask = FL | FR | LFE | FC },
++ { .ca_id = 0x04, .n_ch = 8,
++ .mask = FL | FR | RC},
++ { .ca_id = 0x05, .n_ch = 8,
++ .mask = FL | FR | LFE | RC },
++ { .ca_id = 0x06, .n_ch = 8,
++ .mask = FL | FR | FC | RC },
++ { .ca_id = 0x07, .n_ch = 8,
++ .mask = FL | FR | LFE | FC | RC },
++ { .ca_id = 0x0c, .n_ch = 8,
++ .mask = FL | FR | RC | RL | RR },
++ { .ca_id = 0x0d, .n_ch = 8,
++ .mask = FL | FR | LFE | RL | RR | RC },
++ { .ca_id = 0x0e, .n_ch = 8,
++ .mask = FL | FR | FC | RL | RR | RC },
++ { .ca_id = 0x10, .n_ch = 8,
++ .mask = FL | FR | RL | RR | RLC | RRC },
++ { .ca_id = 0x11, .n_ch = 8,
++ .mask = FL | FR | LFE | RL | RR | RLC | RRC },
++ { .ca_id = 0x12, .n_ch = 8,
++ .mask = FL | FR | FC | RL | RR | RLC | RRC },
++ { .ca_id = 0x14, .n_ch = 8,
++ .mask = FL | FR | FLC | FRC },
++ { .ca_id = 0x15, .n_ch = 8,
++ .mask = FL | FR | LFE | FLC | FRC },
++ { .ca_id = 0x16, .n_ch = 8,
++ .mask = FL | FR | FC | FLC | FRC },
++ { .ca_id = 0x17, .n_ch = 8,
++ .mask = FL | FR | LFE | FC | FLC | FRC },
++ { .ca_id = 0x18, .n_ch = 8,
++ .mask = FL | FR | RC | FLC | FRC },
++ { .ca_id = 0x19, .n_ch = 8,
++ .mask = FL | FR | LFE | RC | FLC | FRC },
++ { .ca_id = 0x1a, .n_ch = 8,
++ .mask = FL | FR | RC | FC | FLC | FRC },
++ { .ca_id = 0x1b, .n_ch = 8,
++ .mask = FL | FR | LFE | RC | FC | FLC | FRC },
++ { .ca_id = 0x1c, .n_ch = 8,
++ .mask = FL | FR | RL | RR | FLC | FRC },
++ { .ca_id = 0x1d, .n_ch = 8,
++ .mask = FL | FR | LFE | RL | RR | FLC | FRC },
++ { .ca_id = 0x1e, .n_ch = 8,
++ .mask = FL | FR | FC | RL | RR | FLC | FRC },
++ { .ca_id = 0x1f, .n_ch = 8,
++ .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC },
++};
++
++static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc)
++{
++ int i;
++ static const unsigned long hdmi_codec_eld_spk_alloc_bits[] = {
++ [0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR,
++ [4] = RC, [5] = FLC | FRC, [6] = RLC | RRC,
++ };
++ unsigned long spk_mask = 0;
++
++ for (i = 0; i < ARRAY_SIZE(hdmi_codec_eld_spk_alloc_bits); i++) {
++ if (spk_alloc & (1 << i))
++ spk_mask |= hdmi_codec_eld_spk_alloc_bits[i];
++ }
++
++ return spk_mask;
++}
++
++static int hdmi_codec_get_ch_alloc_table_idx(struct vc4_hdmi *vc4_hdmi,
++ unsigned char channels)
++{
++ struct drm_connector *connector = &vc4_hdmi->connector;
++ int i;
++ u8 spk_alloc;
++ unsigned long spk_mask;
++ const struct hdmi_codec_cea_spk_alloc *cap = hdmi_codec_channel_alloc;
++
++ spk_alloc = drm_eld_get_spk_alloc(connector->eld);
++ spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
++
++ for (i = 0; i < ARRAY_SIZE(hdmi_codec_channel_alloc); i++, cap++) {
++ /* If spk_alloc == 0, HDMI is unplugged return stereo config*/
++ if (!spk_alloc && cap->ca_id == 0)
++ return i;
++ if (cap->n_ch != channels)
++ continue;
++ if (!(cap->mask == (spk_mask & cap->mask)))
++ continue;
++ return i;
++ }
++
++ return -EINVAL;
++}
++
++static void hdmi_codec_eld_chmap(struct vc4_hdmi *vc4_hdmi)
++{
++ struct drm_connector *connector = &vc4_hdmi->connector;
++ u8 spk_alloc;
++ unsigned long spk_mask;
++
++ spk_alloc = drm_eld_get_spk_alloc(connector->eld);
++ spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
++
++ /* Detect if only stereo supported, else return 8 channels mappings */
++ if ((spk_mask & ~(FL | FR)))
++ vc4_hdmi->audio.chmap = hdmi_codec_8ch_chmaps;
++ else
++ vc4_hdmi->audio.chmap = hdmi_codec_stereo_chmaps;
++}
++
+ static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
+ {
+ struct drm_info_node *node = (struct drm_info_node *)m->private;
+@@ -350,6 +656,9 @@ static void vc4_hdmi_set_audio_infoframe
+ frame.audio.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
+ frame.audio.channels = vc4_hdmi->audio.channels;
+
++ /* Select a channel allocation that matches with ELD and pcm channels */
++ frame.audio.channel_allocation = vc4_hdmi->audio.chmap_idx;
++
+ vc4_hdmi_write_infoframe(encoder, &frame);
+ }
+
+@@ -881,6 +1190,10 @@ static int vc4_hdmi_audio_startup(struct
+ if (ret)
+ return ret;
+
++ /* Select chmap supported */
++ vc4_hdmi->audio.max_channels = 8;
++ hdmi_codec_eld_chmap(vc4_hdmi);
++
+ return 0;
+ }
+
+@@ -967,6 +1280,7 @@ static int vc4_hdmi_audio_prepare(struct
+ u32 channel_map;
+ u32 mai_audio_format;
+ u32 mai_sample_rate;
++ int idx;
+
+ if (substream != vc4_hdmi->audio.substream)
+ return -EINVAL;
+@@ -1027,6 +1341,14 @@ static int vc4_hdmi_audio_prepare(struct
+ HDMI_WRITE(HDMI_AUDIO_PACKET_CONFIG, audio_packet_config);
+ vc4_hdmi_set_n_cts(vc4_hdmi);
+
++ idx = hdmi_codec_get_ch_alloc_table_idx(vc4_hdmi, vc4_hdmi->audio.channels);
++ if (idx < 0) {
++ DRM_ERROR("Not able to map channels to speakers (%d)\n", idx);
++ vc4_hdmi->audio.chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
++ } else {
++ vc4_hdmi->audio.chmap_idx = hdmi_codec_channel_alloc[idx].ca_id;
++ }
++
+ return 0;
+ }
+
+@@ -1145,6 +1467,89 @@ static int vc4_spdif_mask_get(struct snd
+ return 0;
+ }
+
++/*
++ * ALSA API channel-map control callbacks
++ */
++static int vc4_chmap_ctl_info(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_info *uinfo)
++{
++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
++ struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component);
++
++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
++ uinfo->count = vc4_hdmi->audio.max_channels;
++ uinfo->value.integer.min = 0;
++ uinfo->value.integer.max = SNDRV_CHMAP_LAST;
++
++ return 0;
++}
++
++static int vc4_chmap_ctl_get(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
++ struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component);
++ unsigned const char *map;
++ unsigned int i;
++
++ if (!vc4_hdmi->audio.chmap)
++ return -EINVAL;
++
++ map = vc4_hdmi->audio.chmap[vc4_hdmi->audio.chmap_idx].map;
++
++ for (i = 0; i < vc4_hdmi->audio.max_channels; i++) {
++ if (vc4_hdmi->audio.chmap_idx == HDMI_CODEC_CHMAP_IDX_UNKNOWN)
++ ucontrol->value.integer.value[i] = 0;
++ else
++ ucontrol->value.integer.value[i] = map[i];
++ }
++ return 0;
++}
++
++static int vc4_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
++ unsigned int size, unsigned int __user *tlv)
++{
++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
++ struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component);
++ const struct snd_pcm_chmap_elem *map;
++ unsigned int __user *dst;
++ int c, count = 0;
++
++ if (!vc4_hdmi->audio.chmap)
++ return -EINVAL;
++ if (size < 8)
++ return -ENOMEM;
++ if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv))
++ return -EFAULT;
++ size -= 8;
++ dst = tlv + 2;
++ for (map = vc4_hdmi->audio.chmap; map->channels; map++) {
++ int chs_bytes = map->channels * 4;
++ //if (!valid_chmap_channels(info, map->channels))
++ // continue;
++ if (size < 8)
++ return -ENOMEM;
++ if (put_user(SNDRV_CTL_TLVT_CHMAP_FIXED, dst) ||
++ put_user(chs_bytes, dst + 1))
++ return -EFAULT;
++ dst += 2;
++ size -= 8;
++ count += 8;
++ if (size < chs_bytes)
++ return -ENOMEM;
++ size -= chs_bytes;
++ count += chs_bytes;
++ for (c = 0; c < map->channels; c++) {
++ if (put_user(map->map[c], dst))
++ return -EFAULT;
++ dst++;
++ }
++ }
++ if (put_user(count, tlv + 1))
++ return -EFAULT;
++ return 0;
++}
++
+ static const struct snd_kcontrol_new vc4_hdmi_audio_controls[] = {
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+@@ -1167,6 +1572,16 @@ static const struct snd_kcontrol_new vc4
+ .info = vc4_spdif_info,
+ .get = vc4_spdif_mask_get,
+ },
++ {
++ .access = SNDRV_CTL_ELEM_ACCESS_READ |
++ SNDRV_CTL_ELEM_ACCESS_TLV_READ |
++ SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
++ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
++ .name = "Playback Channel Map",
++ .info = vc4_chmap_ctl_info,
++ .get = vc4_chmap_ctl_get,
++ .tlv.c = vc4_chmap_ctl_tlv,
++ },
+ };
+
+ static const struct snd_soc_dapm_widget vc4_hdmi_audio_widgets[] = {
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
+@@ -117,6 +117,9 @@ struct vc4_hdmi_audio {
+ bool streaming;
+
+ unsigned char iec_status[4];
++ const struct snd_pcm_chmap_elem *chmap;
++ unsigned int chmap_idx;
++ unsigned int max_channels;
+ };
+
+ /* General HDMI hardware state. */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0921-SQUASH-leds-actpwr-delete-unused-variable.patch b/target/linux/bcm27xx/patches-5.4/950-0921-SQUASH-leds-actpwr-delete-unused-variable.patch
new file mode 100644
index 0000000000..1166f6a2ed
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0921-SQUASH-leds-actpwr-delete-unused-variable.patch
@@ -0,0 +1,20 @@
+From 867a447dbe461b6cfdfae2fcd71c449dced9cd8a Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 20 Jul 2020 09:35:46 +0100
+Subject: [PATCH] SQUASH: leds: actpwr - delete unused variable
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/leds/trigger/ledtrig-actpwr.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/leds/trigger/ledtrig-actpwr.c
++++ b/drivers/leds/trigger/ledtrig-actpwr.c
+@@ -94,7 +94,6 @@ static void actpwr_trig_cycle(struct tim
+ {
+ struct actpwr_trig_data *trig = &actpwr_data;
+ struct actpwr_vled *active;
+- enum led_brightness value;
+
+ active = &trig->virt_leds[trig->next_active];
+ trig->active = active;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0922-staging-vchiq_arm-children-inherit-DMA-config.patch b/target/linux/bcm27xx/patches-5.4/950-0922-staging-vchiq_arm-children-inherit-DMA-config.patch
new file mode 100644
index 0000000000..9dbc80c4ac
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0922-staging-vchiq_arm-children-inherit-DMA-config.patch
@@ -0,0 +1,36 @@
+From 9f0d49445428265cd6cf0862d94bc7f3dd1304d0 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 21 Jul 2020 17:34:09 +0100
+Subject: [PATCH] staging: vchiq_arm: children inherit DMA config
+
+Although it is no longer necessary for vchiq's children to have a
+different DMA configuration to the parent, they do still need to
+explicitly to have their DMA configuration set - to be that of the
+parent.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+@@ -3205,8 +3205,18 @@ vchiq_register_child(struct platform_dev
+
+ child->dev.of_node = np;
+
++ /*
++ * We want the dma-ranges etc to be copied from the parent VCHIQ device
++ * to be passed on to the children without a node of their own.
++ */
++ if (!np)
++ np = pdev->dev.of_node;
++
+ of_dma_configure(&child->dev, np, true);
+
++ if (np != pdev->dev.of_node)
++ of_node_put(np);
++
+ return child;
+ }
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0923-ARM-dts-2711-DMA-can-address-36-bits.patch b/target/linux/bcm27xx/patches-5.4/950-0923-ARM-dts-2711-DMA-can-address-36-bits.patch
new file mode 100644
index 0000000000..a77737986e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0923-ARM-dts-2711-DMA-can-address-36-bits.patch
@@ -0,0 +1,25 @@
+From df3f3eba7e6f19694369ea52360c0d5d18d310c3 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 22 Jul 2020 17:45:24 +0100
+Subject: [PATCH] ARM: dts: 2711 DMA can address 36 bits
+
+Kernels prior to 5.7 only see the first entry in dma-ranges, so make
+it cover the full addressable range.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2711-rpi.dtsi | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi
+@@ -193,8 +193,7 @@
+ <0x0 0x40000000 0x0 0xff800000 0x0 0x00800000>,
+ <0x6 0x00000000 0x6 0x00000000 0x0 0x40000000>,
+ <0x0 0x00000000 0x0 0x00000000 0x0 0xfc000000>;
+- dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0xfc000000>,
+- <0x1 0x00000000 0x1 0x00000000 0x1 0x00000000>;
++ dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x4 0x00000000>;
+
+ dma40: dma@7e007b00 {
+ compatible = "brcm,bcm2711-dma";
diff --git a/target/linux/bcm27xx/patches-5.4/950-0924-bcm2835-dma-Advertise-the-full-DMA-range.patch b/target/linux/bcm27xx/patches-5.4/950-0924-bcm2835-dma-Advertise-the-full-DMA-range.patch
new file mode 100644
index 0000000000..33c740ffef
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0924-bcm2835-dma-Advertise-the-full-DMA-range.patch
@@ -0,0 +1,77 @@
+From bf7baee1935c4d485083c3b3c439631ae4ac3c0f Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 22 Jul 2020 17:59:31 +0100
+Subject: [PATCH] bcm2835-dma: Advertise the full DMA range
+
+Unless the DMA mask is set wider than 32 bits, DMA mapping will use a
+bounce buffer.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/dma/bcm2835-dma.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+--- a/drivers/dma/bcm2835-dma.c
++++ b/drivers/dma/bcm2835-dma.c
+@@ -41,6 +41,7 @@
+ #define BCM2711_DMA_MEMCPY_CHAN 14
+
+ struct bcm2835_dma_cfg_data {
++ u64 dma_mask;
+ u32 chan_40bit_mask;
+ };
+
+@@ -302,10 +303,12 @@ DEFINE_SPINLOCK(memcpy_lock);
+
+ static const struct bcm2835_dma_cfg_data bcm2835_dma_cfg = {
+ .chan_40bit_mask = 0,
++ .dma_mask = DMA_BIT_MASK(32),
+ };
+
+ static const struct bcm2835_dma_cfg_data bcm2711_dma_cfg = {
+ .chan_40bit_mask = BIT(11) | BIT(12) | BIT(13) | BIT(14),
++ .dma_mask = DMA_BIT_MASK(36),
+ };
+
+ static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c)
+@@ -1185,6 +1188,8 @@ static struct dma_chan *bcm2835_dma_xlat
+
+ static int bcm2835_dma_probe(struct platform_device *pdev)
+ {
++ const struct bcm2835_dma_cfg_data *cfg_data;
++ const struct of_device_id *of_id;
+ struct bcm2835_dmadev *od;
+ struct resource *res;
+ void __iomem *base;
+@@ -1194,13 +1199,20 @@ static int bcm2835_dma_probe(struct plat
+ int irq_flags;
+ uint32_t chans_available;
+ char chan_name[BCM2835_DMA_CHAN_NAME_SIZE];
+- const struct of_device_id *of_id;
+ int chan_count, chan_start, chan_end;
+
++ of_id = of_match_node(bcm2835_dma_of_match, pdev->dev.of_node);
++ if (!of_id) {
++ dev_err(&pdev->dev, "Failed to match compatible string\n");
++ return -EINVAL;
++ }
++
++ cfg_data = of_id->data;
++
+ if (!pdev->dev.dma_mask)
+ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+
+- rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
++ rc = dma_set_mask_and_coherent(&pdev->dev, cfg_data->dma_mask);
+ if (rc) {
+ dev_err(&pdev->dev, "Unable to set DMA mask\n");
+ return rc;
+@@ -1266,7 +1278,7 @@ static int bcm2835_dma_probe(struct plat
+ return -EINVAL;
+ }
+
+- od->cfg_data = of_id->data;
++ od->cfg_data = cfg_data;
+
+ /* Request DMA channel mask from device tree */
+ if (of_property_read_u32(pdev->dev.of_node,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0925-ARM-dts-Add-UART-skip-init-properties-for-U-boot.patch b/target/linux/bcm27xx/patches-5.4/950-0925-ARM-dts-Add-UART-skip-init-properties-for-U-boot.patch
new file mode 100644
index 0000000000..be6c9dd250
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0925-ARM-dts-Add-UART-skip-init-properties-for-U-boot.patch
@@ -0,0 +1,35 @@
+From 197b4fbd218a0a12573cdfcb011eeb3f00765d96 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 17 Jul 2020 11:20:07 +0100
+Subject: [PATCH] ARM: dts: Add UART skip-init properties for U-boot
+
+U-boot can get stuck trying to initialise UARTs that aren't mapped
+to the pin header. There is no reason for U-boot not to rely on the
+initialisation by the firmware, so tag both UARTs with the u-boot
+magic boolean property "skip-init".
+
+See: https://github.com/raspberrypi/linux/pull/3731
+ https://lists.denx.de/pipermail/u-boot/2017-April/285606.html
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm270x-rpi.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm270x-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm270x-rpi.dtsi
+@@ -102,6 +102,14 @@
+ };
+ };
+
++&uart0 {
++ skip-init;
++};
++
++&uart1 {
++ skip-init;
++};
++
+ &txp {
+ status = "disabled";
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0926-drm-vc4-Remove-UIF-from-the-list-of-modifiers-return.patch b/target/linux/bcm27xx/patches-5.4/950-0926-drm-vc4-Remove-UIF-from-the-list-of-modifiers-return.patch
new file mode 100644
index 0000000000..7ae22a72fc
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0926-drm-vc4-Remove-UIF-from-the-list-of-modifiers-return.patch
@@ -0,0 +1,29 @@
+From 132454781a30f57ccb393443209def76dc0b572a Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 28 Jul 2020 13:01:42 +0100
+Subject: [PATCH] drm/vc4: Remove UIF from the list of modifiers
+ returned by format_mod_supported
+
+FKMS was listing UIF in the supported modifiers from format_mod_supported
+when actually the pipeline doesn't support it. X was then choosing to
+use it, and that then failed to render.
+
+Remove references to UIF.
+
+https://github.com/raspberrypi/linux/issues/3665
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -718,7 +718,6 @@ static bool vc4_fkms_format_mod_supporte
+ switch (modifier) {
+ case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
+ case DRM_FORMAT_MOD_LINEAR:
+- case DRM_FORMAT_MOD_BROADCOM_UIF:
+ return true;
+ default:
+ return false;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0927-ARM-proc-v7-Force-misalignment-of-early-stmia.patch b/target/linux/bcm27xx/patches-5.4/950-0927-ARM-proc-v7-Force-misalignment-of-early-stmia.patch
new file mode 100644
index 0000000000..158ff69bff
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0927-ARM-proc-v7-Force-misalignment-of-early-stmia.patch
@@ -0,0 +1,60 @@
+From 965cce6b1c6acc25d7cfd29ccf95c8ebbf1d7f57 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 29 Jul 2020 13:47:55 +0100
+Subject: [PATCH] ARM: proc-v7: Force misalignment of early stmia
+
+In an attempt to prevent the problem of CPUn not starting, explicitly
+misalign the scratch space used to save registers acros the cache
+invalidation.
+
+Notes:
+At this stage in the boot process the core is running with its cache
+disabled. Before enabling the cache its contents must be explicitly
+invalidated, a process that requires quite a few registers that the
+caller must preserve. Evidence suggests that something is writing a
+block of zeroes over that space at a time when all other cores should
+be idle, possibly some kind of write-combiner, and the misalignment is
+designed to disrupt any write-coalescing.
+
+In truth, I don't understand why this patch works, and when the failure
+is so random it is hard to be certain that this isn't just rolling the
+dice again. One interesting test would be to change the "addeq r12, #4"s
+to "addeq r12, #0"s determine see if the offset itself is significant or
+just the additional code.
+
+See: https://github.com/Hexxeh/rpi-firmware/issues/232
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/mm/proc-v7.S | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/mm/proc-v7.S
++++ b/arch/arm/mm/proc-v7.S
+@@ -287,6 +287,8 @@ __v7_ca17mp_setup:
+ mov r10, #0
+ 1: adr r0, __v7_setup_stack_ptr
+ ldr r12, [r0]
++ tst r12, #0x1f
++ addeq r12, r12, #4
+ add r12, r12, r0 @ the local stack
+ stmia r12, {r1-r6, lr} @ v7_invalidate_l1 touches r0-r6
+ bl v7_invalidate_l1
+@@ -474,6 +476,8 @@ __v7_setup:
+ adr r0, __v7_setup_stack_ptr
+ ldr r12, [r0]
+ add r12, r12, r0 @ the local stack
++ tst r12, #0x1f
++ addeq r12, r12, #4
+ stmia r12, {r1-r6, lr} @ v7_invalidate_l1 touches r0-r6
+ bl v7_invalidate_l1
+ ldmia r12, {r1-r6, lr}
+@@ -557,7 +561,7 @@ ENDPROC(__v7_setup)
+ .bss
+ .align 2
+ __v7_setup_stack:
+- .space 4 * 7 @ 7 registers
++ .space 4 * 8 @ 7 registers + 1 spare
+
+ __INITDATA
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0928-overlays-Fix-sc16is75x-overlays-w.r.t.-serdev.patch b/target/linux/bcm27xx/patches-5.4/950-0928-overlays-Fix-sc16is75x-overlays-w.r.t.-serdev.patch
new file mode 100644
index 0000000000..ed9f1e1492
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0928-overlays-Fix-sc16is75x-overlays-w.r.t.-serdev.patch
@@ -0,0 +1,182 @@
+From a934bc7776953d7ce8e27c2d8720de58d5ceeeef Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 30 Jul 2020 15:13:09 +0100
+Subject: [PATCH] overlays: Fix sc16is75x overlays w.r.t. serdev
+
+Enabling serdev support in rpi-5.4.y had the unintended consequence of
+making any UART device node with a subnode look like a "serdev" node,
+which prevents it from having the usual /dev/ttyXXX character device.
+Solve the problem by moving the subnode (a static clock declaration)
+into the root node.
+
+At the same time, regularise (and sometimes correct) the overlays.
+
+See: https://github.com/raspberrypi/linux/issues/3765
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ .../dts/overlays/sc16is750-i2c-overlay.dts | 23 +++++++++-------
+ .../dts/overlays/sc16is752-i2c-overlay.dts | 27 ++++++++++---------
+ .../dts/overlays/sc16is752-spi0-overlay.dts | 21 +++++++++------
+ .../dts/overlays/sc16is752-spi1-overlay.dts | 6 ++---
+ 4 files changed, 45 insertions(+), 32 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts
++++ b/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts
+@@ -13,26 +13,31 @@
+
+ sc16is750: sc16is750@48 {
+ compatible = "nxp,sc16is750";
+- reg = <0x48>; /* address */
++ reg = <0x48>; /* i2c address */
+ clocks = <&sc16is750_clk>;
+ interrupt-parent = <&gpio>;
+ interrupts = <24 2>; /* IRQ_TYPE_EDGE_FALLING */
++ gpio-controller;
+ #gpio-cells = <2>;
+-
+- sc16is750_clk: sc16is750_clk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-frequency = <14745600>;
+- };
++ i2c-max-frequency = <400000>;
+ };
+ };
+ };
+
++ fragment@1 {
++ target-path = "/";
++ __overlay__ {
++ sc16is750_clk: sc16is750_i2c_clk@48 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <14745600>;
++ };
++ };
++ };
+
+ __overrides__ {
+ int_pin = <&sc16is750>,"interrupts:0";
+- addr = <&sc16is750>,"reg:0",<&sc16is750_clk>,"name";
++ addr = <&sc16is750>,"reg:0", <&sc16is750_clk>,"name";
+ xtal = <&sc16is750_clk>,"clock-frequency:0";
+ };
+-
+ };
+--- a/arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts
++++ b/arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts
+@@ -5,29 +5,32 @@
+ compatible = "brcm,bcm2835";
+
+ fragment@0 {
+- target = <&i2c1>;
+-
+- frag1: __overlay__ {
++ target = <&i2c_arm>;
++ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ sc16is752: sc16is752@48 {
+ compatible = "nxp,sc16is752";
+- reg = <0x48>; // i2c address
++ reg = <0x48>; /* i2c address */
+ clocks = <&sc16is752_clk>;
+ interrupt-parent = <&gpio>;
+- interrupts = <24 0x2>; /* IRQ_TYPE_EDGE_FALLING */
++ interrupts = <24 2>; /* IRQ_TYPE_EDGE_FALLING */
+ gpio-controller;
+- #gpio-cells = <0>;
++ #gpio-cells = <2>;
+ i2c-max-frequency = <400000>;
+- status = "okay";
++ };
++ };
++ };
+
+- sc16is752_clk: sc16is752_clk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-frequency = <14745600>;
+- };
++ fragment@1 {
++ target-path = "/";
++ __overlay__ {
++ sc16is752_clk: sc16is752_i2c_clk@48 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <14745600>;
+ };
+ };
+ };
+--- a/arch/arm/boot/dts/overlays/sc16is752-spi0-overlay.dts
++++ b/arch/arm/boot/dts/overlays/sc16is752-spi0-overlay.dts
+@@ -17,15 +17,9 @@
+ clocks = <&sc16is752_clk>;
+ interrupt-parent = <&gpio>;
+ interrupts = <24 2>; /* IRQ_TYPE_EDGE_FALLING */
+- #gpio-controller;
++ gpio-controller;
+ #gpio-cells = <2>;
+ spi-max-frequency = <4000000>;
+-
+- sc16is752_clk: sc16is752_clk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-frequency = <14745600>;
+- };
+ };
+ };
+ };
+@@ -37,8 +31,19 @@
+ };
+ };
+
++ fragment@2 {
++ target-path = "/";
++ __overlay__ {
++ sc16is752_clk: sc16is752_spi0_0_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <14745600>;
++ };
++ };
++ };
++
+ __overrides__ {
+ int_pin = <&sc16is752>,"interrupts:0";
+- xtal = <&sc16is752_clk>, "clock-frequency:0";
++ xtal = <&sc16is752_clk>,"clock-frequency:0";
+ };
+ };
+--- a/arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts
++++ b/arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts
+@@ -21,7 +21,7 @@
+
+ fragment@1 {
+ target = <&spi1>;
+- frag1: __overlay__ {
++ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+@@ -35,7 +35,7 @@
+ clocks = <&sc16is752_clk>;
+ interrupt-parent = <&gpio>;
+ interrupts = <24 2>; /* IRQ_TYPE_EDGE_FALLING */
+- #gpio-controller;
++ gpio-controller;
+ #gpio-cells = <2>;
+ spi-max-frequency = <4000000>;
+ };
+@@ -52,7 +52,7 @@
+ fragment@3 {
+ target-path = "/";
+ __overlay__ {
+- sc16is752_clk: sc16is752_spi1_clk {
++ sc16is752_clk: sc16is752_spi1_0_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <14745600>;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0929-overlays-Delete-spi0-hw-cs.patch b/target/linux/bcm27xx/patches-5.4/950-0929-overlays-Delete-spi0-hw-cs.patch
new file mode 100644
index 0000000000..044a3ad3f1
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0929-overlays-Delete-spi0-hw-cs.patch
@@ -0,0 +1,87 @@
+From 9fcbc40311f8de3f7a0a27155f310ff19e150d76 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 30 Jul 2020 18:06:24 +0100
+Subject: [PATCH] overlays: Delete spi0-hw-cs
+
+The spi0-hw-cs overlay is unnecessary (and actually harmful) with the
+current kernels. Delete it, leaving a note in the README and a
+deprecation message from the firmware:
+
+ dterror: overlay 'spi0-hw-cs' is deprecated: no longer necessary
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 -
+ arch/arm/boot/dts/overlays/README | 6 ++---
+ arch/arm/boot/dts/overlays/overlay_map.dts | 4 +++
+ .../boot/dts/overlays/spi0-hw-cs-overlay.dts | 26 -------------------
+ 4 files changed, 7 insertions(+), 30 deletions(-)
+ delete mode 100644 arch/arm/boot/dts/overlays/spi0-hw-cs-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -159,7 +159,6 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ spi-gpio40-45.dtbo \
+ spi-rtc.dtbo \
+ spi0-cs.dtbo \
+- spi0-hw-cs.dtbo \
+ spi1-1cs.dtbo \
+ spi1-2cs.dtbo \
+ spi1-3cs.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -2346,9 +2346,9 @@ Params: cs0_pin GPIO pin
+
+
+ Name: spi0-hw-cs
+-Info: Re-enables hardware CS/CE (chip selects) for SPI0
+-Load: dtoverlay=spi0-hw-cs
+-Params: <None>
++Info: This overlay has been deprecated and removed because it is no longer
++ necessary and has been seen to prevent spi0 from working.
++Load: <Deprecated>
+
+
+ Name: spi1-1cs
+--- a/arch/arm/boot/dts/overlays/overlay_map.dts
++++ b/arch/arm/boot/dts/overlays/overlay_map.dts
+@@ -61,6 +61,10 @@
+ deprecated = "use sdio,bus_width=1,gpios_22_25";
+ };
+
++ spi0-hw-cs {
++ deprecated = "no longer necessary";
++ };
++
+ spi3-1cs {
+ bcm2711;
+ };
+--- a/arch/arm/boot/dts/overlays/spi0-hw-cs-overlay.dts
++++ /dev/null
+@@ -1,26 +0,0 @@
+-/*
+- * Device tree overlay to re-enable hardware CS for SPI0
+- */
+-
+-/dts-v1/;
+-/plugin/;
+-
+-/ {
+- compatible = "brcm,bcm2835";
+-
+- 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 --git a/target/linux/bcm27xx/patches-5.4/950-0930-backlight-gpio-Explicitly-set-the-direction-of-the-G.patch b/target/linux/bcm27xx/patches-5.4/950-0930-backlight-gpio-Explicitly-set-the-direction-of-the-G.patch
new file mode 100644
index 0000000000..d016cdaa43
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0930-backlight-gpio-Explicitly-set-the-direction-of-the-G.patch
@@ -0,0 +1,88 @@
+From aa455fdc2495cb05b65cc03cc472de43df632c5c Mon Sep 17 00:00:00 2001
+From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+Date: Tue, 22 Oct 2019 10:36:24 +0200
+Subject: [PATCH] backlight: gpio: Explicitly set the direction of
+ the GPIO
+
+commit 706dc68102bc7421a9e6573d149ab6d769d71cc7 upstream.
+
+The GPIO backlight driver currently requests the line 'as is', without
+acively setting its direction. This can lead to problems: if the line
+is in input mode by default, we won't be able to drive it later when
+updating the status and also reading its initial value doesn't make
+sense for backlight setting.
+
+Request the line 'as is' initially, so that we can read its value
+without affecting it but then change the direction to output explicitly
+when setting the initial brightness.
+
+Also: check the current direction and only read the value if it's output.
+
+Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+---
+ drivers/video/backlight/gpio_backlight.c | 23 ++++++++++++++++++-----
+ 1 file changed, 18 insertions(+), 5 deletions(-)
+
+--- a/drivers/video/backlight/gpio_backlight.c
++++ b/drivers/video/backlight/gpio_backlight.c
+@@ -26,9 +26,8 @@ struct gpio_backlight {
+ int def_value;
+ };
+
+-static int gpio_backlight_update_status(struct backlight_device *bl)
++static int gpio_backlight_get_next_brightness(struct backlight_device *bl)
+ {
+- struct gpio_backlight *gbl = bl_get_data(bl);
+ int brightness = bl->props.brightness;
+
+ if (bl->props.power != FB_BLANK_UNBLANK ||
+@@ -36,6 +35,14 @@ static int gpio_backlight_update_status(
+ bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
+ brightness = 0;
+
++ return brightness;
++}
++
++static int gpio_backlight_update_status(struct backlight_device *bl)
++{
++ struct gpio_backlight *gbl = bl_get_data(bl);
++ int brightness = gpio_backlight_get_next_brightness(bl);
++
+ gpiod_set_value_cansleep(gbl->gpiod, brightness);
+
+ return 0;
+@@ -86,7 +93,8 @@ static int gpio_backlight_initial_power_
+ return gbl->def_value ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
+
+ /* if the enable GPIO is disabled, do not enable the backlight */
+- if (gpiod_get_value_cansleep(gbl->gpiod) == 0)
++ if (gpiod_get_direction(gbl->gpiod) == 0 &&
++ gpiod_get_value_cansleep(gbl->gpiod) == 0)
+ return FB_BLANK_POWERDOWN;
+
+ return FB_BLANK_UNBLANK;
+@@ -100,7 +108,7 @@ static int gpio_backlight_probe(struct p
+ struct backlight_properties props;
+ struct backlight_device *bl;
+ struct gpio_backlight *gbl;
+- int ret;
++ int ret, init_brightness;
+
+ gbl = devm_kzalloc(&pdev->dev, sizeof(*gbl), GFP_KERNEL);
+ if (gbl == NULL)
+@@ -153,7 +161,12 @@ static int gpio_backlight_probe(struct p
+ bl->props.power = gpio_backlight_initial_power_state(gbl);
+ bl->props.brightness = 1;
+
+- backlight_update_status(bl);
++ init_brightness = gpio_backlight_get_next_brightness(bl);
++ ret = gpiod_direction_output(gbl->gpiod, init_brightness);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to set initial brightness\n");
++ return ret;
++ }
+
+ platform_set_drvdata(pdev, bl);
+ return 0;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0931-overlays-Add-maxtherm-overlay-for-MAX6675-31855.patch b/target/linux/bcm27xx/patches-5.4/950-0931-overlays-Add-maxtherm-overlay-for-MAX6675-31855.patch
new file mode 100644
index 0000000000..882cb8df5e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0931-overlays-Add-maxtherm-overlay-for-MAX6675-31855.patch
@@ -0,0 +1,238 @@
+From 56e726d1631c9551530b8db4127352c64c3cb94d Mon Sep 17 00:00:00 2001
+From: Dougie Lawson <dl1ims@gmail.com>
+Date: Mon, 27 Jul 2020 23:52:40 +0100
+Subject: [PATCH] overlays: Add maxtherm overlay for MAX6675/31855
+
+Add an overlay - maxtherm - to support the MAX6675 and MAX31855 family
+of thermocouples.
+
+Developed from an original set of overlays by Dougie Lawson.
+
+See: https://github.com/raspberrypi/linux/pull/3763
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 30 ++++
+ .../boot/dts/overlays/maxtherm-overlay.dts | 166 ++++++++++++++++++
+ 3 files changed, 197 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/maxtherm-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -98,6 +98,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ justboom-digi.dtbo \
+ ltc294x.dtbo \
+ max98357a.dtbo \
++ maxtherm.dtbo \
+ mbed-dac.dtbo \
+ mcp23017.dtbo \
+ mcp23s17.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1622,6 +1622,36 @@ Params: no-sdmode Driver d
+ of the DAC (default GPIO4 if parameter omitted).
+
+
++Name: maxtherm
++Info: Configure a MAX6675 or MAX31855 thermocouple as an IIO device.
++
++ 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.
++ The overlay expects to disable the relevant spidev node, so also using
++ e.g. cs0_spidev=off is unnecessary.
++
++ Note: with the 5.7 kernel (and later) there will also be
++ overlays for MAX31855E, MAX31855J, MAX31855K,
++ MAX31885N, MAX31855R, MAX31855S and MAX31855T.
++
++ Example:
++ MAX31855 on /dev/spidev0.0
++ dtoverlay=maxtherm,spi0-0,max31855
++
++Load: dtoverlay=maxtherm,<param>=<val>
++Params: spi<n>-<m> Configure device at spi<n>, cs<m>
++ (boolean, required)
++ max6675 Enable support for the MAX6675 (default)
++ max31855 Enable support for the MAX31855
++ max31855e Enable support for the MAX31855E
++ max31855j Enable support for the MAX31855J
++ max31855k Enable support for the MAX31855K
++ max31855n Enable support for the MAX31855N
++ max31855r Enable support for the MAX31855R
++ max31855s Enable support for the MAX31855S
++ max31855t Enable support for the MAX31855T
++
++
+ Name: mbed-dac
+ Info: Configures the mbed AudioCODEC (TLV320AIC23B)
+ Load: dtoverlay=mbed-dac
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/maxtherm-overlay.dts
+@@ -0,0 +1,166 @@
++/*
++ * Universal device tree overlay for SPI devices
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2835";
++
++ 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";
++ };
++ };
++
++ maxfrag: fragment@8 {
++ target = <&spi0>;
++ __overlay__ {
++ status = "okay";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ max: maxtherm@0 {
++ compatible = "maxim,max6675";
++ reg = <0>;
++ spi-max-frequency = <500000>;
++ };
++ };
++ };
++
++ fragment@9 {
++ target = <&max>;
++ __dormant__ {
++ compatible = "maxim,max31855e", "maxim,max31855";
++ };
++ };
++
++ fragment@10 {
++ target = <&max>;
++ __dormant__ {
++ compatible = "maxim,max31855j", "maxim,max31855";
++ };
++ };
++
++ fragment@11 {
++ target = <&max>;
++ __dormant__ {
++ compatible = "maxim,max31855k", "maxim,max31855";
++ };
++ };
++
++ fragment@12 {
++ target = <&max>;
++ __dormant__ {
++ compatible = "maxim,max31855n", "maxim,max31855";
++ };
++ };
++
++ fragment@13 {
++ target = <&max>;
++ __dormant__ {
++ compatible = "maxim,max31855r", "maxim,max31855";
++ };
++ };
++
++ fragment@14 {
++ target = <&max>;
++ __dormant__ {
++ compatible = "maxim,max31855s", "maxim,max31855";
++ };
++ };
++
++ fragment@15 {
++ target = <&max>;
++ __dormant__ {
++ compatible = "maxim,max31855t", "maxim,max31855";
++ };
++ };
++
++ __overrides__ {
++ spi0-0 = <0>, "+0",
++ <&maxfrag>,"target:0=",<&spi0>,
++ <&max>,"reg:0=0";
++ spi0-1 = <0>, "+1",
++ <&maxfrag>,"target:0=",<&spi0>,
++ <&max>,"reg:0=1";
++ spi1-0 = <0>, "+2",
++ <&maxfrag>,"target:0=",<&spi1>,
++ <&max>,"reg:0=0";
++ spi1-1 = <0>, "+3",
++ <&maxfrag>,"target:0=",<&spi1>,
++ <&max>,"reg:0=1";
++ spi1-2 = <0>, "+4",
++ <&maxfrag>,"target:0=",<&spi1>,
++ <&max>,"reg:0=2";
++ spi2-0 = <0>, "+5",
++ <&maxfrag>,"target:0=",<&spi2>,
++ <&max>,"reg:0=0";
++ spi2-1 = <0>, "+6",
++ <&maxfrag>,"target:0=",<&spi2>,
++ <&max>,"reg:0=1";
++ spi2-2 = <0>, "+7",
++ <&maxfrag>,"target:0=",<&spi2>,
++ <&max>,"reg:0=2";
++ max6675 = <&max>,"compatible=maxim,max6675";
++ max31855 = <&max>,"compatible=maxim,max31855";
++ max31855e = <0>,"+9";
++ max31855j = <0>,"+10";
++ max31855k = <0>,"+11";
++ max31855n = <0>,"+12";
++ max31855r = <0>,"+13";
++ max31855s = <0>,"+14";
++ max31855t = <0>,"+15";
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-0932-dtoverlays-Add-the-iio_hwmon-driver-to-correct-ADC-i.patch b/target/linux/bcm27xx/patches-5.4/950-0932-dtoverlays-Add-the-iio_hwmon-driver-to-correct-ADC-i.patch
new file mode 100644
index 0000000000..1005396340
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0932-dtoverlays-Add-the-iio_hwmon-driver-to-correct-ADC-i.patch
@@ -0,0 +1,40 @@
+From 8bfdbba339bd363633e2232777fd749000011a41 Mon Sep 17 00:00:00 2001
+From: Annaliese McDermond <nh6z@nh6z.net>
+Date: Sun, 2 Aug 2020 18:25:07 +0000
+Subject: [PATCH] dtoverlays: Add the iio_hwmon driver to correct ADC
+ issues
+
+The Linux kernel maintainers removed the hwmon driver for the
+ads1015 used on this board. They deprecated it in favor of using
+the IIO version of the driver with the iio_hwmon bridge. This
+patch updates the DRAWS dtoverlay to support that usage.
+
+Signed-off-by: Annaliese McDermond <nh6z@nh6z.net>
+---
+ arch/arm/boot/dts/overlays/draws-overlay.dts | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/draws-overlay.dts
++++ b/arch/arm/boot/dts/overlays/draws-overlay.dts
+@@ -45,6 +45,13 @@
+ gpios = <&gpio 7 0>;
+ status = "okay";
+ };
++
++ iio-hwmon {
++ compatible = "iio-hwmon";
++ status = "okay";
++ io-channels = <&tla2024 4>, <&tla2024 5>, <&tla2024 6>,
++ <&tla2024 7>;
++ };
+ };
+ };
+
+@@ -91,6 +98,7 @@
+ reg = <0x48>;
+ #address-cells = <1>;
+ #size-cells = <0>;
++ #io-channel-cells = <1>;
+
+ adc_ch4: channel@4 {
+ reg = <4>;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0933-dts-bcm2711-Disable-DVP-by-default.patch b/target/linux/bcm27xx/patches-5.4/950-0933-dts-bcm2711-Disable-DVP-by-default.patch
new file mode 100644
index 0000000000..9e4612e871
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0933-dts-bcm2711-Disable-DVP-by-default.patch
@@ -0,0 +1,44 @@
+From c74f523a5af1d9d3a6f9aee05585e52a78a79f53 Mon Sep 17 00:00:00 2001
+From: Tim Gover <tim.gover@raspberrypi.com>
+Date: Fri, 7 Aug 2020 13:55:18 +0100
+Subject: [PATCH] dts: bcm2711: Disable DVP by default
+
+The HDMI DVP should be disabled by default as is the case for other
+display related drivers. This changes resolves an issue when using
+the legacy firmware display driver where the DVP caused the 108 MHz
+clock in HDMI TX to be gated off when Linux started. This effectively
+stopped the firmware from being able to change the HDMI analog PHY
+registers.
+
+Add a fragment to re-enable this in vc4-kms-v3d-pi4-overlay
+---
+ arch/arm/boot/dts/bcm2711-rpi.dtsi | 1 +
+ arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts | 7 +++++++
+ 2 files changed, 8 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi
+@@ -46,6 +46,7 @@
+ clocks = <&clk_108MHz>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
++ status = "disabled";
+ };
+
+ hdmi0: hdmi@7ef00700 {
+--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts
++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts
+@@ -145,6 +145,13 @@
+ };
+ };
+
++ fragment@20 {
++ target = <&dvp>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
+ __overrides__ {
+ audio = <0>,"!17";
+ audio1 = <0>,"!18";
diff --git a/target/linux/bcm27xx/patches-5.4/950-0934-ARM-dts-Add-required-USB-power-domain-for-XCHI.patch b/target/linux/bcm27xx/patches-5.4/950-0934-ARM-dts-Add-required-USB-power-domain-for-XCHI.patch
new file mode 100644
index 0000000000..28cb8e72ae
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0934-ARM-dts-Add-required-USB-power-domain-for-XCHI.patch
@@ -0,0 +1,24 @@
+From 0ce033a8b915cd72b002505dd7b7ff90c36def02 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 5 Aug 2020 17:35:48 +0100
+Subject: [PATCH] ARM: dts: Add required USB power domain for XCHI
+
+The firmware setting otg_mode=1 can be used to enable the onboard XHCI
+controller in host mode, but that requires that the USB power domain
+is enabled.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2711-rpi.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi
+@@ -217,6 +217,7 @@
+ status = "disabled";
+ reg = <0x0 0x7e9c0000 0x0 0x100000>;
+ interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
++ power-domains = <&power RPI_POWER_DOMAIN_USB>;
+ };
+
+ hevc-decoder@7eb00000 {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0935-overlays-Regenerate-upstream-pi4.patch b/target/linux/bcm27xx/patches-5.4/950-0935-overlays-Regenerate-upstream-pi4.patch
new file mode 100644
index 0000000000..429390931d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0935-overlays-Regenerate-upstream-pi4.patch
@@ -0,0 +1,28 @@
+From a5dd8f7ddc00f0f4e58f56b729b7e0066edf4e71 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 12 Aug 2020 10:15:52 +0100
+Subject: [PATCH] overlays: Regenerate upstream-pi4
+
+The recent modification to vc4-kms-v3d-pi4 also results in a change
+to the Pi 4 version of the upstream overlay.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts
++++ b/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts
+@@ -128,6 +128,12 @@
+ };
+ };
+ fragment@20 {
++ target = <&dvp>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++ fragment@21 {
+ target = <&usb>;
+ #address-cells = <1>;
+ #size-cells = <1>;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0936-drm-vc4-Increase-the-number-of-planes-per-crtc-in-FK.patch b/target/linux/bcm27xx/patches-5.4/950-0936-drm-vc4-Increase-the-number-of-planes-per-crtc-in-FK.patch
new file mode 100644
index 0000000000..b2b1e7f46d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0936-drm-vc4-Increase-the-number-of-planes-per-crtc-in-FK.patch
@@ -0,0 +1,105 @@
+From 078e6dfcff1fc4ef0ee3b29a5f94403624c2e7ac Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Mon, 20 Jul 2020 16:42:57 +0100
+Subject: [PATCH] drm/vc4: Increase the number of planes per crtc in
+ FKMS.
+
+The number assigned was arbitrary as one primary, one overlay,
+and one cursor.
+The number has to be below the DRM limit of 32 planes total,
+and the current firmware API limit of 16 planes total.
+
+Increase the number to 8 planes per crtc (1 primary,
+6 overlay, and a cursor).
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c | 54 ++++++++++----------------
+ 1 file changed, 21 insertions(+), 33 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -48,7 +48,7 @@ struct vc4_fkms {
+ bool bcm2711;
+ };
+
+-#define PLANES_PER_CRTC 3
++#define PLANES_PER_CRTC 8
+
+ struct set_plane {
+ u8 display;
+@@ -1742,7 +1742,6 @@ static int vc4_fkms_create_screen(struct
+ struct vc4_crtc *vc4_crtc;
+ struct vc4_fkms_encoder *vc4_encoder;
+ struct drm_crtc *crtc;
+- struct drm_plane *primary_plane, *overlay_plane, *cursor_plane;
+ struct drm_plane *destroy_plane, *temp;
+ struct mailbox_blank_display blank = {
+ .tag1 = {RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, 4, 0, },
+@@ -1750,7 +1749,8 @@ static int vc4_fkms_create_screen(struct
+ .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_BLANK, 4, 0, },
+ .blank = 1,
+ };
+- int ret;
++ struct drm_plane *planes[PLANES_PER_CRTC];
++ int ret, i;
+
+ vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
+ if (!vc4_crtc)
+@@ -1763,38 +1763,26 @@ static int vc4_fkms_create_screen(struct
+ /* Blank the firmware provided framebuffer */
+ rpi_firmware_property_list(vc4->firmware, &blank, sizeof(blank));
+
+- primary_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_PRIMARY,
+- display_ref,
+- 0 + (display_idx * PLANES_PER_CRTC)
+- );
+- if (IS_ERR(primary_plane)) {
+- dev_err(dev, "failed to construct primary plane\n");
+- ret = PTR_ERR(primary_plane);
+- goto err;
+- }
+-
+- overlay_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_OVERLAY,
+- display_ref,
+- 1 + (display_idx * PLANES_PER_CRTC)
+- );
+- if (IS_ERR(overlay_plane)) {
+- dev_err(dev, "failed to construct overlay plane\n");
+- ret = PTR_ERR(overlay_plane);
+- goto err;
+- }
+-
+- cursor_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_CURSOR,
+- display_ref,
+- 2 + (display_idx * PLANES_PER_CRTC)
+- );
+- if (IS_ERR(cursor_plane)) {
+- dev_err(dev, "failed to construct cursor plane\n");
+- ret = PTR_ERR(cursor_plane);
+- goto err;
++ for (i = 0; i < PLANES_PER_CRTC; i++) {
++ planes[i] = vc4_fkms_plane_init(drm,
++ (i == 0) ?
++ DRM_PLANE_TYPE_PRIMARY :
++ (i == PLANES_PER_CRTC - 1) ?
++ DRM_PLANE_TYPE_CURSOR :
++ DRM_PLANE_TYPE_OVERLAY,
++ display_ref,
++ i + (display_idx * PLANES_PER_CRTC)
++ );
++ if (IS_ERR(planes[i])) {
++ dev_err(dev, "failed to construct plane %u\n", i);
++ ret = PTR_ERR(planes[i]);
++ goto err;
++ }
+ }
+
+- drm_crtc_init_with_planes(drm, crtc, primary_plane, cursor_plane,
+- &vc4_crtc_funcs, NULL);
++ drm_crtc_init_with_planes(drm, crtc, planes[0],
++ planes[PLANES_PER_CRTC - 1], &vc4_crtc_funcs,
++ NULL);
+ drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs);
+
+ vc4_encoder = devm_kzalloc(dev, sizeof(*vc4_encoder), GFP_KERNEL);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0937-drm-vc4-Set-the-possible-crtcs-mask-correctly-for-pl.patch b/target/linux/bcm27xx/patches-5.4/950-0937-drm-vc4-Set-the-possible-crtcs-mask-correctly-for-pl.patch
new file mode 100644
index 0000000000..9f020f7a53
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0937-drm-vc4-Set-the-possible-crtcs-mask-correctly-for-pl.patch
@@ -0,0 +1,40 @@
+From 84a67330f3457469bc42f203111fc5ad800c506b Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 13 Aug 2020 18:29:56 +0100
+Subject: [PATCH] drm/vc4: Set the possible crtcs mask correctly for
+ planes with FKMS
+
+The driver was assigning all planes to crtcs when actually they're
+mapped to a specific crtc.
+
+Correct the mask.
+
+https://github.com/raspberrypi/linux/issues/3734
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -816,7 +816,7 @@ static struct drm_plane *vc4_fkms_plane_
+ formats[num_formats++] = vc_image_formats[i].drm;
+
+ plane = &vc4_plane->base;
+- ret = drm_universal_plane_init(dev, plane, 0xff,
++ ret = drm_universal_plane_init(dev, plane, 0,
+ &vc4_plane_funcs,
+ formats, num_formats, modifiers,
+ type, NULL);
+@@ -1785,6 +1785,10 @@ static int vc4_fkms_create_screen(struct
+ NULL);
+ drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs);
+
++ /* Update the possible_crtcs mask for the overlay plane(s) */
++ for (i = 1; i < (PLANES_PER_CRTC - 1); i++)
++ planes[i]->possible_crtcs = drm_crtc_mask(crtc);
++
+ vc4_encoder = devm_kzalloc(dev, sizeof(*vc4_encoder), GFP_KERNEL);
+ if (!vc4_encoder)
+ return -ENOMEM;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0938-staging-vc04_services-codec-Fix-incorrect-buffer-cle.patch b/target/linux/bcm27xx/patches-5.4/950-0938-staging-vc04_services-codec-Fix-incorrect-buffer-cle.patch
new file mode 100644
index 0000000000..14736dc2dc
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0938-staging-vc04_services-codec-Fix-incorrect-buffer-cle.patch
@@ -0,0 +1,52 @@
+From 84fa15b87a5f938c064ee2d9fca43248865ffbec Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 13 Aug 2020 16:58:18 +0100
+Subject: [PATCH] staging: vc04_services: codec: Fix incorrect buffer
+ cleanup
+
+The allocated input and output buffers are initialised in
+buf_init and should only be cleared up in buf_cleanup.
+stop_streaming was (incorrectly) cleaning up the buffers to
+avoid an issue in videobuf2 that had been fixed by the orphaned
+buffer support.
+
+Remove the erroneous cleanup.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../bcm2835-codec/bcm2835-v4l2-codec.c | 17 +----------------
+ 1 file changed, 1 insertion(+), 16 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+@@ -2320,10 +2320,7 @@ static void bcm2835_codec_stop_streaming
+ struct bcm2835_codec_q_data *q_data = get_q_data(ctx, q->type);
+ struct vchiq_mmal_port *port = get_port_data(ctx, q->type);
+ struct vb2_v4l2_buffer *vbuf;
+- struct vb2_v4l2_buffer *vb2;
+- struct v4l2_m2m_buffer *m2m;
+- struct m2m_mmal_buffer *buf;
+- int ret, i;
++ int ret;
+
+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: type: %d - return buffers\n",
+ __func__, q->type);
+@@ -2363,18 +2360,6 @@ static void bcm2835_codec_stop_streaming
+ }
+ }
+
+- /*
+- * Release the VCSM handle here as otherwise REQBUFS(0) aborts because
+- * someone is using the dmabuf before giving the driver a chance to do
+- * anything about it.
+- */
+- for (i = 0; i < q->num_buffers; i++) {
+- vb2 = to_vb2_v4l2_buffer(q->bufs[i]);
+- m2m = container_of(vb2, struct v4l2_m2m_buffer, vb);
+- buf = container_of(m2m, struct m2m_mmal_buffer, m2m);
+-
+- bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
+- }
+
+ /* If both ports disabled, then disable the component */
+ if (!ctx->component->input[0].enabled &&
diff --git a/target/linux/bcm27xx/patches-5.4/950-0939-staging-vc04_service-codec-Allow-start_streaming-to-.patch b/target/linux/bcm27xx/patches-5.4/950-0939-staging-vc04_service-codec-Allow-start_streaming-to-.patch
new file mode 100644
index 0000000000..66a551d2d7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0939-staging-vc04_service-codec-Allow-start_streaming-to-.patch
@@ -0,0 +1,70 @@
+From d88ef7d22cac032c4ddf7e4b8af5982d5a3019cb Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 13 Aug 2020 17:01:27 +0100
+Subject: [PATCH] staging: vc04_service: codec: Allow start_streaming
+ to update the buffernum
+
+start_streaming passes a count of how many buffers have been queued
+to videobuf2.
+
+Allow this value to update the number of buffers the VPU allocates
+on a port to avoid buffer recycling issues.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../bcm2835-codec/bcm2835-v4l2-codec.c | 23 +++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+@@ -2268,6 +2268,7 @@ static int bcm2835_codec_start_streaming
+ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(q);
+ struct bcm2835_codec_dev *dev = ctx->dev;
+ struct bcm2835_codec_q_data *q_data = get_q_data(ctx, q->type);
++ struct vchiq_mmal_port *port = get_port_data(ctx, q->type);
+ int ret;
+
+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: type: %d count %d\n",
+@@ -2283,6 +2284,20 @@ static int bcm2835_codec_start_streaming
+ ctx->component_enabled = true;
+ }
+
++ if (count < port->minimum_buffer.num)
++ count = port->minimum_buffer.num;
++
++ if (port->current_buffer.num != count + 1) {
++ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, buffer count changed %u to %u\n",
++ __func__, ctx, port->current_buffer.num, count + 1);
++
++ port->current_buffer.num = count + 1;
++ ret = vchiq_mmal_port_set_format(dev->instance, port);
++ if (ret)
++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Error updating buffer count, ret %d\n",
++ __func__, ret);
++ }
++
+ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ /*
+ * Create the EOS buffer.
+@@ -2294,17 +2309,17 @@ static int bcm2835_codec_start_streaming
+ &q_data->eos_buffer.mmal);
+ q_data->eos_buffer_in_use = false;
+
+- ctx->component->input[0].cb_ctx = ctx;
++ port->cb_ctx = ctx;
+ ret = vchiq_mmal_port_enable(dev->instance,
+- &ctx->component->input[0],
++ port,
+ ip_buffer_cb);
+ if (ret)
+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling i/p port, ret %d\n",
+ __func__, ret);
+ } else {
+- ctx->component->output[0].cb_ctx = ctx;
++ port->cb_ctx = ctx;
+ ret = vchiq_mmal_port_enable(dev->instance,
+- &ctx->component->output[0],
++ port,
+ op_buffer_cb);
+ if (ret)
+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n",
diff --git a/target/linux/bcm27xx/patches-5.4/950-0940-staging-vc04_services-codec-Fix-component-enable-dis.patch b/target/linux/bcm27xx/patches-5.4/950-0940-staging-vc04_services-codec-Fix-component-enable-dis.patch
new file mode 100644
index 0000000000..16c1cd79c0
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0940-staging-vc04_services-codec-Fix-component-enable-dis.patch
@@ -0,0 +1,38 @@
+From 764c8052ce21a56a55dc25dbc6ee0c075952cdeb Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 13 Aug 2020 17:04:53 +0100
+Subject: [PATCH] staging: vc04_services: codec: Fix component
+ enable/disable
+
+start_streaming enabled the VPU component if ctx->component_enabled
+was not set.
+stop_streaming disabled the VPU component if both ports were
+disabled. It didn't clear ctx->component_enabled.
+
+If seeking, this meant that the component never got re-enabled,
+and buffers never got processed afterwards.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+@@ -2377,13 +2377,15 @@ static void bcm2835_codec_stop_streaming
+
+
+ /* If both ports disabled, then disable the component */
+- if (!ctx->component->input[0].enabled &&
++ if (ctx->component_enabled &&
++ !ctx->component->input[0].enabled &&
+ !ctx->component->output[0].enabled) {
+ ret = vchiq_mmal_component_disable(dev->instance,
+ ctx->component);
+ if (ret)
+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling component, ret %d\n",
+ __func__, ret);
++ ctx->component_enabled = false;
+ }
+
+ if (V4L2_TYPE_IS_OUTPUT(q->type))
diff --git a/target/linux/bcm27xx/patches-5.4/950-0941-update-rpi-display-overlay.dts-pins-for-5.4.patch b/target/linux/bcm27xx/patches-5.4/950-0941-update-rpi-display-overlay.dts-pins-for-5.4.patch
new file mode 100644
index 0000000000..eed665bd4e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0941-update-rpi-display-overlay.dts-pins-for-5.4.patch
@@ -0,0 +1,32 @@
+From 6d2723af0ade644e99e069b54dbcac8b58d603f2 Mon Sep 17 00:00:00 2001
+From: Andreas Watterott <1488433+awatterott@users.noreply.github.com>
+Date: Mon, 17 Aug 2020 21:17:09 +0200
+Subject: [PATCH] update rpi-display-overlay.dts pins for 5.4
+
+---
+ arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts
++++ b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts
+@@ -59,9 +59,9 @@
+ bgr;
+ fps = <30>;
+ buswidth = <8>;
+- reset-gpios = <&gpio 23 0>;
++ reset-gpios = <&gpio 23 1>;
+ dc-gpios = <&gpio 24 0>;
+- led-gpios = <&gpio 18 1>;
++ led-gpios = <&gpio 18 0>;
+ debug = <0>;
+ };
+
+@@ -72,7 +72,7 @@
+ spi-max-frequency = <2000000>;
+ interrupts = <25 2>; /* high-to-low edge triggered */
+ interrupt-parent = <&gpio>;
+- pendown-gpio = <&gpio 25 0>;
++ pendown-gpio = <&gpio 25 1>;
+ ti,x-plate-ohms = /bits/ 16 <60>;
+ ti,pressure-max = /bits/ 16 <255>;
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0942-Bluetooth-btrtl-Add-support-for-RTL8761B.patch b/target/linux/bcm27xx/patches-5.4/950-0942-Bluetooth-btrtl-Add-support-for-RTL8761B.patch
new file mode 100644
index 0000000000..f0fbdd4356
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0942-Bluetooth-btrtl-Add-support-for-RTL8761B.patch
@@ -0,0 +1,77 @@
+From 61695e30db3121c11e52be89751e610d2e97212a Mon Sep 17 00:00:00 2001
+From: "Ziqian SUN (Zamir)" <sztsian@gmail.com>
+Date: Sat, 11 Apr 2020 09:34:27 +0800
+Subject: [PATCH] Bluetooth: btrtl: Add support for RTL8761B
+
+commit 04896832c94aae4842100cafb8d3a73e1bed3a45 upstream.
+
+Add new compatible device RTL8761B. RTL8761B is a USB Bluetooth device,
+with support of BLE and BR/EDR. The USB info is
+
+T: Bus=03 Lev=04 Prnt=04 Port=00 Cnt=01 Dev#= 29 Spd=12 MxCh= 0
+D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
+P: Vendor=0bda ProdID=8771 Rev= 2.00
+S: Manufacturer=Realtek
+S: Product=Bluetooth Radio
+S: SerialNumber=XXXXXXXXXXXX
+C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+
+Signed-off-by: Ziqian SUN (Zamir) <sztsian@gmail.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+---
+ drivers/bluetooth/btrtl.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/bluetooth/btrtl.c
++++ b/drivers/bluetooth/btrtl.c
+@@ -130,12 +130,19 @@ static const struct id_table ic_id_table
+ .cfg_name = "rtl_bt/rtl8821c_config" },
+
+ /* 8761A */
+- { IC_MATCH_FL_LMPSUBV, RTL_ROM_LMP_8761A, 0x0,
++ { IC_INFO(RTL_ROM_LMP_8761A, 0xa),
+ .config_needed = false,
+ .has_rom_version = true,
+ .fw_name = "rtl_bt/rtl8761a_fw.bin",
+ .cfg_name = "rtl_bt/rtl8761a_config" },
+
++ /* 8761B */
++ { IC_INFO(RTL_ROM_LMP_8761A, 0xb),
++ .config_needed = false,
++ .has_rom_version = true,
++ .fw_name = "rtl_bt/rtl8761b_fw.bin",
++ .cfg_name = "rtl_bt/rtl8761b_config" },
++
+ /* 8822C with USB interface */
+ { IC_INFO(RTL_ROM_LMP_8822B, 0xc),
+ .config_needed = false,
+@@ -255,6 +262,7 @@ static int rtlbt_parse_firmware(struct h
+ { RTL_ROM_LMP_8723B, 9 }, /* 8723D */
+ { RTL_ROM_LMP_8821A, 10 }, /* 8821C */
+ { RTL_ROM_LMP_8822B, 13 }, /* 8822C */
++ { RTL_ROM_LMP_8761A, 14 }, /* 8761B */
+ };
+
+ min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0943-dtoverlays-Add-overlay-for-the-PCA953x-family-of-GPI.patch b/target/linux/bcm27xx/patches-5.4/950-0943-dtoverlays-Add-overlay-for-the-PCA953x-family-of-GPI.patch
new file mode 100644
index 0000000000..181440c8db
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0943-dtoverlays-Add-overlay-for-the-PCA953x-family-of-GPI.patch
@@ -0,0 +1,315 @@
+From 5a7c48622a4f7665039211414c9fe4a1914ae3eb Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Mon, 17 Aug 2020 18:11:47 +0100
+Subject: [PATCH] dtoverlays: Add overlay for the PCA953x family of
+ GPIO expanders
+
+Adds an overlay for configuring all the GPIO expanders supported
+by the driver under GPIO_PCA953X.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 36 +++
+ .../arm/boot/dts/overlays/pca953x-overlay.dts | 240 ++++++++++++++++++
+ 3 files changed, 277 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/pca953x-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -119,6 +119,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ ov7251.dtbo \
+ ov9281.dtbo \
+ papirus.dtbo \
++ pca953x.dtbo \
+ pibell.dtbo \
+ piglow.dtbo \
+ piscreen.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1873,6 +1873,42 @@ Params: panel Display
+ speed Display SPI bus speed
+
+
++Name: pca953x
++Info: TI PCA953x family of I2C GPIO expanders. Default is for NXP PCA9534.
++Load: dtoverlay=pca953x,<param>=<val>
++Params: addr I2C address of expander. Default 0x20.
++ pca6416 Select the NXP PCA6416 (16 bit)
++ pca9505 Select the NXP PCA9505 (40 bit)
++ pca9535 Select the NXP PCA9535 (16 bit)
++ pca9536 Select the NXP PCA9536 or TI PCA9536 (4 bit)
++ pca9537 Select the NXP PCA9537 (4 bit)
++ pca9538 Select the NXP PCA9538 (8 bit)
++ pca9539 Select the NXP PCA9539 (16 bit)
++ pca9554 Select the NXP PCA9554 (8 bit)
++ pca9555 Select the NXP PCA9555 (16 bit)
++ pca9556 Select the NXP PCA9556 (8 bit)
++ pca9557 Select the NXP PCA9557 (8 bit)
++ pca9574 Select the NXP PCA9574 (8 bit)
++ pca9575 Select the NXP PCA9575 (16 bit)
++ pca9698 Select the NXP PCA9698 (40 bit)
++ pca16416 Select the NXP PCA16416 (16 bit)
++ pca16524 Select the NXP PCA16524 (24 bit)
++ pca19555a Select the NXP PCA19555A (16 bit)
++ max7310 Select the Maxim MAX7310 (8 bit)
++ max7312 Select the Maxim MAX7312 (16 bit)
++ max7313 Select the Maxim MAX7313 (16 bit)
++ max7315 Select the Maxim MAX7315 (8 bit)
++ pca6107 Select the TI PCA6107 (8 bit)
++ tca6408 Select the TI TCA6408 (8 bit)
++ tca6416 Select the TI TCA6416 (16 bit)
++ tca6424 Select the TI TCA6424 (24 bit)
++ tca9539 Select the TI TCA9539 (16 bit)
++ tca9554 Select the TI TCA9554 (8 bit)
++ cat9554 Select the Onnn CAT9554 (8 bit)
++ pca9654 Select the Onnn PCA9654 (8 bit)
++ xra1202 Select the Exar XRA1202 (8 bit)
++
++
+ [ The pcf2127-rtc overlay has been deleted. See i2c-rtc. ]
+
+
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/pca953x-overlay.dts
+@@ -0,0 +1,240 @@
++// Definitions for NXP PCA953x family of I2C GPIO controllers on ARM I2C bus.
++/dts-v1/;
++/plugin/;
++
++/{
++ compatible = "brcm,bcm2835";
++
++ fragment@0 {
++ target = <&i2c_arm>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ pca: pca@20 {
++ compatible = "nxp,pca9534";
++ reg = <0x20>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ status = "okay";
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca6416";
++ };
++ };
++ fragment@2 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca9505";
++ };
++ };
++ fragment@3 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca9535";
++ };
++ };
++ fragment@4 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca9536";
++ };
++ };
++ fragment@5 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca9537";
++ };
++ };
++ fragment@6 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca9538";
++ };
++ };
++ fragment@7 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca9539";
++ };
++ };
++ fragment@8 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca9554";
++ };
++ };
++ fragment@9 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca9555";
++ };
++ };
++ fragment@10 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca9556";
++ };
++ };
++ fragment@11 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca9557";
++ };
++ };
++ fragment@12 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca9574";
++ };
++ };
++ fragment@13 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca9575";
++ };
++ };
++ fragment@14 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca9698";
++ };
++ };
++ fragment@15 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca16416";
++ };
++ };
++ fragment@16 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca16524";
++ };
++ };
++ fragment@17 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "nxp,pca19555a";
++ };
++ };
++ fragment@18 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "maxim,max7310";
++ };
++ };
++ fragment@19 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "maxim,max7312";
++ };
++ };
++ fragment@20 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "maxim,max7313";
++ };
++ };
++ fragment@21 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "maxim,max7315";
++ };
++ };
++ fragment@22 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "ti,pca6107";
++ };
++ };
++ fragment@23 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "ti,tca6408";
++ };
++ };
++ fragment@24 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "ti,tca6416";
++ };
++ };
++ fragment@25 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "ti,tca6424";
++ };
++ };
++ fragment@26 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "ti,tca9539";
++ };
++ };
++ fragment@27 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "ti,tca9554";
++ };
++ };
++ fragment@28 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "onnn,cat9554";
++ };
++ };
++ fragment@29 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "onnn,pca9654";
++ };
++ };
++ fragment@30 {
++ target = <&pca>;
++ __dormant__ {
++ compatible = "exar,xra1202";
++ };
++ };
++
++ __overrides__ {
++ addr = <&pca>,"reg:0";
++ pca6416 = <0>, "+1";
++ pca9505 = <0>, "+2";
++ pca9535 = <0>, "+3";
++ pca9536 = <0>, "+4";
++ pca9537 = <0>, "+5";
++ pca9538 = <0>, "+6";
++ pca9539 = <0>, "+7";
++ pca9554 = <0>, "+8";
++ pca9555 = <0>, "+9";
++ pca9556 = <0>, "+10";
++ pca9557 = <0>, "+11";
++ pca9574 = <0>, "+12";
++ pca9575 = <0>, "+13";
++ pca9698 = <0>, "+14";
++ pca16416 = <0>, "+15";
++ pca16524 = <0>, "+16";
++ pca19555a = <0>, "+17";
++ max7310 = <0>, "+18";
++ max7312 = <0>, "+19";
++ max7313 = <0>, "+20";
++ max7315 = <0>, "+21";
++ pca6107 = <0>, "+22";
++ tca6408 = <0>, "+23";
++ tca6416 = <0>, "+24";
++ tca6424 = <0>, "+25";
++ tca9539 = <0>, "+26";
++ tca9554 = <0>, "+27";
++ cat9554 = <0>, "+28";
++ pca9654 = <0>, "+29";
++ xra1202 = <0>, "+30";
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-0944-rtc-rv3028-Write-BSM-and-TCE-TCR-to-EEPROM.patch b/target/linux/bcm27xx/patches-5.4/950-0944-rtc-rv3028-Write-BSM-and-TCE-TCR-to-EEPROM.patch
new file mode 100644
index 0000000000..54f3f4f367
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0944-rtc-rv3028-Write-BSM-and-TCE-TCR-to-EEPROM.patch
@@ -0,0 +1,120 @@
+From ffc137a8949cd7859bdf139fa7a56b9dbdb4b2ce Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 15 May 2020 16:28:32 +0100
+Subject: [PATCH] rtc: rv3028: Write BSM and TCE/TCR to EEPROM
+
+Periodically the RV3028 refreshes registers from the EEPROM. When this
+happens, some settings that have only been committed to registers are
+lost. Change the handling of backup-switchover-mode and
+trickle-resistor-ohms to write the EEPROM instead (if something has
+changed), on the understanding that registers will be refreshed
+afterwards.
+
+See: https://github.com/raspberrypi/linux/issues/2912
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/rtc/rtc-rv3028.c | 60 ++++++++++++++++++++++++++++------------
+ 1 file changed, 43 insertions(+), 17 deletions(-)
+
+--- a/drivers/rtc/rtc-rv3028.c
++++ b/drivers/rtc/rtc-rv3028.c
+@@ -18,6 +18,7 @@
+ #include <linux/of_device.h>
+ #include <linux/regmap.h>
+ #include <linux/rtc.h>
++//#include "rtc-core.h"
+
+ #define RV3028_SEC 0x00
+ #define RV3028_MIN 0x01
+@@ -73,7 +74,7 @@
+
+ #define RV3028_BACKUP_TCE BIT(5)
+ #define RV3028_BACKUP_TCR_MASK GENMASK(1,0)
+-#define RV3028_BACKUP_BSM_MASK 0x0C
++#define RV3028_BACKUP_BSM_MASK GENMASK(3,2)
+
+ #define OFFSET_STEP_PPT 953674
+
+@@ -601,7 +602,8 @@ static int rv3028_probe(struct i2c_clien
+ struct rv3028_data *rv3028;
+ int ret, status;
+ u32 ohms;
+- u8 bsm;
++ u32 bsm;
++ u8 backup, backup_bits, backup_mask;
+ struct nvmem_config nvmem_cfg = {
+ .name = "rv3028_nvram",
+ .word_size = 1,
+@@ -673,16 +675,17 @@ static int rv3028_probe(struct i2c_clien
+ if (ret)
+ return ret;
+
++ backup_bits = 0;
++ backup_mask = 0;
++
+ /* setup backup switchover mode */
+- if (!device_property_read_u8(&client->dev, "backup-switchover-mode",
+- &bsm)) {
++ dev_dbg(&client->dev, "Checking RTC backup switchover-mode\n");
++ if (!device_property_read_u32(&client->dev,
++ "backup-switchover-mode",
++ &bsm)) {
+ if (bsm <= 3) {
+- ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP,
+- RV3028_BACKUP_BSM_MASK,
+- (bsm & 0x03) << 2);
+-
+- if (ret)
+- return ret;
++ backup_bits |= (u8)(bsm << 2);
++ backup_mask |= RV3028_BACKUP_BSM_MASK;
+ } else {
+ dev_warn(&client->dev, "invalid backup switchover mode value\n");
+ }
+@@ -698,15 +701,38 @@ static int rv3028_probe(struct i2c_clien
+ break;
+
+ if (i < ARRAY_SIZE(rv3028_trickle_resistors)) {
+- ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP,
+- RV3028_BACKUP_TCE |
+- RV3028_BACKUP_TCR_MASK,
+- RV3028_BACKUP_TCE | i);
+- if (ret)
+- return ret;
++ backup_bits |= RV3028_BACKUP_TCE | i;
++ backup_mask |= RV3028_BACKUP_TCE |
++ RV3028_BACKUP_TCR_MASK;
+ } else {
+- dev_warn(&client->dev, "invalid trickle resistor value\n");
++ dev_warn(&client->dev,
++ "invalid trickle resistor value\n");
++ }
++ }
++
++ if (backup_mask) {
++ ret = rv3028_eeprom_read((void *)(rv3028->regmap),
++ RV3028_BACKUP,
++ (void *)&backup, 1);
++ if (!ret) {
++ /* Write EEPROM only if needed */
++ if ((backup & backup_mask) != backup_bits) {
++ backup = (backup & ~backup_mask) | backup_bits;
++ dev_dbg(&client->dev,
++ "Backup register doesn't match: EEPROM write required\n");
++ ret = rv3028_eeprom_write(
++ (void *)(rv3028->regmap),
++ RV3028_BACKUP, (void *)&backup, 1);
++ }
+ }
++
++ /* In the event of an EEPROM failure, update the register
++ instead. */
++ if (ret)
++ ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP,
++ backup_mask, backup_bits);
++ if (ret)
++ return ret;
+ }
+
+ ret = rtc_add_group(rv3028->rtc, &rv3028_attr_group);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0945-rtc-rv3028-Refresh-RAM-on-EEPROM-write.patch b/target/linux/bcm27xx/patches-5.4/950-0945-rtc-rv3028-Refresh-RAM-on-EEPROM-write.patch
new file mode 100644
index 0000000000..94e3038c8a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0945-rtc-rv3028-Refresh-RAM-on-EEPROM-write.patch
@@ -0,0 +1,92 @@
+From 010b506d6b215673f188ed5cdc4e35419e3ea715 Mon Sep 17 00:00:00 2001
+From: Einar Vading <einar.vading@rhimagnesita.com>
+Date: Fri, 14 Aug 2020 22:14:41 +0200
+Subject: [PATCH] rtc: rv3028: Refresh RAM on EEPROM write
+
+The active RV3028 settings are in RAM so after modifying the settings in
+EEPROM the RAM should be refreshed so that they take effect.
+
+Signed-off-by: Einar Vading <einar.vading@rhimagnesita.com>
+---
+ drivers/rtc/rtc-rv3028.c | 56 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+--- a/drivers/rtc/rtc-rv3028.c
++++ b/drivers/rtc/rtc-rv3028.c
+@@ -66,6 +66,7 @@
+
+ #define RV3028_EVT_CTRL_TSR BIT(2)
+
++#define RV3028_EEPROM_CMD_REFRESH 0x12
+ #define RV3028_EEPROM_CMD_WRITE 0x21
+ #define RV3028_EEPROM_CMD_READ 0x22
+
+@@ -583,6 +584,58 @@ restore_eerd:
+ return ret;
+ }
+
++static int rv3028_ram_refresh(void *priv)
++{
++ u32 status, ctrl1;
++ int ret, err;
++
++ ret = regmap_read(priv, RV3028_CTRL1, &ctrl1);
++ if (ret)
++ return ret;
++
++ if (!(ctrl1 & RV3028_CTRL1_EERD)) {
++ ret = regmap_update_bits(priv, RV3028_CTRL1,
++ RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
++ if (ret)
++ return ret;
++
++ ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
++ !(status & RV3028_STATUS_EEBUSY),
++ RV3028_EEBUSY_POLL,
++ RV3028_EEBUSY_TIMEOUT);
++ if (ret)
++ goto restore_eerd;
++ }
++
++ ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0);
++ if (ret)
++ goto restore_eerd;
++
++ ret = regmap_write(priv, RV3028_EEPROM_CMD,
++ RV3028_EEPROM_CMD_REFRESH);
++ if (ret)
++ goto restore_eerd;
++
++ usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);
++
++ ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
++ !(status & RV3028_STATUS_EEBUSY),
++ RV3028_EEBUSY_POLL,
++ RV3028_EEBUSY_TIMEOUT);
++ if (ret)
++ goto restore_eerd;
++
++restore_eerd:
++ if (!(ctrl1 & RV3028_CTRL1_EERD)) {
++ err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD,
++ 0);
++ if (err && !ret)
++ ret = err;
++ }
++
++ return ret;
++}
++
+ static struct rtc_class_ops rv3028_rtc_ops = {
+ .read_time = rv3028_get_time,
+ .set_time = rv3028_set_time,
+@@ -723,6 +776,9 @@ static int rv3028_probe(struct i2c_clien
+ ret = rv3028_eeprom_write(
+ (void *)(rv3028->regmap),
+ RV3028_BACKUP, (void *)&backup, 1);
++
++ if (!ret)
++ ret = rv3028_ram_refresh((void *)(rv3028->regmap));
+ }
+ }
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0946-dt-overlays-Add-PiFace-Digital-Device-Tree-Overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0946-dt-overlays-Add-PiFace-Digital-Device-Tree-Overlay.patch
new file mode 100644
index 0000000000..d9a6675f07
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0946-dt-overlays-Add-PiFace-Digital-Device-Tree-Overlay.patch
@@ -0,0 +1,199 @@
+From 296cff78df285c99a52760cbcd896abc37820e06 Mon Sep 17 00:00:00 2001
+From: Thomas Preston <thomas.preston@codethink.co.uk>
+Date: Thu, 13 Aug 2020 01:38:35 +0100
+Subject: [PATCH] dt/overlays: Add PiFace Digital Device Tree Overlay
+
+The PiFace Digital is a convenient breakout board for the Microchip
+mcp23s17 SPI GPIO port expander.
+
+The first eight GPIOs 0..7 (bank A) are connected to eight output
+terminals and LEDs, plus two relays on the first two outputs. These
+output loads are active-high.
+
+The next eight GPIOs 8..15 (bank B) are connected to eight input
+terminals with four on-board switches connecting them to ground. Inputs
+devices are therefore expected to bridge terminals to ground, so the
+mcp23s17 pullups are activated for GPIO bank B.
+
+Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 8 +
+ .../dts/overlays/pifacedigital-overlay.dts | 144 ++++++++++++++++++
+ 3 files changed, 153 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/pifacedigital-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -121,6 +121,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ papirus.dtbo \
+ pca953x.dtbo \
+ pibell.dtbo \
++ pifacedigital.dtbo \
+ piglow.dtbo \
+ piscreen.dtbo \
+ piscreen2r.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1949,6 +1949,14 @@ Params: alsaname Set the
+ "PiBell")
+
+
++Name: pifacedigital
++Info: Configures the PiFace Digital mcp23s17 GPIO port expander.
++Load: dtoverlay=pifacedigital,<param>=<val>
++Params: spi-present-mask 8-bit integer, bitmap indicating MCP23S17 SPI0
++ CS0 address. PiFace Digital supports addresses
++ 0-3, which can be configured with JP1 and JP2.
++
++
+ Name: piglow
+ Info: Configures the PiGlow by pimoroni.com
+ Load: dtoverlay=piglow
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/pifacedigital-overlay.dts
+@@ -0,0 +1,144 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * PiFace Digital, Device Tree Overlay.
++ * Copyright (C) 2020 Thomas Preston <thomas.preston@codethink.co.uk>
++ *
++ * The PiFace Digital is a convenient breakout board for the Microchip mcp23s17
++ * SPI GPIO port expander.
++ *
++ * The first eight GPIOs 0..7 (bank A) are connected to eight output terminals
++ * and LEDs, plus two relays on the first two outputs. These output loads are
++ * active-high.
++ *
++ * The next eight GPIOs 8..15 (bank B) are connected to eight input terminals
++ * with four on-board switches connecting them to ground. Inputs devices are
++ * therefore expected to bridge terminals to ground, so the mcp23s17 pullups are
++ * activated for GPIO bank B.
++ *
++ * On PiFace Digital, the mcp23s17 is connected to the Raspberry Pi's SPI0 CS0
++ * bus. Each SPI bus supports up to eight addressable child devices. The PiFace
++ * Digital only supports addresses 0-4, which can be configured by jumpers JP1
++ * and JP2.
++ *
++ * You can tell the driver about these jumper configurations with the
++ * spi-present-mask bitmask:
++ *
++ * | JP1 | JP2 | dtoverlay line in /boot/config.txt |
++ * | --- | --- | ------------------------------------------ |
++ * | 0 | 0 | dtoverlay=pifacedigital |
++ * | 0 | 0 | dtoverlay=pifacedigital:spi-present-mask=1 |
++ * | 0 | 1 | dtoverlay=pifacedigital:spi-present-mask=2 |
++ * | 1 | 0 | dtoverlay=pifacedigital:spi-present-mask=4 |
++ * | 1 | 1 | dtoverlay=pifacedigital:spi-present-mask=8 |
++ *
++ * # Example
++ * Set the dtoverlay config in /boot/config.txt and power off the Raspberry Pi:
++ *
++ * $ grep pifacedigital /boot/config.txt
++ * dtoverlay=pifacedigital
++ * $ sudo systemctl poweroff
++ *
++ * Attach the PiFace Digital and power on the Raspberry Pi.
++ * Then use the libgpiod tools to query the device:
++ *
++ * $ sudo apt install gpiod
++ * $ gpiodetect | grep mcp23s17
++ * gpiochip2 [mcp23s17.0] (16 lines)
++ *
++ * Set GPIO outputs 0, 2 and 5:
++ *
++ * $ gpioset gpiochip2 0=1 2=1 5=1
++ *
++ * Get GPIO status (input GPIO 8..15 are high, because they are active-low):
++ *
++ * $ gpioget gpiochip2 {8..15}
++ * 1 1 1 1 1 1 1 1
++ *
++ * And even monitor interrupts:
++ *
++ * $ gpiomon gpiochip2 {8..15}
++ * event: FALLING EDGE offset: 11 timestamp: [1597361662.926741667]
++ * event: RISING EDGE offset: 11 timestamp: [1597361663.062555051]
++ *
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2835";
++
++ /* Disable exposing /dev/spidev0.0 */
++ fragment@0 {
++ target = <&spidev0>;
++ __overlay__ {
++ status = "disabled";
++ };
++ };
++
++ /* Add the PiFace Digital device node to the spi0.0 device. */
++ fragment@1 {
++ target = <&spi0>;
++ __overlay__ {
++ status = "okay";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ pfdigital: pifacedigital@0 {
++ compatible = "microchip,mcp23s17";
++ reg = <0>;
++
++ /* Set devices present with 8-bit mask. */
++ microchip,spi-present-mask = <0x01>;
++ spi-max-frequency = <500000>;
++
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ /* This device can pass through interrupts. */
++ interrupt-controller;
++ #interrupt-cells = <2>;
++
++ /* INTB is connected to GPIO 25.
++ * 0x8 active-low level-sensitive
++ */
++ interrupts = <25 0x8>;
++ interrupt-parent = <&gpio>;
++
++ /* Configure pull-ups on bank B GPIOs */
++ pinctrl-0 = <&pfdigital_irq &pfdigital_pullups>;
++ pinctrl-names = "default";
++ pfdigital_pullups: pinmux {
++ pins =
++ "gpio8",
++ "gpio9",
++ "gpio10",
++ "gpio11",
++ "gpio12",
++ "gpio13",
++ "gpio14",
++ "gpio15";
++ bias-pull-up;
++ };
++ };
++ };
++ };
++
++ /* PiFace Digital mcp23s17 INTB pin is connected to GPIO 25. The INTB
++ * pin is configured active-low (0 on interrupt), so expect to see
++ * FALLING_EDGE when inputs are bridged to ground (switch is pressed).
++ */
++ fragment@3 {
++ target = <&gpio>;
++ __overlay__ {
++ pfdigital_irq: pifacedigital_irq {
++ brcm,pins = <25>;
++ brcm,function = <0>; /* input */
++ };
++ };
++ };
++
++ __overrides__ {
++ spi-present-mask = <&pfdigital>, "microchip,spi-present-mask:0";
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-0947-overlays-Updated-MCP3008-compatible-strings.patch b/target/linux/bcm27xx/patches-5.4/950-0947-overlays-Updated-MCP3008-compatible-strings.patch
new file mode 100644
index 0000000000..739c4dab52
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0947-overlays-Updated-MCP3008-compatible-strings.patch
@@ -0,0 +1,84 @@
+From 9c5770dd049b3839296ac49fb40f01b6fe55fa81 Mon Sep 17 00:00:00 2001
+From: RICCIARDI-Adrien <adrien.ricciardi@hotmail.fr>
+Date: Thu, 20 Aug 2020 10:18:35 +0200
+Subject: [PATCH] overlays: Updated MCP3008 compatible strings.
+
+Used recommended ones from Documentation/devicetree/bindings/iio/adc/mcp320x.txt.
+---
+ arch/arm/boot/dts/overlays/mcp3008-overlay.dts | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/mcp3008-overlay.dts
++++ b/arch/arm/boot/dts/overlays/mcp3008-overlay.dts
+@@ -72,7 +72,7 @@
+ #size-cells = <0>;
+
+ mcp3008_00: mcp3008@0 {
+- compatible = "mcp3008";
++ compatible = "microchip,mcp3008";
+ reg = <0>;
+ spi-max-frequency = <1600000>;
+ };
+@@ -87,7 +87,7 @@
+ #size-cells = <0>;
+
+ mcp3008_01: mcp3008@1 {
+- compatible = "mcp3008";
++ compatible = "microchip,mcp3008";
+ reg = <1>;
+ spi-max-frequency = <1600000>;
+ };
+@@ -102,7 +102,7 @@
+ #size-cells = <0>;
+
+ mcp3008_10: mcp3008@0 {
+- compatible = "mcp3008";
++ compatible = "microchip,mcp3008";
+ reg = <0>;
+ spi-max-frequency = <1600000>;
+ };
+@@ -117,7 +117,7 @@
+ #size-cells = <0>;
+
+ mcp3008_11: mcp3008@1 {
+- compatible = "mcp3008";
++ compatible = "microchip,mcp3008";
+ reg = <1>;
+ spi-max-frequency = <1600000>;
+ };
+@@ -132,7 +132,7 @@
+ #size-cells = <0>;
+
+ mcp3008_12: mcp3008@2 {
+- compatible = "mcp3008";
++ compatible = "microchip,mcp3008";
+ reg = <2>;
+ spi-max-frequency = <1600000>;
+ };
+@@ -147,7 +147,7 @@
+ #size-cells = <0>;
+
+ mcp3008_20: mcp3008@0 {
+- compatible = "mcp3008";
++ compatible = "microchip,mcp3008";
+ reg = <0>;
+ spi-max-frequency = <1600000>;
+ };
+@@ -162,7 +162,7 @@
+ #size-cells = <0>;
+
+ mcp3008_21: mcp3008@1 {
+- compatible = "mcp3008";
++ compatible = "microchip,mcp3008";
+ reg = <1>;
+ spi-max-frequency = <1600000>;
+ };
+@@ -177,7 +177,7 @@
+ #size-cells = <0>;
+
+ mcp3008_22: mcp3008@2 {
+- compatible = "mcp3008";
++ compatible = "microchip,mcp3008";
+ reg = <2>;
+ spi-max-frequency = <1600000>;
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0948-RESET_CONTROLLER-needs-to-be-activated-to-compile-Br.patch b/target/linux/bcm27xx/patches-5.4/950-0948-RESET_CONTROLLER-needs-to-be-activated-to-compile-Br.patch
new file mode 100644
index 0000000000..68627aa564
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0948-RESET_CONTROLLER-needs-to-be-activated-to-compile-Br.patch
@@ -0,0 +1,20 @@
+From b28871fe542f7805751e804ee385a803af00efae Mon Sep 17 00:00:00 2001
+From: Ramin Moussavi <lordrasmus@gmail.com>
+Date: Sat, 25 Jul 2020 22:31:49 +0200
+Subject: [PATCH] RESET_CONTROLLER needs to be activated to compile
+ Broadcom BCM2835 clock support
+
+---
+ drivers/clk/bcm/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/clk/bcm/Kconfig
++++ b/drivers/clk/bcm/Kconfig
+@@ -5,6 +5,7 @@ config CLK_BCM2835
+ depends on COMMON_CLK
+ default ARCH_BCM2835 || ARCH_BRCMSTB
+ select RESET_SIMPLE
++ select RESET_CONTROLLER
+ help
+ Enable common clock framework support for Broadcom BCM2835
+ SoCs.
diff --git a/target/linux/bcm27xx/patches-5.4/950-0949-media-dvbsky-use-a-single-mutex-and-state-buffers-fo.patch b/target/linux/bcm27xx/patches-5.4/950-0949-media-dvbsky-use-a-single-mutex-and-state-buffers-fo.patch
new file mode 100644
index 0000000000..836364e5de
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0949-media-dvbsky-use-a-single-mutex-and-state-buffers-fo.patch
@@ -0,0 +1,64 @@
+From 08ccbb8e0667e90e5c7334057965c6205a3855fb Mon Sep 17 00:00:00 2001
+From: Andrei Koshkosh <andreykosh000@mail.ru>
+Date: Sun, 29 Sep 2019 05:04:05 -0300
+Subject: [PATCH] media: dvbsky: use a single mutex and state buffers
+ for all R/W ops
+
+commit cecf0bbbcb6f035a5ca2197f3e11ec2b7fb3da83 upstream.
+
+Re-use usb_mutex from dvb_usb_device for this.
+
+See: https://github.com/raspberrypi/linux/issues/3809
+
+Tested-by: Jan Pieter van Woerkom <jp@jpvw.nl>
+Signed-off-by: Andrei Koshkosh <andreykosh000@mail.ru>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+---
+ drivers/media/usb/dvb-usb-v2/dvbsky.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c
++++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c
+@@ -22,7 +22,6 @@ MODULE_PARM_DESC(disable_rc, "Disable in
+ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+ struct dvbsky_state {
+- struct mutex stream_mutex;
+ u8 ibuf[DVBSKY_BUF_LEN];
+ u8 obuf[DVBSKY_BUF_LEN];
+ u8 last_lock;
+@@ -60,17 +59,19 @@ static int dvbsky_usb_generic_rw(struct
+ static int dvbsky_stream_ctrl(struct dvb_usb_device *d, u8 onoff)
+ {
+ struct dvbsky_state *state = d_to_priv(d);
++ static const u8 obuf_pre[3] = { 0x37, 0, 0 };
++ static const u8 obuf_post[3] = { 0x36, 3, 0 };
+ int ret;
+- u8 obuf_pre[3] = { 0x37, 0, 0 };
+- u8 obuf_post[3] = { 0x36, 3, 0 };
+
+- mutex_lock(&state->stream_mutex);
+- ret = dvbsky_usb_generic_rw(d, obuf_pre, 3, NULL, 0);
++ mutex_lock(&d->usb_mutex);
++ memcpy(state->obuf, obuf_pre, 3);
++ ret = dvb_usbv2_generic_write_locked(d, state->obuf, 3);
+ if (!ret && onoff) {
+ msleep(20);
+- ret = dvbsky_usb_generic_rw(d, obuf_post, 3, NULL, 0);
++ memcpy(state->obuf, obuf_post, 3);
++ ret = dvb_usbv2_generic_write_locked(d, state->obuf, 3);
+ }
+- mutex_unlock(&state->stream_mutex);
++ mutex_unlock(&d->usb_mutex);
+ return ret;
+ }
+
+@@ -598,7 +599,6 @@ static int dvbsky_init(struct dvb_usb_de
+ if (ret)
+ return ret;
+ */
+- mutex_init(&state->stream_mutex);
+
+ state->last_lock = 0;
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0950-ARM-dts-bcm2711-Enable-support-for-DDR52-eMMC.patch b/target/linux/bcm27xx/patches-5.4/950-0950-ARM-dts-bcm2711-Enable-support-for-DDR52-eMMC.patch
new file mode 100644
index 0000000000..7a0e78d2f6
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0950-ARM-dts-bcm2711-Enable-support-for-DDR52-eMMC.patch
@@ -0,0 +1,22 @@
+From e31ec540cff5498f86f57cccb7a35b323bdb6f33 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 24 Aug 2020 17:11:34 +0100
+Subject: [PATCH] ARM: dts: bcm2711: Enable support for DDR52 eMMC
+
+See: https://github.com/raspberrypi/linux/issues/3802
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2711-rpi.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi
+@@ -310,3 +310,7 @@
+ &hvs {
+ clocks = <&firmware_clocks 4>;
+ };
++
++&emmc2 {
++ mmc-ddr-3_3v;
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-0951-staging-vc04_services-ISP-Fix-dmabuf-error-check-in-.patch b/target/linux/bcm27xx/patches-5.4/950-0951-staging-vc04_services-ISP-Fix-dmabuf-error-check-in-.patch
new file mode 100644
index 0000000000..32f66fbb8b
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0951-staging-vc04_services-ISP-Fix-dmabuf-error-check-in-.patch
@@ -0,0 +1,25 @@
+From 971ec8a5c6229dc45b89105196a86333635fc553 Mon Sep 17 00:00:00 2001
+From: Paul Elder <paul.elder@ideasonboard.com>
+Date: Mon, 24 Aug 2020 17:14:29 +0900
+Subject: [PATCH] staging: vc04_services: ISP: Fix dmabuf error check
+ in S_CTRL
+
+In bcm2835_isp_s_ctrl, the error check for dma_buf_get() is incorrect,
+and considers ERR_PTR pointers as valid dmabufs. Fix this error check.
+
+Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
+---
+ drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
+@@ -733,7 +733,7 @@ static int bcm2835_isp_s_ctrl(struct v4l
+ sizeof(struct bcm2835_isp_lens_shading));
+
+ dmabuf = dma_buf_get(ls.dmabuf);
+- if (!dmabuf)
++ if (IS_ERR_OR_NULL(dmabuf))
+ return -EINVAL;
+
+ ret = vc_sm_cma_import_dmabuf(dmabuf,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0952-ARM-dts-bcm2708.dtsi-Don-t-delete-the-cpus-node.patch b/target/linux/bcm27xx/patches-5.4/950-0952-ARM-dts-bcm2708.dtsi-Don-t-delete-the-cpus-node.patch
new file mode 100644
index 0000000000..2ad707d33b
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0952-ARM-dts-bcm2708.dtsi-Don-t-delete-the-cpus-node.patch
@@ -0,0 +1,26 @@
+From a32c73cc5a06b0bf7f2b18314b46a052ce6517ee Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 24 Aug 2020 18:28:52 +0100
+Subject: [PATCH] ARM: dts: bcm2708.dtsi: Don't delete the cpus node
+
+The cpus node was originally deleted to match the then downstream
+version of the BCM2835 DTS files, but doing so doesn't seem to make
+any material difference. Its presence is necessary for the CPUFREQ_DT
+support that is planned in the near future, so remove the deletion.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2708.dtsi | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2708.dtsi
++++ b/arch/arm/boot/dts/bcm2708.dtsi
+@@ -2,8 +2,6 @@
+ #include "bcm270x.dtsi"
+
+ / {
+- /delete-node/ cpus;
+-
+ __overrides__ {
+ arm_freq;
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0953-ARM-dts-bcm2835-Use-the-L2-non-allocating-alias.patch b/target/linux/bcm27xx/patches-5.4/950-0953-ARM-dts-bcm2835-Use-the-L2-non-allocating-alias.patch
new file mode 100644
index 0000000000..d87ffc8c22
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0953-ARM-dts-bcm2835-Use-the-L2-non-allocating-alias.patch
@@ -0,0 +1,30 @@
+From 121fdf16a2ff4cf651c376a37eeca255544c47fd Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 27 Aug 2020 17:57:18 +0100
+Subject: [PATCH] ARM: dts: bcm2835: Use the L2 non-allocating alias
+
+The /soc/dma-ranges property on BCM2835 currently results in DMA
+addresses in the range 0x40000000-0x5fffffff. This will allocate in the
+system L2 cache, which may adversely affect performance.
+
+Change the dma-ranges property to give addresses in the range
+0x80000000-0x9fffffff, which are coherent with L2 but non-allocating.
+
+See: https://github.com/raspberrypi/linux/issues/3602
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2835.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/bcm2835.dtsi
++++ b/arch/arm/boot/dts/bcm2835.dtsi
+@@ -18,7 +18,7 @@
+
+ soc {
+ ranges = <0x7e000000 0x20000000 0x02000000>;
+- dma-ranges = <0x40000000 0x00000000 0x20000000>;
++ dma-ranges = <0x80000000 0x00000000 0x20000000>;
+ };
+
+ arm-pmu {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0954-media-bcm2835-unicam-Drop-WARN-on-uing-direct-cache-.patch b/target/linux/bcm27xx/patches-5.4/950-0954-media-bcm2835-unicam-Drop-WARN-on-uing-direct-cache-.patch
new file mode 100644
index 0000000000..481c55b649
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0954-media-bcm2835-unicam-Drop-WARN-on-uing-direct-cache-.patch
@@ -0,0 +1,34 @@
+From d535074e3e2c08ba5a6b627e54f4597f0f6f9240 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 27 Aug 2020 16:30:26 +0100
+Subject: [PATCH] media: bcm2835-unicam: Drop WARN on uing direct
+ cache alias
+
+Pi 0&1 pass all ARM accesses through the VPU L2 cache, therefore
+the dma-ranges property sets the cache alias bits to other
+than the direct alias, hence this WARN was firing.
+
+It was overprotective coding, so assume that everything is OK
+with the dma-ranges, and remove the WARN.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/platform/bcm2835/bcm2835-unicam.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -708,13 +708,6 @@ static void unicam_wr_dma_addr(struct un
+ {
+ dma_addr_t endaddr = dmaaddr + buffer_size;
+
+- /*
+- * dmaaddr and endaddr should be a 32-bit address with the top two bits
+- * set to 0x3 to signify uncached access through the Videocore memory
+- * controller.
+- */
+- WARN_ON((dmaaddr >> 30) != 0x3 || (endaddr >> 30) != 0x3);
+-
+ if (pad_id == IMAGE_PAD) {
+ reg_write(dev, UNICAM_IBSA0, dmaaddr);
+ reg_write(dev, UNICAM_IBEA0, endaddr);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0955-media-i2c-tc358743-Only-allow-supported-pixel-fmts-i.patch b/target/linux/bcm27xx/patches-5.4/950-0955-media-i2c-tc358743-Only-allow-supported-pixel-fmts-i.patch
new file mode 100644
index 0000000000..e7836602c5
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0955-media-i2c-tc358743-Only-allow-supported-pixel-fmts-i.patch
@@ -0,0 +1,30 @@
+From b443f3889a2f689c7f480211e12f17ddc3b483f8 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 10 Jul 2020 12:40:50 +0100
+Subject: [PATCH] media: i2c: tc358743: Only allow supported pixel
+ fmts in set_fmt
+
+Fix commit "media: tc358743: Return an appropriate colorspace from
+tc358743_set_fmt" to ensure that the format passed in to set_fmt
+is checked to be valid, and reset to the current format if not.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/tc358743.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/media/i2c/tc358743.c
++++ b/drivers/media/i2c/tc358743.c
+@@ -1731,8 +1731,10 @@ static int tc358743_set_fmt(struct v4l2_
+ u32 code = format->format.code; /* is overwritten by get_fmt */
+ int ret = tc358743_get_fmt(sd, cfg, format);
+
+- format->format.code = code;
+- format->format.colorspace = tc358743_g_colorspace(code);
++ if (code == MEDIA_BUS_FMT_RGB888_1X24 ||
++ code == MEDIA_BUS_FMT_UYVY8_1X16)
++ format->format.code = code;
++ format->format.colorspace = tc358743_g_colorspace(format->format.code);
+
+ if (ret)
+ return ret;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0956-media-i2c-ov9281-Add-support-for-8-bit-readout.patch b/target/linux/bcm27xx/patches-5.4/950-0956-media-i2c-ov9281-Add-support-for-8-bit-readout.patch
new file mode 100644
index 0000000000..f6880c9eae
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0956-media-i2c-ov9281-Add-support-for-8-bit-readout.patch
@@ -0,0 +1,188 @@
+From c673ce1338b69c5c8c6572e361be02356af93a72 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Tue, 7 Jul 2020 18:29:10 +0100
+Subject: [PATCH] media: i2c: ov9281: Add support for 8 bit readout
+
+The sensor supports 8 bit mode as well as 10bit, so add the
+relevant code to allow selection of this.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/ov9281.c | 66 ++++++++++++++++++++++++++++++--------
+ 1 file changed, 52 insertions(+), 14 deletions(-)
+
+--- a/drivers/media/i2c/ov9281.c
++++ b/drivers/media/i2c/ov9281.c
+@@ -29,11 +29,12 @@
+
+ #define OV9281_LINK_FREQ_400MHZ 400000000
+ #define OV9281_LANES 2
+-#define OV9281_BITS_PER_SAMPLE 10
+
+ /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
+-#define OV9281_PIXEL_RATE (OV9281_LINK_FREQ_400MHZ * 2 * \
+- OV9281_LANES / OV9281_BITS_PER_SAMPLE)
++#define OV9281_PIXEL_RATE_10BIT (OV9281_LINK_FREQ_400MHZ * 2 * \
++ OV9281_LANES / 10)
++#define OV9281_PIXEL_RATE_8BIT (OV9281_LINK_FREQ_400MHZ * 2 * \
++ OV9281_LANES / 8)
+ #define OV9281_XVCLK_FREQ 24000000
+
+ #define CHIP_ID 0x9281
+@@ -122,24 +123,25 @@ struct ov9281 {
+ struct v4l2_ctrl *digi_gain;
+ struct v4l2_ctrl *hblank;
+ struct v4l2_ctrl *vblank;
++ struct v4l2_ctrl *pixel_rate;
+ struct v4l2_ctrl *test_pattern;
+ struct mutex mutex;
+ bool streaming;
+ bool power_on;
+ const struct ov9281_mode *cur_mode;
++ u32 code;
+ };
+
+ #define to_ov9281(sd) container_of(sd, struct ov9281, subdev)
+
+ /*
+ * Xclk 24Mhz
+- * max_framerate 120fps
++ * max_framerate 120fps for 10 bit, 144fps for 8 bit.
+ * mipi_datarate per lane 800Mbps
+ */
+ static const struct regval ov9281_1280x800_regs[] = {
+ {0x0103, 0x01},
+ {0x0302, 0x32},
+- {0x030d, 0x50},
+ {0x030e, 0x02},
+ {0x3001, 0x00},
+ {0x3004, 0x00},
+@@ -168,7 +170,6 @@ static const struct regval ov9281_1280x8
+ {0x3620, 0x6f},
+ {0x3632, 0x56},
+ {0x3633, 0x78},
+- {0x3662, 0x05},
+ {0x3666, 0x00},
+ {0x366f, 0x5a},
+ {0x3680, 0x84},
+@@ -235,6 +236,18 @@ static const struct regval ov9281_1280x8
+ {REG_NULL, 0x00},
+ };
+
++static const struct regval op_10bit[] = {
++ {0x030d, 0x50},
++ {0x3662, 0x05},
++ {REG_NULL, 0x00},
++};
++
++static const struct regval op_8bit[] = {
++ {0x030d, 0x60},
++ {0x3662, 0x07},
++ {REG_NULL, 0x00},
++};
++
+ static const struct ov9281_mode supported_modes[] = {
+ {
+ .width = 1280,
+@@ -374,12 +387,13 @@ static int ov9281_set_fmt(struct v4l2_su
+ {
+ struct ov9281 *ov9281 = to_ov9281(sd);
+ const struct ov9281_mode *mode;
+- s64 h_blank, vblank_def;
++ s64 h_blank, vblank_def, pixel_rate;
+
+ mutex_lock(&ov9281->mutex);
+
+ mode = ov9281_find_best_fit(fmt);
+- fmt->format.code = MEDIA_BUS_FMT_Y10_1X10;
++ if (fmt->format.code != MEDIA_BUS_FMT_Y8_1X8)
++ fmt->format.code = MEDIA_BUS_FMT_Y10_1X10;
+ fmt->format.width = mode->width;
+ fmt->format.height = mode->height;
+ fmt->format.field = V4L2_FIELD_NONE;
+@@ -396,6 +410,7 @@ static int ov9281_set_fmt(struct v4l2_su
+ *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+ } else {
+ ov9281->cur_mode = mode;
++ ov9281->code = fmt->format.code;
+ h_blank = mode->hts_def - mode->width;
+ __v4l2_ctrl_modify_range(ov9281->hblank, h_blank,
+ h_blank, 1, h_blank);
+@@ -405,6 +420,11 @@ static int ov9281_set_fmt(struct v4l2_su
+ OV9281_VTS_MAX - mode->height,
+ 1, vblank_def);
+ __v4l2_ctrl_s_ctrl(ov9281->vblank, vblank_def);
++
++ pixel_rate = (fmt->format.code == MEDIA_BUS_FMT_Y10_1X10) ?
++ OV9281_PIXEL_RATE_10BIT : OV9281_PIXEL_RATE_8BIT;
++ __v4l2_ctrl_modify_range(ov9281->pixel_rate, pixel_rate,
++ pixel_rate, 1, pixel_rate);
+ }
+
+ mutex_unlock(&ov9281->mutex);
+@@ -425,7 +445,7 @@ static int ov9281_get_fmt(struct v4l2_su
+ } else {
+ fmt->format.width = mode->width;
+ fmt->format.height = mode->height;
+- fmt->format.code = MEDIA_BUS_FMT_Y10_1X10;
++ fmt->format.code = ov9281->code;
+ fmt->format.field = V4L2_FIELD_NONE;
+ fmt->format.colorspace = V4L2_COLORSPACE_SRGB;
+ fmt->format.ycbcr_enc =
+@@ -446,9 +466,16 @@ static int ov9281_enum_mbus_code(struct
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+ {
+- if (code->index)
++ switch (code->index) {
++ default:
+ return -EINVAL;
+- code->code = MEDIA_BUS_FMT_Y10_1X10;
++ case 0:
++ code->code = MEDIA_BUS_FMT_Y10_1X10;
++ break;
++ case 1:
++ code->code = MEDIA_BUS_FMT_Y8_1X8;
++ break;
++ }
+
+ return 0;
+ }
+@@ -460,7 +487,8 @@ static int ov9281_enum_frame_sizes(struc
+ if (fse->index >= ARRAY_SIZE(supported_modes))
+ return -EINVAL;
+
+- if (fse->code != MEDIA_BUS_FMT_Y10_1X10)
++ if (fse->code != MEDIA_BUS_FMT_Y10_1X10 &&
++ fse->code != MEDIA_BUS_FMT_Y8_1X8)
+ return -EINVAL;
+
+ fse->min_width = supported_modes[fse->index].width;
+@@ -543,6 +571,13 @@ static int __ov9281_start_stream(struct
+ if (ret)
+ return ret;
+
++ if (ov9281->code == MEDIA_BUS_FMT_Y10_1X10)
++ ret = ov9281_write_array(ov9281->client, op_10bit);
++ else
++ ret = ov9281_write_array(ov9281->client, op_8bit);
++ if (ret)
++ return ret;
++
+ /* In case these controls are set before streaming */
+ mutex_unlock(&ov9281->mutex);
+ ret = v4l2_ctrl_handler_setup(&ov9281->ctrl_handler);
+@@ -849,8 +884,11 @@ static int ov9281_initialize_controls(st
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+- v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
+- 0, OV9281_PIXEL_RATE, 1, OV9281_PIXEL_RATE);
++ ov9281->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
++ V4L2_CID_PIXEL_RATE,
++ OV9281_PIXEL_RATE_10BIT,
++ OV9281_PIXEL_RATE_10BIT, 1,
++ OV9281_PIXEL_RATE_10BIT);
+
+ h_blank = mode->hts_def - mode->width;
+ ov9281->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0957-overlays-Add-spi0-1cs-and-spi0-2cs.patch b/target/linux/bcm27xx/patches-5.4/950-0957-overlays-Add-spi0-1cs-and-spi0-2cs.patch
new file mode 100644
index 0000000000..3af45bb0b6
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0957-overlays-Add-spi0-1cs-and-spi0-2cs.patch
@@ -0,0 +1,199 @@
+From 692af7a59fd6d9d3b64edbf028cd75b0096ef8c7 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 28 Aug 2020 12:55:41 +0100
+Subject: [PATCH] overlays: Add spi0-1cs and spi0-2cs
+
+The spi0-1cs overlay allows the SPI0 interface to be run with a single
+CS line, which can be useful if GPIOs are in short supply. The no_miso
+parameter is for write-only devices that don't need the return channel,
+and again is there to free up a GPIO.
+
+spi0-2cs is the new name for spi0-cs (now deprecated with a redirect
+to spi0-2cs), but with the addedd no_miso parameter.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 3 +-
+ arch/arm/boot/dts/overlays/README | 22 ++++++++--
+ arch/arm/boot/dts/overlays/overlay_map.dts | 4 ++
+ .../boot/dts/overlays/spi0-1cs-overlay.dts | 42 +++++++++++++++++++
+ ...i0-cs-overlay.dts => spi0-2cs-overlay.dts} | 8 ++++
+ 5 files changed, 75 insertions(+), 4 deletions(-)
+ create mode 100644 arch/arm/boot/dts/overlays/spi0-1cs-overlay.dts
+ rename arch/arm/boot/dts/overlays/{spi0-cs-overlay.dts => spi0-2cs-overlay.dts} (79%)
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -161,7 +161,8 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ spi-gpio35-39.dtbo \
+ spi-gpio40-45.dtbo \
+ spi-rtc.dtbo \
+- spi0-cs.dtbo \
++ spi0-1cs.dtbo \
++ spi0-2cs.dtbo \
+ spi1-1cs.dtbo \
+ spi1-2cs.dtbo \
+ spi1-3cs.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -2412,11 +2412,27 @@ Load: dtoverlay=spi-rtc,<param>=<val>
+ Params: pcf2123 Select the PCF2123 device
+
+
+-Name: spi0-cs
+-Info: Allows the (software) CS pins for SPI0 to be changed
+-Load: dtoverlay=spi0-cs,<param>=<val>
++Name: spi0-1cs
++Info: Only use one CS pin for SPI0
++Load: dtoverlay=spi0-1cs,<param>=<val>
++Params: cs0_pin GPIO pin for CS0 (default 8)
++ no_miso Don't claim and use the MISO pin (9), freeing
++ it for other uses.
++
++
++Name: spi0-2cs
++Info: Change the CS pins for SPI0
++Load: dtoverlay=spi0-2cs,<param>=<val>
+ Params: cs0_pin GPIO pin for CS0 (default 8)
+ cs1_pin GPIO pin for CS1 (default 7)
++ no_miso Don't claim and use the MISO pin (9), freeing
++ it for other uses.
++
++
++Name: spi0-cs
++Info: This overlay has been renamed spi0-1cs, keeping spi0-cs as an
++ alias for backwards compatibility.
++Load: <Deprecated>
+
+
+ Name: spi0-hw-cs
+--- a/arch/arm/boot/dts/overlays/overlay_map.dts
++++ b/arch/arm/boot/dts/overlays/overlay_map.dts
+@@ -61,6 +61,10 @@
+ deprecated = "use sdio,bus_width=1,gpios_22_25";
+ };
+
++ spi0-cs {
++ renamed = "spi0-2cs";
++ };
++
+ spi0-hw-cs {
+ deprecated = "no longer necessary";
+ };
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/spi0-1cs-overlay.dts
+@@ -0,0 +1,42 @@
++/dts-v1/;
++/plugin/;
++
++
++/ {
++ compatible = "brcm,bcm2835";
++
++ fragment@0 {
++ target = <&spi0_cs_pins>;
++ frag0: __overlay__ {
++ brcm,pins = <8>;
++ };
++ };
++
++ fragment@1 {
++ target = <&spi0>;
++ frag1: __overlay__ {
++ cs-gpios = <&gpio 8 1>;
++ status = "okay";
++ };
++ };
++
++ fragment@2 {
++ target = <&spidev1>;
++ __overlay__ {
++ status = "disabled";
++ };
++ };
++
++ fragment@3 {
++ target = <&spi0_pins>;
++ __dormant__ {
++ brcm,pins = <10 11>;
++ };
++ };
++
++ __overrides__ {
++ cs0_pin = <&frag0>,"brcm,pins:0",
++ <&frag1>,"cs-gpios:4";
++ no_miso = <0>,"=3";
++ };
++};
+--- a/arch/arm/boot/dts/overlays/spi0-cs-overlay.dts
++++ /dev/null
+@@ -1,29 +0,0 @@
+-/dts-v1/;
+-/plugin/;
+-
+-
+-/ {
+- compatible = "brcm,bcm2835";
+-
+- 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";
+- };
+-};
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/spi0-2cs-overlay.dts
+@@ -0,0 +1,37 @@
++/dts-v1/;
++/plugin/;
++
++
++/ {
++ compatible = "brcm,bcm2835";
++
++ 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";
++ };
++ };
++
++ fragment@2 {
++ target = <&spi0_pins>;
++ __dormant__ {
++ brcm,pins = <10 11>;
++ };
++ };
++
++ __overrides__ {
++ cs0_pin = <&frag0>,"brcm,pins:0",
++ <&frag1>,"cs-gpios:4";
++ cs1_pin = <&frag0>,"brcm,pins:4",
++ <&frag1>,"cs-gpios:16";
++ no_miso = <0>,"=2";
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-0958-overlays-Fix-error-in-README.patch b/target/linux/bcm27xx/patches-5.4/950-0958-overlays-Fix-error-in-README.patch
new file mode 100644
index 0000000000..ab6db1e389
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0958-overlays-Fix-error-in-README.patch
@@ -0,0 +1,23 @@
+From 9102032e6d06f271058b6bd98db453a2275ec9b9 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 28 Aug 2020 22:04:05 +0100
+Subject: [PATCH] overlays: Fix error in README
+
+spi0-cs has been renamed spi0-2cs, not spi0-1cs.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -2430,7 +2430,7 @@ Params: cs0_pin GPIO pin
+
+
+ Name: spi0-cs
+-Info: This overlay has been renamed spi0-1cs, keeping spi0-cs as an
++Info: This overlay has been renamed spi0-2cs, keeping spi0-cs as an
+ alias for backwards compatibility.
+ Load: <Deprecated>
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0959-overlays-Minor-README-correction.patch b/target/linux/bcm27xx/patches-5.4/950-0959-overlays-Minor-README-correction.patch
new file mode 100644
index 0000000000..1cc7ff9c47
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0959-overlays-Minor-README-correction.patch
@@ -0,0 +1,21 @@
+From 8314b7ffe066745d9a2045e2ecaf287487342df3 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 2 Sep 2020 08:39:57 +0100
+Subject: [PATCH] overlays: Minor README correction
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -134,7 +134,7 @@ Params:
+ 6=Alt 7=Speed/Flash
+ 8=Link 9=Activity
+
+- eth_led1 Set mode of LED1 - green on Pi3B (default "6"),
++ eth_led1 Set mode of LED1 - green on Pi3B+ (default "6"),
+ amber on Pi4 (default "8"). See eth_led0 for
+ legal values.
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0960-staging-fbtft-Add-support-for-display-variants.patch b/target/linux/bcm27xx/patches-5.4/950-0960-staging-fbtft-Add-support-for-display-variants.patch
new file mode 100644
index 0000000000..185e8eb493
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0960-staging-fbtft-Add-support-for-display-variants.patch
@@ -0,0 +1,204 @@
+From fe85ae40abf546bf592d171de942c17238103e52 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 1 Sep 2020 18:15:27 +0100
+Subject: [PATCH] staging/fbtft: Add support for display variants
+
+Display variants are intended as a replacement for the now-deleted
+fbtft_device drivers. Drivers can register additional compatible
+strings with a custom callback that can make the required changes
+to the fbtft_display structure.
+
+Start the ball rolling by adding adafruit18, adafruit18_green and
+sainsmart18 displays.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/staging/fbtft/fb_st7735r.c | 38 +++++++++++++++++++++++++++++-
+ drivers/staging/fbtft/fbtft-core.c | 15 +++++++++++-
+ drivers/staging/fbtft/fbtft.h | 28 +++++++++++++++++-----
+ 3 files changed, 73 insertions(+), 8 deletions(-)
+
+--- a/drivers/staging/fbtft/fb_st7735r.c
++++ b/drivers/staging/fbtft/fb_st7735r.c
+@@ -16,6 +16,10 @@
+ #define DEFAULT_GAMMA "0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10\n" \
+ "0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10"
+
++#define ADAFRUIT18_GAMMA \
++ "02 1c 07 12 37 32 29 2d 29 25 2B 39 00 01 03 10\n" \
++ "03 1d 07 06 2E 2C 29 2D 2E 2E 37 3F 00 00 02 10"
++
+ static const s16 default_init_sequence[] = {
+ -1, MIPI_DCS_SOFT_RESET,
+ -2, 150, /* delay */
+@@ -94,6 +98,14 @@ static void set_addr_win(struct fbtft_pa
+ write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
+ }
+
++static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
++ int xs, int ys, int xe, int ye)
++{
++ write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2);
++ write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1);
++ write_reg(par, 0x2C);
++}
++
+ #define MY BIT(7)
+ #define MX BIT(6)
+ #define MV BIT(5)
+@@ -174,12 +186,36 @@ static struct fbtft_display display = {
+ },
+ };
+
+-FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735r", &display);
++int variant_adafruit18(struct fbtft_display *display)
++{
++ display->gamma = ADAFRUIT18_GAMMA;
++ return 0;
++}
++
++int variant_adafruit18_green(struct fbtft_display *display)
++{
++ display->gamma = ADAFRUIT18_GAMMA;
++ display->fbtftops.set_addr_win = adafruit18_green_tab_set_addr_win;
++ return 0;
++}
++
++FBTFT_REGISTER_DRIVER_START(&display)
++FBTFT_COMPATIBLE("sitronix,st7735r")
++FBTFT_COMPATIBLE("fbtft,sainsmart18")
++FBTFT_VARIANT_COMPATIBLE("fbtft,adafruit18", variant_adafruit18)
++FBTFT_VARIANT_COMPATIBLE("fbtft,adafruit18_green", variant_adafruit18_green)
++FBTFT_REGISTER_DRIVER_END(DRVNAME, &display);
+
+ MODULE_ALIAS("spi:" DRVNAME);
+ MODULE_ALIAS("platform:" DRVNAME);
+ MODULE_ALIAS("spi:st7735r");
+ MODULE_ALIAS("platform:st7735r");
++MODULE_ALIAS("spi:sainsmart18");
++MODULE_ALIAS("platform:sainsmart");
++MODULE_ALIAS("spi:adafruit18");
++MODULE_ALIAS("platform:adafruit18");
++MODULE_ALIAS("spi:adafruit18_green");
++MODULE_ALIAS("platform:adafruit18_green");
+
+ MODULE_DESCRIPTION("FB driver for the ST7735R LCD Controller");
+ MODULE_AUTHOR("Noralf Tronnes");
+--- a/drivers/staging/fbtft/fbtft-core.c
++++ b/drivers/staging/fbtft/fbtft-core.c
+@@ -24,6 +24,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/spinlock.h>
+ #include <linux/of.h>
++#include <linux/of_device.h>
+ #include <video/mipi_display.h>
+
+ #include "fbtft.h"
+@@ -1200,6 +1201,7 @@ static struct fbtft_platform_data *fbtft
+ * @display: Display properties
+ * @sdev: SPI device
+ * @pdev: Platform device
++ * @dt_ids: Compatible string table
+ *
+ * Allocates, initializes and registers a framebuffer
+ *
+@@ -1209,12 +1211,15 @@ static struct fbtft_platform_data *fbtft
+ */
+ int fbtft_probe_common(struct fbtft_display *display,
+ struct spi_device *sdev,
+- struct platform_device *pdev)
++ struct platform_device *pdev,
++ const struct of_device_id *dt_ids)
+ {
+ struct device *dev;
+ struct fb_info *info;
+ struct fbtft_par *par;
+ struct fbtft_platform_data *pdata;
++ const struct of_device_id *match;
++ int (*variant)(struct fbtft_display *);
+ int ret;
+
+ if (sdev)
+@@ -1230,6 +1235,14 @@ int fbtft_probe_common(struct fbtft_disp
+ pdata = fbtft_probe_dt(dev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
++ match = of_match_device(dt_ids, dev);
++ if (match && match->data) {
++ /* apply the variant */
++ variant = match->data;
++ ret = (*variant)(display);
++ if (ret)
++ return ret;
++ }
+ }
+
+ info = fbtft_framebuffer_alloc(display, dev, pdata);
+--- a/drivers/staging/fbtft/fbtft.h
++++ b/drivers/staging/fbtft/fbtft.h
+@@ -251,7 +251,8 @@ void fbtft_register_backlight(struct fbt
+ void fbtft_unregister_backlight(struct fbtft_par *par);
+ int fbtft_init_display(struct fbtft_par *par);
+ int fbtft_probe_common(struct fbtft_display *display, struct spi_device *sdev,
+- struct platform_device *pdev);
++ struct platform_device *pdev,
++ const struct of_device_id *dt_ids);
+ int fbtft_remove_common(struct device *dev, struct fb_info *info);
+
+ /* fbtft-io.c */
+@@ -272,11 +273,13 @@ void fbtft_write_reg8_bus9(struct fbtft_
+ void fbtft_write_reg16_bus8(struct fbtft_par *par, int len, ...);
+ void fbtft_write_reg16_bus16(struct fbtft_par *par, int len, ...);
+
+-#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
++#define FBTFT_REGISTER_DRIVER_START(_display) \
++ \
++static const struct of_device_id dt_ids[]; \
+ \
+ static int fbtft_driver_probe_spi(struct spi_device *spi) \
+ { \
+- return fbtft_probe_common(_display, spi, NULL); \
++ return fbtft_probe_common(_display, spi, NULL, dt_ids); \
+ } \
+ \
+ static int fbtft_driver_remove_spi(struct spi_device *spi) \
+@@ -288,7 +291,7 @@ static int fbtft_driver_remove_spi(struc
+ \
+ static int fbtft_driver_probe_pdev(struct platform_device *pdev) \
+ { \
+- return fbtft_probe_common(_display, NULL, pdev); \
++ return fbtft_probe_common(_display, NULL, pdev, dt_ids); \
+ } \
+ \
+ static int fbtft_driver_remove_pdev(struct platform_device *pdev) \
+@@ -298,8 +301,16 @@ static int fbtft_driver_remove_pdev(stru
+ return fbtft_remove_common(&pdev->dev, info); \
+ } \
+ \
+-static const struct of_device_id dt_ids[] = { \
+- { .compatible = _compatible }, \
++static const struct of_device_id dt_ids[] = {
++
++#define FBTFT_COMPATIBLE(_compatible) \
++ { .compatible = _compatible },
++
++#define FBTFT_VARIANT_COMPATIBLE(_compatible, _variant) \
++ { .compatible = _compatible, .data = _variant },
++
++#define FBTFT_REGISTER_DRIVER_END(_name, _display) \
++ \
+ {}, \
+ }; \
+ \
+@@ -344,6 +355,11 @@ static void __exit fbtft_driver_module_e
+ module_init(fbtft_driver_module_init); \
+ module_exit(fbtft_driver_module_exit);
+
++#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
++ FBTFT_REGISTER_DRIVER_START(_display) \
++ FBTFT_COMPATIBLE(_compatible) \
++ FBTFT_REGISTER_DRIVER_END(_name, _display)
++
+ /* Debug macros */
+
+ /* shorthand debug levels */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0961-overlays-Add-adafruit18-and-sainsmart18-overlays.patch b/target/linux/bcm27xx/patches-5.4/950-0961-overlays-Add-adafruit18-and-sainsmart18-overlays.patch
new file mode 100644
index 0000000000..986ddd49b5
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0961-overlays-Add-adafruit18-and-sainsmart18-overlays.patch
@@ -0,0 +1,169 @@
+From dde4afa87452e8499c611c9a889f4c5f35d9e2bb Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 3 Sep 2020 17:36:00 +0100
+Subject: [PATCH] overlays: Add adafruit18 and sainsmart18 overlays
+
+Add support for three ST7735R-based displays - adafruit18,
+adafruit18_green and sainsmart18.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 2 +
+ arch/arm/boot/dts/overlays/README | 15 ++++++
+ .../boot/dts/overlays/adafruit18-overlay.dts | 49 +++++++++++++++++++
+ .../boot/dts/overlays/sainsmart18-overlay.dts | 47 ++++++++++++++++++
+ 4 files changed, 113 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/adafruit18-overlay.dts
+ create mode 100644 arch/arm/boot/dts/overlays/sainsmart18-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += overlay_ma
+
+ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ act-led.dtbo \
++ adafruit18.dtbo \
+ adau1977-adc.dtbo \
+ adau7002-simple.dtbo \
+ ads1015.dtbo \
+@@ -147,6 +148,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ rpi-tv.dtbo \
+ rpivid-v4l2.dtbo \
+ rra-digidac1-wm8741-audio.dtbo \
++ sainsmart18.dtbo \
+ sc16is750-i2c.dtbo \
+ sc16is752-i2c.dtbo \
+ sc16is752-spi0.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -261,6 +261,14 @@ Params: activelow Set to "
+ REQUIRED
+
+
++Name: adafruit18
++Info: Overlay for the SPI-connected Adafruit 1.8" display (based on the
++ ST7735R chip). It includes support for the "green tab" version.
++Load: dtoverlay=adafruit18,<param>=<val>
++Params: green Use the adafruit18_green variant.
++ rotate Display rotation {0,90,180,270}
++
++
+ Name: adau1977-adc
+ Info: Overlay for activation of ADAU1977 ADC codec over I2C for control
+ and I2S for data.
+@@ -2251,6 +2259,13 @@ Load: dtoverlay=rra-digidac1-wm8741-au
+ Params: <None>
+
+
++Name: sainsmart18
++Info: Overlay for the SPI-connected Sainsmart 1.8" display (based on the
++ ST7735R chip).
++Load: dtoverlay=sainsmart18,<param>=<val>
++Params: rotate Display rotation {0,90,180,270}
++
++
+ 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
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/adafruit18-overlay.dts
+@@ -0,0 +1,49 @@
++/*
++ * Device Tree overlay for Adafruit 1.8" TFT LCD with ST7735R chip 160x128
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2835";
++
++ 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";
++
++ af18: adafruit18@0 {
++ compatible = "fbtft,adafruit18";
++ reg = <0>;
++ pinctrl-names = "default";
++ spi-max-frequency = <40000000>;
++ rotate = <90>;
++ buswidth = <8>;
++ fps = <50>;
++ height = <160>;
++ width = <128>;
++ reset-gpios = <&gpio 25 0>;
++ dc-gpios = <&gpio 24 0>;
++ led-gpios = <&gpio 18 0>;
++ bgr;
++ debug = <0>;
++ };
++ };
++ };
++
++ __overrides__ {
++ green = <&af18>, "compatible=fbtft,adafruit18_green";
++ rotate = <&af18>, "rotate:0";
++ };
++};
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/sainsmart18-overlay.dts
+@@ -0,0 +1,47 @@
++/*
++ * Device Tree overlay for the Sainsmart 1.8" TFT LCD with ST7735R chip 160x128
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2835";
++
++ 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";
++
++ ss18: sainsmart18@0 {
++ compatible = "fbtft,sainsmart18";
++ reg = <0>;
++ pinctrl-names = "default";
++ spi-max-frequency = <40000000>;
++ rotate = <90>;
++ buswidth = <8>;
++ fps = <50>;
++ height = <160>;
++ width = <128>;
++ reset-gpios = <&gpio 25 0>;
++ dc-gpios = <&gpio 24 0>;
++ bgr;
++ debug = <0>;
++ };
++ };
++ };
++
++ __overrides__ {
++ rotate = <&ss18>, "rotate:0";
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-0962-ARM-dts-Limit-BT-modem-baud-rate-on-3B.patch b/target/linux/bcm27xx/patches-5.4/950-0962-ARM-dts-Limit-BT-modem-baud-rate-on-3B.patch
new file mode 100644
index 0000000000..f88cc7b397
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0962-ARM-dts-Limit-BT-modem-baud-rate-on-3B.patch
@@ -0,0 +1,28 @@
+From 27f210c863d3349d41e366fb7573e9dcc0708e3d Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 4 Sep 2020 09:04:29 +0100
+Subject: [PATCH] ARM: dts: Limit BT modem baud rate on 3B
+
+The 3B doesn't have the flow control signals connected to the BT modem,
+which limits the maximum usable baud rate to below 1 Mbaud. Use
+921600 as a relatively safe default value, but the krnbt_baudrate
+parameter can still override it.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
+@@ -117,6 +117,10 @@
+ status = "okay";
+ };
+
++&bt {
++ max-speed = <921600>;
++};
++
+ &spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0963-overlays-Update-i2c0-overlay-to-disable-the-i2c0mux.patch b/target/linux/bcm27xx/patches-5.4/950-0963-overlays-Update-i2c0-overlay-to-disable-the-i2c0mux.patch
new file mode 100644
index 0000000000..3ce5e0bbd3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0963-overlays-Update-i2c0-overlay-to-disable-the-i2c0mux.patch
@@ -0,0 +1,70 @@
+From 2be1e1c949138b40aac6be1e6f761c69e98dcf66 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 3 Sep 2020 14:59:40 +0100
+Subject: [PATCH] overlays: Update i2c0 overlay to disable the
+ i2c0mux.
+
+The i2c0 overlay was assigning pinctrl settings to node i2c0,
+which is now the port@0 output of the mux. That leaves a high
+chance of it colliding with the port@1 output and not doing
+what was intended.
+
+Set the i2c0 overlay to disable i2c0mux, set the pin-ctrl on
+the root i2c controller, and redirect the alias, so overall it
+behaves exactly as before.
+Combining with dtparam=i2c_vc=on is going to cause conflicts,
+so this is noted in the README.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 7 +++++++
+ arch/arm/boot/dts/overlays/i2c0-overlay.dts | 15 ++++++++++++++-
+ 2 files changed, 21 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1354,6 +1354,13 @@ Name: i2c0
+ 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.
++ Do NOT use in conjunction with dtparam=i2c_vc=on. From the 5.4 kernel
++ onwards the base DT includes the use of i2c_mux_pinctrl to expose two
++ muxings of BSC0 - GPIOs 0&1, and whichever combination is used for the
++ camera and display connectors. This overlay disables that mux and
++ configures /dev/i2c0 to point at whichever set of pins is requested.
++ dtparam=i2c_vc=on will try and enable the mux, so combining the two
++ will cause conflicts.
+ Load: dtoverlay=i2c0,<param>=<val>
+ Params: pins_0_1 Use pins 0 and 1 (default)
+ pins_28_29 Use pins 28 and 29
+--- a/arch/arm/boot/dts/overlays/i2c0-overlay.dts
++++ b/arch/arm/boot/dts/overlays/i2c0-overlay.dts
+@@ -5,7 +5,7 @@
+ compatible = "brcm,bcm2835";
+
+ fragment@0 {
+- target = <&i2c0>;
++ target = <&i2c0if>;
+ __overlay__ {
+ status = "okay";
+ pinctrl-0 = <&i2c0_pins>;
+@@ -51,6 +51,19 @@
+ };
+ };
+
++ fragment@6 {
++ target = <&i2c0mux>;
++ __overlay__ {
++ status = "disabled";
++ };
++ };
++
++ fragment@7 {
++ target-path = "/aliases";
++ __overlay__ {
++ i2c0 = "/soc/i2c@7e205000";
++ };
++ };
+ __overrides__ {
+ pins_0_1 = <0>,"+1-2-3-4";
+ pins_28_29 = <0>,"-1+2-3-4";
diff --git a/target/linux/bcm27xx/patches-5.4/950-0964-dt-Remove-duplicate-assignment-for-i2c0-pinctrl-conf.patch b/target/linux/bcm27xx/patches-5.4/950-0964-dt-Remove-duplicate-assignment-for-i2c0-pinctrl-conf.patch
new file mode 100644
index 0000000000..ce3d9b5773
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0964-dt-Remove-duplicate-assignment-for-i2c0-pinctrl-conf.patch
@@ -0,0 +1,155 @@
+From 12bd4eee1bb882417a38c2b5c9790e97725e489d Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 3 Sep 2020 15:12:50 +0100
+Subject: [PATCH] dt: Remove duplicate assignment for i2c0 pinctrl
+ config
+
+The include file bcm283x-rpi-i2c0mux_0_XX.dtsi was setting
+pinctrl-0 on i2c0mux, as were the individual platform DT files.
+
+Remove this duplication and rely on the include file.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 4 ----
+ arch/arm/boot/dts/bcm2708-rpi-b.dts | 4 ----
+ arch/arm/boot/dts/bcm2708-rpi-cm.dts | 4 ----
+ arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 4 ----
+ arch/arm/boot/dts/bcm2708-rpi-zero.dts | 4 ----
+ arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 4 ----
+ arch/arm/boot/dts/bcm2710-rpi-2-b.dts | 4 ----
+ arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 4 ----
+ arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 4 ----
+ arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 4 ----
+ 10 files changed, 40 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
+@@ -73,10 +73,6 @@
+ clock-frequency = <100000>;
+ };
+
+-&i2c0mux {
+- pinctrl-0 = <&i2c0_pins>;
+-};
+-
+ &i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+--- a/arch/arm/boot/dts/bcm2708-rpi-b.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts
+@@ -73,10 +73,6 @@
+ clock-frequency = <100000>;
+ };
+
+-&i2c0mux {
+- pinctrl-0 = <&i2c0_pins>;
+-};
+-
+ &i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+--- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts
+@@ -72,10 +72,6 @@
+ clock-frequency = <100000>;
+ };
+
+-&i2c0mux {
+- pinctrl-0 = <&i2c0_pins>;
+-};
+-
+ &i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+--- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts
+@@ -122,10 +122,6 @@
+ clock-frequency = <100000>;
+ };
+
+-&i2c0mux {
+- pinctrl-0 = <&i2c0_pins>;
+-};
+-
+ &i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+--- a/arch/arm/boot/dts/bcm2708-rpi-zero.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts
+@@ -76,10 +76,6 @@
+ clock-frequency = <100000>;
+ };
+
+-&i2c0mux {
+- pinctrl-0 = <&i2c0_pins>;
+-};
+-
+ &i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+--- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts
++++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts
+@@ -73,10 +73,6 @@
+ clock-frequency = <100000>;
+ };
+
+-&i2c0mux {
+- pinctrl-0 = <&i2c0_pins>;
+-};
+-
+ &i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+--- a/arch/arm/boot/dts/bcm2710-rpi-2-b.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-2-b.dts
+@@ -73,10 +73,6 @@
+ clock-frequency = <100000>;
+ };
+
+-&i2c0mux {
+- pinctrl-0 = <&i2c0_pins>;
+-};
+-
+ &i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts
+@@ -132,10 +132,6 @@
+ clock-frequency = <100000>;
+ };
+
+-&i2c0mux {
+- pinctrl-0 = <&i2c0_pins>;
+-};
+-
+ &i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
+@@ -147,10 +147,6 @@
+ clock-frequency = <100000>;
+ };
+
+-&i2c0mux {
+- pinctrl-0 = <&i2c0_pins>;
+-};
+-
+ &i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+--- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts
+@@ -92,10 +92,6 @@
+ clock-frequency = <100000>;
+ };
+
+-&i2c0mux {
+- pinctrl-0 = <&i2c0_pins>;
+-};
+-
+ &i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0965-overlays-Add-option-for-composite-to-vc4-kms-v3d-pi4.patch b/target/linux/bcm27xx/patches-5.4/950-0965-overlays-Add-option-for-composite-to-vc4-kms-v3d-pi4.patch
new file mode 100644
index 0000000000..0334261bb5
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0965-overlays-Add-option-for-composite-to-vc4-kms-v3d-pi4.patch
@@ -0,0 +1,68 @@
+From bbced22ee3d4c08612bbc35c860d2274e85d5a51 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 27 Aug 2020 18:57:26 +0100
+Subject: [PATCH] overlays: Add option for composite to
+ vc4-kms-v3d-pi4.
+
+Composite is an alternative to HDMI/DPI/DSI on Pi4 as it
+requires very particular clock setups.
+Add an option to vc4-kms-v3d-pi4 to enable composite and
+disable all other graphics outputs.
+
+NB This must be used in conjunction with enable_tvout=1
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 2 ++
+ .../dts/overlays/vc4-kms-v3d-pi4-overlay.dts | 26 +++++++++++++++++++
+ 2 files changed, 28 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -2924,6 +2924,8 @@ Params: cma-256 CMA is 2
+ audio1 Enable or disable audio over HDMI1 (default
+ "on")
+ noaudio Disable all HDMI audio (default "off")
++ composite Enable the composite output (disables all other
++ outputs)
+
+
+ Name: vga666
+--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts
++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts
+@@ -152,9 +152,35 @@
+ };
+ };
+
++ fragment@21 {
++ target = <&pixelvalve3>;
++ __dormant__ {
++ status = "okay";
++ };
++ };
++
++ fragment@22 {
++ target = <&vec>;
++ __dormant__ {
++ status = "okay";
++ };
++ };
++
+ __overrides__ {
+ audio = <0>,"!17";
+ audio1 = <0>,"!18";
+ noaudio = <0>,"=17", <0>,"=18", <0>,"!19";
++ composite = <0>, "!1",
++ <0>, "!2",
++ <0>, "!3",
++ <0>, "!4",
++ <0>, "!6",
++ <0>, "!7",
++ <0>, "!8",
++ <0>, "!9",
++ <0>, "!10",
++ <0>, "!16",
++ <0>, "=21",
++ <0>, "=22";
+ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0966-minor-typo-in-directions.patch b/target/linux/bcm27xx/patches-5.4/950-0966-minor-typo-in-directions.patch
new file mode 100644
index 0000000000..2a649333cf
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0966-minor-typo-in-directions.patch
@@ -0,0 +1,20 @@
+From 8f2841137865fb064ab59fc60b2bd22bbd27078a Mon Sep 17 00:00:00 2001
+From: lsellens <lsellens@gmail.com>
+Date: Mon, 14 Sep 2020 22:35:39 -0500
+Subject: [PATCH] minor typo in directions
+
+---
+ arch/arm/boot/dts/overlays/gpio-fan-overlay.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/gpio-fan-overlay.dts
++++ b/arch/arm/boot/dts/overlays/gpio-fan-overlay.dts
+@@ -31,7 +31,7 @@
+ * - sudo nano /boot/config.txt add "dtoverlay=gpio-fan" or "dtoverlay=gpio-fan,gpiopin=12,temp=45000"
+ * or
+ * - sudo sh -c 'printf "\n# Enable PI GPIO-Fan Default\ndtoverlay=gpio-fan\n" >> /boot/config.txt'
+- * - sudo sh -c 'printf "\n# Enable PI GPIO-Fan Custom\ntoverlay=gpio-fan,gpiopin=12,temp=45000\n" >> /boot/config.txt'
++ * - sudo sh -c 'printf "\n# Enable PI GPIO-Fan Custom\ndtoverlay=gpio-fan,gpiopin=12,temp=45000\n" >> /boot/config.txt'
+ *
+ */
+ /dts-v1/;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0967-overlays-Regenerate-upstream-pi4-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0967-overlays-Regenerate-upstream-pi4-overlay.patch
new file mode 100644
index 0000000000..c025aa2735
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0967-overlays-Regenerate-upstream-pi4-overlay.patch
@@ -0,0 +1,31 @@
+From b1345dbdf08ded4350233bc95925647d01e936f8 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 14 Sep 2020 15:49:38 +0100
+Subject: [PATCH] overlays: Regenerate upstream-pi4 overlay
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts
++++ b/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts
+@@ -134,6 +134,18 @@
+ };
+ };
+ fragment@21 {
++ target = <&pixelvalve3>;
++ __dormant__ {
++ status = "okay";
++ };
++ };
++ fragment@22 {
++ target = <&vec>;
++ __dormant__ {
++ status = "okay";
++ };
++ };
++ fragment@23 {
+ target = <&usb>;
+ #address-cells = <1>;
+ #size-cells = <1>;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0968-overlays-Add-parameters-to-adafruit18-sainsmart18.patch b/target/linux/bcm27xx/patches-5.4/950-0968-overlays-Add-parameters-to-adafruit18-sainsmart18.patch
new file mode 100644
index 0000000000..99ef611fe3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0968-overlays-Add-parameters-to-adafruit18-sainsmart18.patch
@@ -0,0 +1,94 @@
+From 9249fb1ac6b8bfcc0056fe2a871d4965b774c667 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 14 Sep 2020 15:48:16 +0100
+Subject: [PATCH] overlays: Add parameters to adafruit18, sainsmart18
+
+Also fix polarity of the reset GPIO.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 13 +++++++++++++
+ arch/arm/boot/dts/overlays/adafruit18-overlay.dts | 11 +++++++++--
+ arch/arm/boot/dts/overlays/sainsmart18-overlay.dts | 10 ++++++++--
+ 3 files changed, 30 insertions(+), 4 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -267,6 +267,13 @@ Info: Overlay for the SPI-connected Ad
+ Load: dtoverlay=adafruit18,<param>=<val>
+ Params: green Use the adafruit18_green variant.
+ rotate Display rotation {0,90,180,270}
++ speed SPI bus speed in Hz (default 4000000)
++ fps Display frame rate in Hz
++ bgr Enable BGR mode (default on)
++ debug Debug output level {0-7}
++ dc_pin GPIO pin for D/C (default 24)
++ reset_pin GPIO pin for RESET (default 25)
++ led_pin GPIO used to control backlight (default 18)
+
+
+ Name: adau1977-adc
+@@ -2271,6 +2278,12 @@ Info: Overlay for the SPI-connected Sa
+ ST7735R chip).
+ Load: dtoverlay=sainsmart18,<param>=<val>
+ Params: rotate Display rotation {0,90,180,270}
++ speed SPI bus speed in Hz (default 4000000)
++ fps Display frame rate in Hz
++ bgr Enable BGR mode (default on)
++ debug Debug output level {0-7}
++ dc_pin GPIO pin for D/C (default 24)
++ reset_pin GPIO pin for RESET (default 25)
+
+
+ Name: sc16is750-i2c
+--- a/arch/arm/boot/dts/overlays/adafruit18-overlay.dts
++++ b/arch/arm/boot/dts/overlays/adafruit18-overlay.dts
+@@ -33,7 +33,7 @@
+ fps = <50>;
+ height = <160>;
+ width = <128>;
+- reset-gpios = <&gpio 25 0>;
++ reset-gpios = <&gpio 25 1>;
+ dc-gpios = <&gpio 24 0>;
+ led-gpios = <&gpio 18 0>;
+ bgr;
+@@ -44,6 +44,13 @@
+
+ __overrides__ {
+ green = <&af18>, "compatible=fbtft,adafruit18_green";
+- rotate = <&af18>, "rotate:0";
++ speed = <&af18>,"spi-max-frequency:0";
++ rotate = <&af18>,"rotate:0";
++ fps = <&af18>,"fps:0";
++ bgr = <&af18>,"bgr?";
++ debug = <&af18>,"debug:0";
++ dc_pin = <&af18>,"dc-gpios:4";
++ reset_pin = <&af18>,"reset-gpios:4";
++ led_pin = <&af18>,"led-gpios:4";
+ };
+ };
+--- a/arch/arm/boot/dts/overlays/sainsmart18-overlay.dts
++++ b/arch/arm/boot/dts/overlays/sainsmart18-overlay.dts
+@@ -33,7 +33,7 @@
+ fps = <50>;
+ height = <160>;
+ width = <128>;
+- reset-gpios = <&gpio 25 0>;
++ reset-gpios = <&gpio 25 1>;
+ dc-gpios = <&gpio 24 0>;
+ bgr;
+ debug = <0>;
+@@ -42,6 +42,12 @@
+ };
+
+ __overrides__ {
+- rotate = <&ss18>, "rotate:0";
++ speed = <&ss18>,"spi-max-frequency:0";
++ rotate = <&ss18>,"rotate:0";
++ fps = <&ss18>,"fps:0";
++ bgr = <&ss18>,"bgr?";
++ debug = <&ss18>,"debug:0";
++ dc_pin = <&ss18>,"dc-gpios:4";
++ reset_pin = <&ss18>,"reset-gpios:4";
+ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0969-rpivid_h265-Fix-width-height-typo.patch b/target/linux/bcm27xx/patches-5.4/950-0969-rpivid_h265-Fix-width-height-typo.patch
new file mode 100644
index 0000000000..3aeb6e41ca
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0969-rpivid_h265-Fix-width-height-typo.patch
@@ -0,0 +1,21 @@
+From 3effc5ad6a017d4523158e04d2543a42def1744f Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Mon, 21 Sep 2020 14:02:44 +0100
+Subject: [PATCH] rpivid_h265: Fix width/height typo
+
+Signed-off-by: popcornmix <popcornmix@gmail.com>
+---
+ drivers/staging/media/rpivid/rpivid_h265.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/media/rpivid/rpivid_h265.c
++++ b/drivers/staging/media/rpivid/rpivid_h265.c
+@@ -2178,7 +2178,7 @@ static int rpivid_h265_start(struct rpiv
+ if (w > 4096)
+ w = 4096;
+ if (h == 0)
+- w = 1088;
++ h = 1088;
+ if (h > 4096)
+ h = 4096;
+ wxh = w * h;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0970-overlays-Add-extra-CMA-sizes-up-to-512M.patch b/target/linux/bcm27xx/patches-5.4/950-0970-overlays-Add-extra-CMA-sizes-up-to-512M.patch
new file mode 100644
index 0000000000..b9d46ac8b3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0970-overlays-Add-extra-CMA-sizes-up-to-512M.patch
@@ -0,0 +1,78 @@
+From 43d90a5beafa788c629c41a22623d82c10a9bbb9 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 21 Sep 2020 22:00:10 +0100
+Subject: [PATCH] overlays: Add extra CMA sizes (up to 512M)
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 24 ++++++++++++++++++----
+ arch/arm/boot/dts/overlays/cma-overlay.dts | 4 ++++
+ 2 files changed, 24 insertions(+), 4 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -582,7 +582,11 @@ Name: cma
+ Info: Set custom CMA sizes, only use if you know what you are doing, might
+ clash with other overlays like vc4-fkms-v3d and vc4-kms-v3d.
+ Load: dtoverlay=cma,<param>=<val>
+-Params: cma-256 CMA is 256MB (needs 1GB)
++Params: cma-512 CMA is 512MB (needs 1GB)
++ cma-448 CMA is 448MB (needs 1GB)
++ cma-384 CMA is 384MB (needs 1GB)
++ cma-320 CMA is 320MB (needs 1GB)
++ cma-256 CMA is 256MB (needs 1GB)
+ cma-192 CMA is 192MB (needs 1GB)
+ cma-128 CMA is 128MB
+ cma-96 CMA is 96MB
+@@ -2892,7 +2896,11 @@ 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,<param>
+-Params: cma-256 CMA is 256MB (needs 1GB)
++Params: cma-512 CMA is 512MB (needs 1GB)
++ cma-448 CMA is 448MB (needs 1GB)
++ cma-384 CMA is 384MB (needs 1GB)
++ cma-320 CMA is 320MB (needs 1GB)
++ cma-256 CMA is 256MB (needs 1GB)
+ cma-192 CMA is 192MB (needs 1GB)
+ cma-128 CMA is 128MB
+ cma-96 CMA is 96MB
+@@ -2911,7 +2919,11 @@ Params: <None>
+ Name: vc4-kms-v3d
+ Info: Enable Eric Anholt's DRM VC4 HDMI/HVS/V3D driver.
+ Load: dtoverlay=vc4-kms-v3d,<param>
+-Params: cma-256 CMA is 256MB (needs 1GB)
++Params: cma-512 CMA is 512MB (needs 1GB)
++ cma-448 CMA is 448MB (needs 1GB)
++ cma-384 CMA is 384MB (needs 1GB)
++ cma-320 CMA is 320MB (needs 1GB)
++ cma-256 CMA is 256MB (needs 1GB)
+ cma-192 CMA is 192MB (needs 1GB)
+ cma-128 CMA is 128MB
+ cma-96 CMA is 96MB
+@@ -2925,7 +2937,11 @@ Params: cma-256 CMA is 2
+ Name: vc4-kms-v3d-pi4
+ Info: Enable Eric Anholt's DRM VC4 HDMI/HVS/V3D driver for Pi4.
+ Load: dtoverlay=vc4-kms-v3d-pi4,<param>
+-Params: cma-256 CMA is 256MB
++Params: cma-512 CMA is 512MB
++ cma-448 CMA is 448MB
++ cma-384 CMA is 384MB
++ cma-320 CMA is 320MB
++ cma-256 CMA is 256MB
+ cma-192 CMA is 192MB
+ cma-128 CMA is 128MB
+ cma-96 CMA is 96MB
+--- a/arch/arm/boot/dts/overlays/cma-overlay.dts
++++ b/arch/arm/boot/dts/overlays/cma-overlay.dts
+@@ -21,6 +21,10 @@
+ };
+
+ __overrides__ {
++ cma-512 = <&frag0>,"size:0=",<0x20000000>;
++ cma-448 = <&frag0>,"size:0=",<0x1c000000>;
++ cma-384 = <&frag0>,"size:0=",<0x18000000>;
++ cma-320 = <&frag0>,"size:0=",<0x14000000>;
+ cma-256 = <&frag0>,"size:0=",<0x10000000>;
+ cma-192 = <&frag0>,"size:0=",<0xC000000>;
+ cma-128 = <&frag0>,"size:0=",<0x8000000>;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0971-overlays-Add-note-to-BCM2711-overlays.patch b/target/linux/bcm27xx/patches-5.4/950-0971-overlays-Add-note-to-BCM2711-overlays.patch
new file mode 100644
index 0000000000..3cf76d0934
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0971-overlays-Add-note-to-BCM2711-overlays.patch
@@ -0,0 +1,150 @@
+From b2e311257e8c06f5d39004515c4adb65bb4fad3f Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 21 Sep 2020 22:09:40 +0100
+Subject: [PATCH] overlays: Add note to BCM2711 overlays
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 32 +++++++++++++++----------------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1403,7 +1403,7 @@ Load: <Deprecated>
+
+
+ Name: i2c3
+-Info: Enable the i2c3 bus
++Info: Enable the i2c3 bus. BCM2711 only.
+ Load: dtoverlay=i2c3,<param>
+ Params: pins_2_3 Use GPIOs 2 and 3
+ pins_4_5 Use GPIOs 4 and 5 (default)
+@@ -1412,7 +1412,7 @@ Params: pins_2_3 Use GPIO
+
+
+ Name: i2c4
+-Info: Enable the i2c4 bus
++Info: Enable the i2c4 bus. BCM2711 only.
+ Load: dtoverlay=i2c4,<param>
+ Params: pins_6_7 Use GPIOs 6 and 7
+ pins_8_9 Use GPIOs 8 and 9 (default)
+@@ -1421,7 +1421,7 @@ Params: pins_6_7 Use GPIO
+
+
+ Name: i2c5
+-Info: Enable the i2c5 bus
++Info: Enable the i2c5 bus. BCM2711 only.
+ Load: dtoverlay=i2c5,<param>
+ Params: pins_10_11 Use GPIOs 10 and 11
+ pins_12_13 Use GPIOs 12 and 13 (default)
+@@ -1430,7 +1430,7 @@ Params: pins_10_11 Use GPIO
+
+
+ Name: i2c6
+-Info: Enable the i2c6 bus
++Info: Enable the i2c6 bus. BCM2711 only.
+ Load: dtoverlay=i2c6,<param>
+ Params: pins_0_1 Use GPIOs 0 and 1
+ pins_22_23 Use GPIOs 22 and 23 (default)
+@@ -2582,7 +2582,7 @@ Params: cs0_pin GPIO pin
+ Name: spi3-1cs
+ Info: Enables spi3 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.
++ creation are configurable. BCM2711 only.
+ Load: dtoverlay=spi3-1cs,<param>=<val>
+ Params: cs0_pin GPIO pin for CS0 (default 0 - BCM SPI3_CE0).
+ cs0_spidev Set to 'off' to prevent the creation of a
+@@ -2593,7 +2593,7 @@ Params: cs0_pin GPIO pin
+ Name: spi3-2cs
+ Info: Enables spi3 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.
++ creation are configurable. BCM2711 only.
+ Load: dtoverlay=spi3-2cs,<param>=<val>
+ Params: cs0_pin GPIO pin for CS0 (default 0 - BCM SPI3_CE0).
+ cs1_pin GPIO pin for CS1 (default 24 - BCM SPI3_CE1).
+@@ -2608,7 +2608,7 @@ Params: cs0_pin GPIO pin
+ Name: spi4-1cs
+ Info: Enables spi4 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.
++ creation are configurable. BCM2711 only.
+ Load: dtoverlay=spi4-1cs,<param>=<val>
+ Params: cs0_pin GPIO pin for CS0 (default 4 - BCM SPI4_CE0).
+ cs0_spidev Set to 'off' to prevent the creation of a
+@@ -2619,7 +2619,7 @@ Params: cs0_pin GPIO pin
+ Name: spi4-2cs
+ Info: Enables spi4 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.
++ creation are configurable. BCM2711 only.
+ Load: dtoverlay=spi4-2cs,<param>=<val>
+ Params: cs0_pin GPIO pin for CS0 (default 4 - BCM SPI4_CE0).
+ cs1_pin GPIO pin for CS1 (default 25 - BCM SPI4_CE1).
+@@ -2634,7 +2634,7 @@ Params: cs0_pin GPIO pin
+ Name: spi5-1cs
+ Info: Enables spi5 with a single chip select (CS) line and associated spidev
+ dev node. The gpio pin numbers for the CS lines and spidev device node
+- creation are configurable.
++ creation are configurable. BCM2711 only.
+ Load: dtoverlay=spi5-1cs,<param>=<val>
+ Params: cs0_pin GPIO pin for CS0 (default 12 - BCM SPI5_CE0).
+ cs0_spidev Set to 'off' to prevent the creation of a
+@@ -2645,7 +2645,7 @@ Params: cs0_pin GPIO pin
+ Name: spi5-2cs
+ Info: Enables spi5 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.
++ creation are configurable. BCM2711 only.
+ Load: dtoverlay=spi5-2cs,<param>=<val>
+ Params: cs0_pin GPIO pin for CS0 (default 12 - BCM SPI5_CE0).
+ cs1_pin GPIO pin for CS1 (default 26 - BCM SPI5_CE1).
+@@ -2660,7 +2660,7 @@ Params: cs0_pin GPIO pin
+ Name: spi6-1cs
+ Info: Enables spi6 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.
++ creation are configurable. BCM2711 only.
+ Load: dtoverlay=spi6-1cs,<param>=<val>
+ Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI6_CE0).
+ cs0_spidev Set to 'off' to prevent the creation of a
+@@ -2671,7 +2671,7 @@ Params: cs0_pin GPIO pin
+ Name: spi6-2cs
+ Info: Enables spi6 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.
++ creation are configurable. BCM2711 only.
+ Load: dtoverlay=spi6-2cs,<param>=<val>
+ Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI6_CE0).
+ cs1_pin GPIO pin for CS1 (default 27 - BCM SPI6_CE1).
+@@ -2843,25 +2843,25 @@ Params: txd1_pin GPIO pin
+
+
+ Name: uart2
+-Info: Enable uart 2 on GPIOs 0-3
++Info: Enable uart 2 on GPIOs 0-3. BCM2711 only.
+ Load: dtoverlay=uart2,<param>
+ Params: ctsrts Enable CTS/RTS on GPIOs 2-3 (default off)
+
+
+ Name: uart3
+-Info: Enable uart 3 on GPIOs 4-7
++Info: Enable uart 3 on GPIOs 4-7. BCM2711 only.
+ Load: dtoverlay=uart3,<param>
+ Params: ctsrts Enable CTS/RTS on GPIOs 6-7 (default off)
+
+
+ Name: uart4
+-Info: Enable uart 4 on GPIOs 8-11
++Info: Enable uart 4 on GPIOs 8-11. BCM2711 only.
+ Load: dtoverlay=uart4,<param>
+ Params: ctsrts Enable CTS/RTS on GPIOs 10-11 (default off)
+
+
+ Name: uart5
+-Info: Enable uart 5 on GPIOs 12-15
++Info: Enable uart 5 on GPIOs 12-15. BCM2711 only.
+ Load: dtoverlay=uart5,<param>
+ Params: ctsrts Enable CTS/RTS on GPIOs 14-15 (default off)
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0972-overlays-adafruit18-sainsmart18-default-bgr-to-off.patch b/target/linux/bcm27xx/patches-5.4/950-0972-overlays-adafruit18-sainsmart18-default-bgr-to-off.patch
new file mode 100644
index 0000000000..70e11f46ab
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0972-overlays-adafruit18-sainsmart18-default-bgr-to-off.patch
@@ -0,0 +1,53 @@
+From b9801549748233e71a5c0dd76351e02a125505b4 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 21 Sep 2020 20:45:46 +0100
+Subject: [PATCH] overlays: adafruit18,sainsmart18: default bgr to
+ off
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 4 ++--
+ arch/arm/boot/dts/overlays/adafruit18-overlay.dts | 1 -
+ arch/arm/boot/dts/overlays/sainsmart18-overlay.dts | 1 -
+ 3 files changed, 2 insertions(+), 4 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -269,7 +269,7 @@ Params: green Use the
+ rotate Display rotation {0,90,180,270}
+ speed SPI bus speed in Hz (default 4000000)
+ fps Display frame rate in Hz
+- bgr Enable BGR mode (default on)
++ bgr Enable BGR mode (default off)
+ debug Debug output level {0-7}
+ dc_pin GPIO pin for D/C (default 24)
+ reset_pin GPIO pin for RESET (default 25)
+@@ -2284,7 +2284,7 @@ Load: dtoverlay=sainsmart18,<param>=<v
+ Params: rotate Display rotation {0,90,180,270}
+ speed SPI bus speed in Hz (default 4000000)
+ fps Display frame rate in Hz
+- bgr Enable BGR mode (default on)
++ bgr Enable BGR mode (default off)
+ debug Debug output level {0-7}
+ dc_pin GPIO pin for D/C (default 24)
+ reset_pin GPIO pin for RESET (default 25)
+--- a/arch/arm/boot/dts/overlays/adafruit18-overlay.dts
++++ b/arch/arm/boot/dts/overlays/adafruit18-overlay.dts
+@@ -36,7 +36,6 @@
+ reset-gpios = <&gpio 25 1>;
+ dc-gpios = <&gpio 24 0>;
+ led-gpios = <&gpio 18 0>;
+- bgr;
+ debug = <0>;
+ };
+ };
+--- a/arch/arm/boot/dts/overlays/sainsmart18-overlay.dts
++++ b/arch/arm/boot/dts/overlays/sainsmart18-overlay.dts
+@@ -35,7 +35,6 @@
+ width = <128>;
+ reset-gpios = <&gpio 25 1>;
+ dc-gpios = <&gpio 24 0>;
+- bgr;
+ debug = <0>;
+ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0973-net-bcmgenet-Reset-RBUF-on-first-open.patch b/target/linux/bcm27xx/patches-5.4/950-0973-net-bcmgenet-Reset-RBUF-on-first-open.patch
new file mode 100644
index 0000000000..b7f0ce0cad
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0973-net-bcmgenet-Reset-RBUF-on-first-open.patch
@@ -0,0 +1,70 @@
+From 507c4d749a1bbc3eb5c364dda61ac6bf95026cf1 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 25 Sep 2020 15:07:23 +0100
+Subject: [PATCH] net: bcmgenet: Reset RBUF on first open
+
+If the RBUF logic is not reset when the kernel starts then there
+may be some data left over from any network boot loader. If the
+64-byte packet headers are enabled then this can be fatal.
+
+Extend bcmgenet_dma_disable to do perform the reset, but not when
+called from bcmgenet_resume in order to preserve a wake packet.
+
+N.B. This different handling of resume is just based on a hunch -
+why else wouldn't one reset the RBUF as well as the TBUF? If this
+isn't the case then it's easy to change the patch to make the RBUF
+reset unconditional.
+
+See: https://github.com/raspberrypi/linux/issues/3850
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/net/ethernet/broadcom/genet/bcmgenet.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+@@ -2790,7 +2790,7 @@ static void bcmgenet_set_hw_addr(struct
+ }
+
+ /* Returns a reusable dma control register value */
+-static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv)
++static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv, bool flush_rx)
+ {
+ u32 reg;
+ u32 dma_ctrl;
+@@ -2809,6 +2809,14 @@ static u32 bcmgenet_dma_disable(struct b
+ udelay(10);
+ bcmgenet_umac_writel(priv, 0, UMAC_TX_FLUSH);
+
++ if (flush_rx) {
++ reg = bcmgenet_rbuf_ctrl_get(priv);
++ bcmgenet_rbuf_ctrl_set(priv, reg | BIT(0));
++ udelay(10);
++ bcmgenet_rbuf_ctrl_set(priv, reg);
++ udelay(10);
++ }
++
+ return dma_ctrl;
+ }
+
+@@ -2910,8 +2918,8 @@ static int bcmgenet_open(struct net_devi
+ bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
+ }
+
+- /* Disable RX/TX DMA and flush TX queues */
+- dma_ctrl = bcmgenet_dma_disable(priv);
++ /* Disable RX/TX DMA and flush TX and RX queues */
++ dma_ctrl = bcmgenet_dma_disable(priv, true);
+
+ /* Reinitialize TDMA and RDMA and SW housekeeping */
+ ret = bcmgenet_init_dma(priv);
+@@ -3671,7 +3679,7 @@ static int bcmgenet_resume(struct device
+ bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC);
+
+ /* Disable RX/TX DMA and flush TX queues */
+- dma_ctrl = bcmgenet_dma_disable(priv);
++ dma_ctrl = bcmgenet_dma_disable(priv, false);
+
+ /* Reinitialize TDMA and RDMA and SW housekeeping */
+ ret = bcmgenet_init_dma(priv);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0974-ASoC-cs42xx8-Only-define-cs42xx8_of_match-once.patch b/target/linux/bcm27xx/patches-5.4/950-0974-ASoC-cs42xx8-Only-define-cs42xx8_of_match-once.patch
new file mode 100644
index 0000000000..1c8e4d6699
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0974-ASoC-cs42xx8-Only-define-cs42xx8_of_match-once.patch
@@ -0,0 +1,43 @@
+From e84f00c45ad064f1503d2eb03d7600e59744f0e6 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 29 Sep 2020 15:03:34 +0100
+Subject: [PATCH] ASoC: cs42xx8: Only define cs42xx8_of_match once
+
+cs42xx8.c exports cs42xx8_of_match, so there's no need to redefine it
+in cs42xx8-i2c.c - doing so breaks linking when loadable module
+support is disabled. It would be tidy to use the exported match table
+in cs42xx8.c's of_match_table member, but an imported symbol can't be
+used in a module's MODULE_DEVICE_TABLE declaration. Instead, rename
+the duplicated declarations so as not to clash.
+
+See: https://github.com/raspberrypi/linux/issues/3873
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ sound/soc/codecs/cs42xx8-i2c.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/sound/soc/codecs/cs42xx8-i2c.c
++++ b/sound/soc/codecs/cs42xx8-i2c.c
+@@ -45,18 +45,18 @@ static struct i2c_device_id cs42xx8_i2c_
+ };
+ MODULE_DEVICE_TABLE(i2c, cs42xx8_i2c_id);
+
+-const struct of_device_id cs42xx8_of_match[] = {
++const struct of_device_id cs42xx8_i2c_of_match[] = {
+ { .compatible = "cirrus,cs42448", .data = &cs42448_data, },
+ { .compatible = "cirrus,cs42888", .data = &cs42888_data, },
+ { /* sentinel */ }
+ };
+-MODULE_DEVICE_TABLE(of, cs42xx8_of_match);
++MODULE_DEVICE_TABLE(of, cs42xx8_i2c_of_match);
+
+ static struct i2c_driver cs42xx8_i2c_driver = {
+ .driver = {
+ .name = "cs42xx8",
+ .pm = &cs42xx8_pm,
+- .of_match_table = cs42xx8_of_match,
++ .of_match_table = cs42xx8_i2c_of_match,
+ },
+ .probe = cs42xx8_i2c_probe,
+ .remove = cs42xx8_i2c_remove,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0975-staging-bcm2835-codec-Use-a-define-the-completion-ti.patch b/target/linux/bcm27xx/patches-5.4/950-0975-staging-bcm2835-codec-Use-a-define-the-completion-ti.patch
new file mode 100644
index 0000000000..f85baf297c
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0975-staging-bcm2835-codec-Use-a-define-the-completion-ti.patch
@@ -0,0 +1,35 @@
+From 7ad713e695d67b78b3cb69927d099a29593444b1 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 30 Sep 2020 12:12:32 +0100
+Subject: [PATCH] staging: bcm2835-codec: Use a define the completion
+ timeout
+
+Hiding a use of "HZ" as a timeout is a little nasty.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+@@ -89,6 +89,9 @@ static const char * const components[] =
+ "ril.isp",
+ };
+
++/* Timeout for stop_streaming to allow all buffers to return */
++#define COMPLETE_TIMEOUT (2 * HZ)
++
+ #define MIN_W 32
+ #define MIN_H 32
+ #define MAX_W 1920
+@@ -2366,7 +2369,8 @@ static void bcm2835_codec_stop_streaming
+ while (atomic_read(&port->buffers_with_vpu)) {
+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Waiting for buffers to be returned - %d outstanding\n",
+ __func__, atomic_read(&port->buffers_with_vpu));
+- ret = wait_for_completion_timeout(&ctx->frame_cmplt, HZ);
++ ret = wait_for_completion_timeout(&ctx->frame_cmplt,
++ COMPLETE_TIMEOUT);
+ if (ret <= 0) {
+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n",
+ __func__,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0976-staging-bcm2835-codec-Correct-buffer-number-change-o.patch b/target/linux/bcm27xx/patches-5.4/950-0976-staging-bcm2835-codec-Correct-buffer-number-change-o.patch
new file mode 100644
index 0000000000..c0193cb2e7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0976-staging-bcm2835-codec-Correct-buffer-number-change-o.patch
@@ -0,0 +1,30 @@
+From 96f4d69496b483b8eb65dc4602d5cb96844f6647 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 30 Sep 2020 12:13:44 +0100
+Subject: [PATCH] staging: bcm2835-codec: Correct buffer number
+ change on start streaming
+
+"cac8c90 staging: vc04_service: codec: Allow start_streaming to update
+the buffernum" allowed the number of buffers configured to be decreased
+as well as increased, but there is no requirement for all buffers to
+have been queued when start_streaming is called.
+
+Only allow increasing the buffernum.
+
+Fixes: "cac8c90 staging: vc04_service: codec: Allow start_streaming to update the buffernum"
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+@@ -2290,7 +2290,7 @@ static int bcm2835_codec_start_streaming
+ if (count < port->minimum_buffer.num)
+ count = port->minimum_buffer.num;
+
+- if (port->current_buffer.num != count + 1) {
++ if (port->current_buffer.num < count + 1) {
+ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, buffer count changed %u to %u\n",
+ __func__, ctx, port->current_buffer.num, count + 1);
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0977-USB-gadget-f_hid-avoid-crashes-and-log-spam.patch b/target/linux/bcm27xx/patches-5.4/950-0977-USB-gadget-f_hid-avoid-crashes-and-log-spam.patch
new file mode 100644
index 0000000000..1fe685cd99
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0977-USB-gadget-f_hid-avoid-crashes-and-log-spam.patch
@@ -0,0 +1,56 @@
+From 22198e801db7542c59098a75bdab120bcbc42652 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 30 Sep 2020 19:23:43 +0100
+Subject: [PATCH] USB: gadget: f_hid: avoid crashes and log spam
+
+Disconnecting and reconnecting the USB cable can lead to crashes and a
+variety of kernel log spam. Try to fix or minimise both.
+
+See: https://github.com/raspberrypi/linux/issues/3870
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/usb/gadget/function/f_hid.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -344,6 +344,11 @@ static ssize_t f_hidg_write(struct file
+
+ spin_lock_irqsave(&hidg->write_spinlock, flags);
+
++ if (!hidg->req) {
++ spin_unlock_irqrestore(&hidg->write_spinlock, flags);
++ return -ESHUTDOWN;
++ }
++
+ #define WRITE_COND (!hidg->write_pending)
+ try_again:
+ /* write queue */
+@@ -364,7 +369,13 @@ try_again:
+ count = min_t(unsigned, count, hidg->report_length);
+
+ spin_unlock_irqrestore(&hidg->write_spinlock, flags);
+- status = copy_from_user(req->buf, buffer, count);
++ if (req) {
++ status = copy_from_user(req->buf, buffer, count);
++ } else {
++ ERROR(hidg->func.config->cdev, "hidg->req is NULL\n");
++ status = -ESHUTDOWN;
++ goto release_write_pending;
++ }
+
+ if (status != 0) {
+ ERROR(hidg->func.config->cdev,
+@@ -393,6 +404,11 @@ try_again:
+
+ spin_unlock_irqrestore(&hidg->write_spinlock, flags);
+
++ if (!hidg->in_ep->enabled) {
++ ERROR(hidg->func.config->cdev, "in_ep is disabled\n");
++ status = -ESHUTDOWN;
++ goto release_write_pending;
++ }
+ status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC);
+ if (status < 0) {
+ ERROR(hidg->func.config->cdev,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0978-Update-hy28b-overlay.dts.patch b/target/linux/bcm27xx/patches-5.4/950-0978-Update-hy28b-overlay.dts.patch
new file mode 100644
index 0000000000..48efb5adc2
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0978-Update-hy28b-overlay.dts.patch
@@ -0,0 +1,21 @@
+From 8c997be099769362cb201d360ad57b639e799e9e Mon Sep 17 00:00:00 2001
+From: newbloke82 <39644602+newbloke82@users.noreply.github.com>
+Date: Thu, 1 Oct 2020 19:16:35 +0200
+Subject: [PATCH] Update hy28b-overlay.dts
+
+My hy28b TFT stopped working on upgrade to 5.4 kernel. I had a whitescreen but no obvious errors when using 'sudo vcdbg log msg' or 'dmesg'. Both /dev/fb0 and /dev/fb1 were present. Followed this article on waveshare32b that 'reset_gpios needed to be 0 0 1 instead of 0 0 0' (https://forum.armbian.com/topic/13233-any-clues-for-the-creation-of-a-dtoverlay-for-fbtft-on-54y/). I applied a similar change to this dts file and compiled a new dtbo: 'dtc -O dtb -o hy28b.dtbo hy28b-overlay.dts'. Fixed my issue - may help others? I got from the 5.4 upgrade thread that other tft users are having issues with small tfts... https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=269769&p=1706597&hilit=gpio#p1706597
+---
+ arch/arm/boot/dts/overlays/hy28b-overlay.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/hy28b-overlay.dts
++++ b/arch/arm/boot/dts/overlays/hy28b-overlay.dts
+@@ -61,7 +61,7 @@
+ fps = <50>;
+ buswidth = <8>;
+ startbyte = <0x70>;
+- reset-gpios = <&gpio 25 0>;
++ reset-gpios = <&gpio 25 1>;
+ 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";
diff --git a/target/linux/bcm27xx/patches-5.4/950-0979-overlays-Update-display-GPIO-declarations.patch b/target/linux/bcm27xx/patches-5.4/950-0979-overlays-Update-display-GPIO-declarations.patch
new file mode 100644
index 0000000000..9b3cc5d64e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0979-overlays-Update-display-GPIO-declarations.patch
@@ -0,0 +1,170 @@
+From 0e81e4689a34e3f413ef403e0d801970d324c5b2 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 2 Oct 2020 10:06:49 +0100
+Subject: [PATCH] overlays: Update display GPIO declarations
+
+The 5.4 kernel changes the way a number of display drivers use GPIOs.
+That change has exposed flaws/broken a number of display overlays, so
+after a trickle of single-display patches this is a best-guess attempt
+to fix the remainder. As none of these changes have been tested on real
+displays there is a possibility that this either doesn't fix the
+problem or even breaks something that was working - apologies if that
+is the case.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/goodix-overlay.dts | 2 +-
+ arch/arm/boot/dts/overlays/hy28a-overlay.dts | 2 +-
+ arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts | 2 +-
+ arch/arm/boot/dts/overlays/media-center-overlay.dts | 6 +++---
+ arch/arm/boot/dts/overlays/mz61581-overlay.dts | 2 +-
+ arch/arm/boot/dts/overlays/piscreen-overlay.dts | 4 ++--
+ arch/arm/boot/dts/overlays/piscreen2r-overlay.dts | 4 ++--
+ arch/arm/boot/dts/overlays/sh1106-spi-overlay.dts | 2 +-
+ arch/arm/boot/dts/overlays/ssd1306-spi-overlay.dts | 2 +-
+ arch/arm/boot/dts/overlays/ssd1351-spi-overlay.dts | 2 +-
+ arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 4 ++--
+ 11 files changed, 16 insertions(+), 16 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/goodix-overlay.dts
++++ b/arch/arm/boot/dts/overlays/goodix-overlay.dts
+@@ -31,7 +31,7 @@
+ 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
++ reset-gpios = <&gpio 17 1>; // Pin11 on GPIO header
+ };
+ };
+ };
+--- a/arch/arm/boot/dts/overlays/hy28a-overlay.dts
++++ b/arch/arm/boot/dts/overlays/hy28a-overlay.dts
+@@ -61,7 +61,7 @@
+ fps = <50>;
+ buswidth = <8>;
+ startbyte = <0x70>;
+- reset-gpios = <&gpio 25 0>;
++ reset-gpios = <&gpio 25 1>;
+ led-gpios = <&gpio 18 1>;
+ debug = <0>;
+ };
+--- a/arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts
++++ b/arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts
+@@ -61,7 +61,7 @@
+ fps = <50>;
+ buswidth = <8>;
+ startbyte = <0x70>;
+- reset-gpios = <&gpio 25 0>;
++ reset-gpios = <&gpio 25 1>;
+ led-gpios = <&gpio 18 1>;
+
+ init = <0x10000e5 0x78F0
+--- a/arch/arm/boot/dts/overlays/media-center-overlay.dts
++++ b/arch/arm/boot/dts/overlays/media-center-overlay.dts
+@@ -53,9 +53,9 @@
+ bgr;
+ fps = <30>;
+ buswidth = <8>;
+- reset-gpios = <&gpio 23 0>;
++ reset-gpios = <&gpio 23 1>;
+ dc-gpios = <&gpio 24 0>;
+- led-gpios = <&gpio 12 1>;
++ led-gpios = <&gpio 12 0>;
+ debug = <0>;
+ };
+
+@@ -66,7 +66,7 @@
+ spi-max-frequency = <2000000>;
+ interrupts = <25 2>; /* high-to-low edge triggered */
+ interrupt-parent = <&gpio>;
+- pendown-gpio = <&gpio 25 0>;
++ pendown-gpio = <&gpio 25 1>;
+ ti,x-plate-ohms = /bits/ 16 <60>;
+ ti,pressure-max = /bits/ 16 <255>;
+ };
+--- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts
++++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts
+@@ -65,7 +65,7 @@
+ buswidth = <8>;
+ txbuflen = <32768>;
+
+- reset-gpios = <&gpio 15 0>;
++ reset-gpios = <&gpio 15 1>;
+ dc-gpios = <&gpio 25 0>;
+ led-gpios = <&gpio 18 0>;
+
+--- a/arch/arm/boot/dts/overlays/piscreen-overlay.dts
++++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts
+@@ -59,9 +59,9 @@
+ fps = <30>;
+ buswidth = <8>;
+ regwidth = <16>;
+- reset-gpios = <&gpio 25 0>;
++ reset-gpios = <&gpio 25 1>;
+ dc-gpios = <&gpio 24 0>;
+- led-gpios = <&gpio 22 1>;
++ led-gpios = <&gpio 22 0>;
+ debug = <0>;
+
+ init = <0x10000b0 0x00
+--- a/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts
++++ b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts
+@@ -59,9 +59,9 @@
+ buswidth = <8>;
+ regwidth = <16>;
+ txbuflen = <32768>;
+- reset-gpios = <&gpio 25 0>;
++ reset-gpios = <&gpio 25 1>;
+ dc-gpios = <&gpio 24 0>;
+- led-gpios = <&gpio 22 1>;
++ led-gpios = <&gpio 22 0>;
+ debug = <0>;
+
+ init = <0x10000b0 0x00
+--- a/arch/arm/boot/dts/overlays/sh1106-spi-overlay.dts
++++ b/arch/arm/boot/dts/overlays/sh1106-spi-overlay.dts
+@@ -59,7 +59,7 @@
+ rotate = <0>;
+ fps = <25>;
+ buswidth = <8>;
+- reset-gpios = <&gpio 25 0>;
++ reset-gpios = <&gpio 25 1>;
+ dc-gpios = <&gpio 24 0>;
+ debug = <0>;
+
+--- a/arch/arm/boot/dts/overlays/ssd1306-spi-overlay.dts
++++ b/arch/arm/boot/dts/overlays/ssd1306-spi-overlay.dts
+@@ -59,7 +59,7 @@
+ rotate = <0>;
+ fps = <25>;
+ buswidth = <8>;
+- reset-gpios = <&gpio 25 0>;
++ reset-gpios = <&gpio 25 1>;
+ dc-gpios = <&gpio 24 0>;
+ debug = <0>;
+
+--- a/arch/arm/boot/dts/overlays/ssd1351-spi-overlay.dts
++++ b/arch/arm/boot/dts/overlays/ssd1351-spi-overlay.dts
+@@ -59,7 +59,7 @@
+ rotate = <0>;
+ fps = <25>;
+ buswidth = <8>;
+- reset-gpios = <&gpio 25 0>;
++ reset-gpios = <&gpio 25 1>;
+ dc-gpios = <&gpio 24 0>;
+ debug = <0>;
+
+--- a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts
++++ b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts
+@@ -85,9 +85,9 @@
+ fps = <20>;
+ bgr;
+ buswidth = <8>;
+- reset-gpios = <&gpio 25 0>;
++ reset-gpios = <&gpio 25 1>;
+ dc-gpios = <&gpio 24 0>;
+- led-gpios = <&gpio 18 1>;
++ led-gpios = <&gpio 18 0>;
+ debug = <0>;
+
+ init = <0x10000B0 0x80
diff --git a/target/linux/bcm27xx/patches-5.4/950-0980-SQUASH-USB-gadget-f_hid-remove-more-spam.patch b/target/linux/bcm27xx/patches-5.4/950-0980-SQUASH-USB-gadget-f_hid-remove-more-spam.patch
new file mode 100644
index 0000000000..3f199cfdf1
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0980-SQUASH-USB-gadget-f_hid-remove-more-spam.patch
@@ -0,0 +1,26 @@
+From 5018dc559136e2bca24973e71ed8747adf0f37f3 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 5 Oct 2020 15:41:15 +0100
+Subject: [PATCH] SQUASH: USB: gadget: f_hid: remove more spam
+
+Tidying up the previous patch to this file dropped the deletion of a
+particularly noisy error message. Restore its removal.
+
+See: https://github.com/raspberrypi/linux/issues/3870
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/usb/gadget/function/f_hid.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -411,8 +411,6 @@ try_again:
+ }
+ status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC);
+ if (status < 0) {
+- ERROR(hidg->func.config->cdev,
+- "usb_ep_queue error on int endpoint %zd\n", status);
+ goto release_write_pending;
+ } else {
+ status = count;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0981-overlays-Add-sd3078-to-the-i2c-rtc-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0981-overlays-Add-sd3078-to-the-i2c-rtc-overlay.patch
new file mode 100644
index 0000000000..5df3d2ded9
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0981-overlays-Add-sd3078-to-the-i2c-rtc-overlay.patch
@@ -0,0 +1,58 @@
+From 8688b06ae53d6f60adcdcfe3d58ad7ef0ed7dba0 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 5 Oct 2020 16:10:26 +0100
+Subject: [PATCH] overlays: Add sd3078 to the i2c-rtc overlay
+
+Add support for the SD3078 RTC to the i2c-rtc overlay.
+
+See: https://github.com/raspberrypi/linux/issues/3881
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 2 ++
+ arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 16 ++++++++++++++++
+ 2 files changed, 18 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1232,6 +1232,8 @@ Params: abx80x Select o
+
+ rv3028 Select the Micro Crystal RV3028 device
+
++ sd3078 Select the ZXW Shenzhen whwave SD3078 device
++
+ addr Sets the address for the RTC. Note that the
+ device must be configured to use the specified
+ address.
+--- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts
++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts
+@@ -220,6 +220,21 @@
+ };
+ };
+
++ fragment@14 {
++ target = <&i2c_arm>;
++ __dormant__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ sd3078: sd3078@32 {
++ compatible = "whwave,sd3078";
++ reg = <0x32>;
++ status = "okay";
++ };
++ };
++ };
++
+ __overrides__ {
+ abx80x = <0>,"+0";
+ ds1307 = <0>,"+1";
+@@ -235,6 +250,7 @@
+ pcf2129 = <0>,"+11";
+ pcf85363 = <0>,"+12";
+ rv1805 = <0>,"+13";
++ sd3078 = <0>,"+14";
+
+ addr = <&abx80x>, "reg:0",
+ <&ds1307>, "reg:0",
diff --git a/target/linux/bcm27xx/patches-5.4/950-0982-dwc_otg-initialise-sched_frame-for-periodic-QHs-that.patch b/target/linux/bcm27xx/patches-5.4/950-0982-dwc_otg-initialise-sched_frame-for-periodic-QHs-that.patch
new file mode 100644
index 0000000000..2a12614196
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0982-dwc_otg-initialise-sched_frame-for-periodic-QHs-that.patch
@@ -0,0 +1,33 @@
+From 2ae3859a69cecc2820f768f4d22022000e9f2e22 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.org>
+Date: Wed, 7 Oct 2020 15:09:29 +0100
+Subject: [PATCH] dwc_otg: initialise sched_frame for periodic QHs
+ that were parked
+
+If a periodic QH has no remaining QTDs, then it is removed from all
+periodic schedules. When re-adding, initialise the sched_frame and
+start_split_frame from the current value of the frame counter.
+
+See https://bugs.launchpad.net/raspbian/+bug/1819560
+and
+ https://github.com/raspberrypi/linux/issues/3883
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
+@@ -689,7 +689,11 @@ int dwc_otg_hcd_qh_add(dwc_otg_hcd_t * h
+ &qh->qh_list_entry);
+ //hcd->fiq_state->kick_np_queues = 1;
+ } else {
++ /* If the QH wasn't in a schedule, then sched_frame is stale. */
++ qh->sched_frame = dwc_frame_num_inc(dwc_otg_hcd_get_frame_number(hcd),
++ SCHEDULE_SLOP);
+ status = schedule_periodic(hcd, qh);
++ qh->start_split_frame = qh->sched_frame;
+ if ( !hcd->periodic_qh_count ) {
+ intr_mask.b.sofintr = 1;
+ if (fiq_enable) {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0983-staging-bcm2835-camera-Replace-deprecated-V4L2_PIX_F.patch b/target/linux/bcm27xx/patches-5.4/950-0983-staging-bcm2835-camera-Replace-deprecated-V4L2_PIX_F.patch
new file mode 100644
index 0000000000..f86566ee63
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0983-staging-bcm2835-camera-Replace-deprecated-V4L2_PIX_F.patch
@@ -0,0 +1,30 @@
+From c46ee3d6fc36bcfe42ca860f8da85775f0b9cc6a Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 8 Oct 2020 15:35:14 +0100
+Subject: [PATCH] staging: bcm2835-camera: Replace deprecated
+ V4L2_PIX_FMT_BGR32
+
+V4L2_PIX_FMT_BGR32 is deprecated as it is ambiguous over where
+the alpha byte is. Cheese/GStreamer appear to get it wrong for
+one, and qv4l2 gets red and blue swapped.
+
+Swap to the newer V4L2_PIX_FMT_BGRX32 format.
+
+https://www.raspberrypi.org/forums/viewtopic.php?f=38&t=267736&p=1738912
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
++++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+@@ -175,7 +175,7 @@ static struct mmal_fmt formats[] = {
+ .ybbp = 1,
+ .remove_padding = 1,
+ }, {
+- .fourcc = V4L2_PIX_FMT_BGR32,
++ .fourcc = V4L2_PIX_FMT_BGRX32,
+ .mmal = MMAL_ENCODING_BGRA,
+ .depth = 32,
+ .mmal_component = COMP_CAMERA,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0984-staging-bcm2835-codec-Replace-deprecated-V4L2_PIX_FM.patch b/target/linux/bcm27xx/patches-5.4/950-0984-staging-bcm2835-codec-Replace-deprecated-V4L2_PIX_FM.patch
new file mode 100644
index 0000000000..2e6d04bcbb
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0984-staging-bcm2835-codec-Replace-deprecated-V4L2_PIX_FM.patch
@@ -0,0 +1,27 @@
+From ed4adfd60c1495b864720e1f79b0b2a443447e38 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 8 Oct 2020 16:06:59 +0100
+Subject: [PATCH] staging: bcm2835-codec: Replace deprecated
+ V4L2_PIX_FMT_BGR32
+
+V4L2_PIX_FMT_BGR32 is deprecated as it is ambiguous over where
+the alpha byte is.
+
+Swap to the newer V4L2_PIX_FMT_BGRX32 format.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+@@ -207,7 +207,7 @@ static const struct bcm2835_codec_fmt su
+ .mmal_fmt = MMAL_ENCODING_BGR24,
+ .size_multiplier_x2 = 2,
+ }, {
+- .fourcc = V4L2_PIX_FMT_BGR32,
++ .fourcc = V4L2_PIX_FMT_BGRX32,
+ .depth = 32,
+ .bytesperline_align = 32,
+ .flags = 0,
diff --git a/target/linux/bcm27xx/patches-5.4/950-0985-ARM-bcm2711-rpi.dts-Unlock-DMA-channels-9-10.patch b/target/linux/bcm27xx/patches-5.4/950-0985-ARM-bcm2711-rpi.dts-Unlock-DMA-channels-9-10.patch
new file mode 100644
index 0000000000..8895a020b2
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0985-ARM-bcm2711-rpi.dts-Unlock-DMA-channels-9-10.patch
@@ -0,0 +1,33 @@
+From b10a49ab016ed9ac8f231845fb3e83fbf3505652 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 12 Oct 2020 14:36:35 +0100
+Subject: [PATCH] ARM: bcm2711-rpi.dts: Unlock DMA channels 9 & 10
+
+The downstream-specific override of the 32-bit DMA mask needlessly
+disables channels 9 and 10 - the VPU doesn't use them. This override
+is redundant, so delete it.
+
+See: https://github.com/raspberrypi/linux/issues/3896
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2711-rpi.dtsi | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi
+@@ -246,13 +246,8 @@
+ };
+ };
+
+-&dma {
+- /* The VPU firmware uses DMA channel 11 for VCHIQ */
+- brcm,dma-channel-mask = <0x1f5>;
+-};
+-
+ &dma40 {
+- /* The VPU firmware DMA channel 11 for VCHIQ */
++ /* The VPU firmware uses DMA channel 11 for VCHIQ */
+ brcm,dma-channel-mask = <0x7000>;
+ };
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0986-gpio-Add-gpio-fsm-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0986-gpio-Add-gpio-fsm-driver.patch
new file mode 100644
index 0000000000..7076026e7c
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0986-gpio-Add-gpio-fsm-driver.patch
@@ -0,0 +1,1182 @@
+From c31626a9e173f2b2e0adc4cb8bfbb86a958bafcd Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 30 Sep 2020 12:00:54 +0100
+Subject: [PATCH] gpio: Add gpio-fsm driver
+
+The gpio-fsm driver implements simple state machines that allow GPIOs
+to be controlled in response to inputs from other GPIOs - real and
+soft/virtual - and time delays. It can:
++ create dummy GPIOs for drivers that demand them,
++ drive multiple GPIOs from a single input, with optional delays,
++ add a debounce circuit to an input,
++ drive pattern sequences onto LEDs
+etc.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/gpio/Kconfig | 9 +
+ drivers/gpio/Makefile | 1 +
+ drivers/gpio/gpio-fsm.c | 1103 +++++++++++++++++++++++++++
+ include/dt-bindings/gpio/gpio-fsm.h | 21 +
+ 4 files changed, 1134 insertions(+)
+ create mode 100644 drivers/gpio/gpio-fsm.c
+ create mode 100644 include/dt-bindings/gpio/gpio-fsm.h
+
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -1071,6 +1071,15 @@ config HTC_EGPIO
+ several HTC phones. It provides basic support for input
+ pins, output pins, and irqs.
+
++config GPIO_FSM
++ tristate "GPIO FSM support"
++ help
++ The GPIO FSM driver allows the creation of state machines for
++ manipulating GPIOs (both real and virtual), with state transitions
++ triggered by GPIO edges or delays.
++
++ If unsure, say N.
++
+ config GPIO_JANZ_TTL
+ tristate "Janz VMOD-TTL Digital IO Module"
+ depends on MFD_JANZ_CMODIO
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -55,6 +55,7 @@ obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93x
+ obj-$(CONFIG_GPIO_EXAR) += gpio-exar.o
+ obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o
+ obj-$(CONFIG_GPIO_FTGPIO010) += gpio-ftgpio010.o
++obj-$(CONFIG_GPIO_FSM) += gpio-fsm.o
+ obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o
+ obj-$(CONFIG_GPIO_GPIO_MM) += gpio-gpio-mm.o
+ obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.o
+--- /dev/null
++++ b/drivers/gpio/gpio-fsm.c
+@@ -0,0 +1,1103 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * GPIO FSM driver
++ *
++ * This driver implements simple state machines that allow real GPIOs to be
++ * controlled in response to inputs from other GPIOs - real and soft/virtual -
++ * and time delays. It can:
++ * + create dummy GPIOs for drivers that demand them
++ * + drive multiple GPIOs from a single input, with optional delays
++ * + add a debounce circuit to an input
++ * + drive pattern sequences onto LEDs
++ * etc.
++ *
++ * Copyright (C) 2020 Raspberry Pi (Trading) Ltd.
++ */
++
++#include <linux/err.h>
++#include <linux/gpio.h>
++#include <linux/gpio/driver.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include <dt-bindings/gpio/gpio-fsm.h>
++
++#define MODULE_NAME "gpio-fsm"
++
++#define GF_IO_TYPE(x) ((u32)(x) & 0xffff)
++#define GF_IO_INDEX(x) ((u32)(x) >> 16)
++
++enum {
++ SIGNAL_GPIO,
++ SIGNAL_SOFT
++};
++
++enum {
++ INPUT_GPIO,
++ INPUT_SOFT
++};
++
++enum {
++ SYM_UNDEFINED,
++ SYM_NAME,
++ SYM_SET,
++ SYM_START,
++ SYM_SHUTDOWN,
++
++ SYM_MAX
++};
++
++struct soft_gpio {
++ int dir;
++ int value;
++};
++
++struct input_gpio_state {
++ struct gpio_fsm *gf;
++ struct gpio_desc *desc;
++ struct fsm_state *target;
++ int index;
++ int value;
++ int irq;
++ bool enabled;
++ bool active_low;
++};
++
++struct gpio_event {
++ int index;
++ int value;
++ struct fsm_state *target;
++};
++
++struct symtab_entry {
++ const char *name;
++ void *value;
++ struct symtab_entry *next;
++};
++
++struct output_signal {
++ u8 type;
++ u8 value;
++ u16 index;
++};
++
++struct fsm_state {
++ const char *name;
++ struct output_signal *signals;
++ struct gpio_event *gpio_events;
++ struct gpio_event *soft_events;
++ struct fsm_state *delay_target;
++ struct fsm_state *shutdown_target;
++ unsigned int num_signals;
++ unsigned int num_gpio_events;
++ unsigned int num_soft_events;
++ unsigned int delay_ms;
++ unsigned int shutdown_ms;
++};
++
++struct gpio_fsm {
++ struct gpio_chip gc;
++ struct device *dev;
++ spinlock_t spinlock;
++ struct work_struct work;
++ struct timer_list timer;
++ wait_queue_head_t shutdown_event;
++ struct fsm_state *states;
++ struct input_gpio_state *input_gpio_states;
++ struct gpio_descs *input_gpios;
++ struct gpio_descs *output_gpios;
++ struct soft_gpio *soft_gpios;
++ struct fsm_state *start_state;
++ struct fsm_state *shutdown_state;
++ unsigned int num_states;
++ unsigned int num_output_gpios;
++ unsigned int num_input_gpios;
++ unsigned int num_soft_gpios;
++ unsigned int shutdown_timeout_ms;
++ unsigned int shutdown_jiffies;
++
++ struct fsm_state *current_state;
++ struct fsm_state *next_state;
++ struct fsm_state *delay_target_state;
++ int delay_ms;
++ unsigned int debug;
++ bool shutting_down;
++ struct symtab_entry *symtab;
++};
++
++static struct symtab_entry *do_add_symbol(struct symtab_entry **symtab,
++ const char *name, void *value)
++{
++ struct symtab_entry **p = symtab;
++
++ while (*p && strcmp((*p)->name, name))
++ p = &(*p)->next;
++
++ if (*p) {
++ /* This is an existing symbol */
++ if ((*p)->value) {
++ /* Already defined */
++ if (value) {
++ if ((uintptr_t)value < SYM_MAX)
++ return ERR_PTR(-EINVAL);
++ else
++ return ERR_PTR(-EEXIST);
++ }
++ } else {
++ /* Undefined */
++ (*p)->value = value;
++ }
++ } else {
++ /* This is a new symbol */
++ *p = kmalloc(sizeof(struct symtab_entry), GFP_KERNEL);
++ if (*p) {
++ (*p)->name = name;
++ (*p)->value = value;
++ (*p)->next = NULL;
++ }
++ }
++ return *p;
++}
++
++static int add_symbol(struct symtab_entry **symtab,
++ const char *name, void *value)
++{
++ struct symtab_entry *sym = do_add_symbol(symtab, name, value);
++
++ return PTR_ERR_OR_ZERO(sym);
++}
++
++static struct symtab_entry *get_symbol(struct symtab_entry **symtab,
++ const char *name)
++{
++ struct symtab_entry *sym = do_add_symbol(symtab, name, NULL);
++
++ if (IS_ERR(sym))
++ return NULL;
++ return sym;
++}
++
++static void free_symbols(struct symtab_entry **symtab)
++{
++ struct symtab_entry *sym = *symtab;
++ void *p;
++
++ *symtab = NULL;
++ while (sym) {
++ p = sym;
++ sym = sym->next;
++ kfree(p);
++ }
++}
++
++static int gpio_fsm_get_direction(struct gpio_chip *gc, unsigned int off)
++{
++ struct gpio_fsm *gf = gpiochip_get_data(gc);
++ struct soft_gpio *sg;
++
++ if (off >= gf->num_soft_gpios)
++ return -EINVAL;
++ sg = &gf->soft_gpios[off];
++
++ return sg->dir;
++}
++
++static int gpio_fsm_get(struct gpio_chip *gc, unsigned int off)
++{
++ struct gpio_fsm *gf = gpiochip_get_data(gc);
++ struct soft_gpio *sg;
++
++ if (off >= gf->num_soft_gpios)
++ return -EINVAL;
++ sg = &gf->soft_gpios[off];
++
++ return sg->value;
++}
++
++static void gpio_fsm_go_to_state(struct gpio_fsm *gf,
++ struct fsm_state *new_state)
++{
++ struct input_gpio_state *inp_state;
++ struct gpio_event *gp_ev;
++ struct fsm_state *state;
++ int i;
++
++ dev_dbg(gf->dev, "go_to_state(%s)\n",
++ new_state ? new_state->name : "<unset>");
++
++ spin_lock(&gf->spinlock);
++
++ if (gf->next_state) {
++ /* Something else has already requested a transition */
++ spin_unlock(&gf->spinlock);
++ return;
++ }
++
++ gf->next_state = new_state;
++ state = gf->current_state;
++ gf->delay_target_state = NULL;
++
++ if (state) {
++ /* Disarm any GPIO IRQs */
++ for (i = 0; i < state->num_gpio_events; i++) {
++ gp_ev = &state->gpio_events[i];
++ inp_state = &gf->input_gpio_states[gp_ev->index];
++ inp_state->target = NULL;
++ }
++ }
++
++ spin_unlock(&gf->spinlock);
++
++ if (new_state)
++ schedule_work(&gf->work);
++}
++
++static void gpio_fsm_set_soft(struct gpio_fsm *gf,
++ unsigned int off, int val)
++{
++ struct soft_gpio *sg = &gf->soft_gpios[off];
++ struct gpio_event *gp_ev;
++ struct fsm_state *state;
++ int i;
++
++ dev_dbg(gf->dev, "set(%d,%d)\n", off, val);
++ state = gf->current_state;
++ sg->value = val;
++ for (i = 0; i < state->num_soft_events; i++) {
++ gp_ev = &state->soft_events[i];
++ if (gp_ev->index == off && gp_ev->value == val) {
++ if (gf->debug)
++ dev_info(gf->dev,
++ "GF_SOFT %d->%d -> %s\n", gp_ev->index,
++ gp_ev->value, gp_ev->target->name);
++ gpio_fsm_go_to_state(gf, gp_ev->target);
++ break;
++ }
++ }
++}
++
++static int gpio_fsm_direction_input(struct gpio_chip *gc, unsigned int off)
++{
++ struct gpio_fsm *gf = gpiochip_get_data(gc);
++ struct soft_gpio *sg;
++
++ if (off >= gf->num_soft_gpios)
++ return -EINVAL;
++ sg = &gf->soft_gpios[off];
++ sg->dir = GPIOF_DIR_IN;
++
++ return 0;
++}
++
++static int gpio_fsm_direction_output(struct gpio_chip *gc, unsigned int off,
++ int value)
++{
++ struct gpio_fsm *gf = gpiochip_get_data(gc);
++ struct soft_gpio *sg;
++
++ if (off >= gf->num_soft_gpios)
++ return -EINVAL;
++ sg = &gf->soft_gpios[off];
++ sg->dir = GPIOF_DIR_OUT;
++ gpio_fsm_set_soft(gf, off, value);
++
++ return 0;
++}
++
++static void gpio_fsm_set(struct gpio_chip *gc, unsigned int off, int val)
++{
++ struct gpio_fsm *gf;
++
++ gf = gpiochip_get_data(gc);
++ if (off < gf->num_soft_gpios)
++ gpio_fsm_set_soft(gf, off, val);
++}
++
++static void gpio_fsm_enter_state(struct gpio_fsm *gf,
++ struct fsm_state *state)
++{
++ struct input_gpio_state *inp_state;
++ struct output_signal *signal;
++ struct gpio_event *event;
++ struct gpio_desc *gpiod;
++ struct soft_gpio *soft;
++ int value;
++ int i;
++
++ dev_dbg(gf->dev, "enter_state(%s)\n", state->name);
++
++ gf->current_state = state;
++
++ // 1. Apply any listed signals
++ for (i = 0; i < state->num_signals; i++) {
++ signal = &state->signals[i];
++
++ if (gf->debug)
++ dev_info(gf->dev, " set %s %d->%d\n",
++ (signal->type == SIGNAL_GPIO) ? "GF_OUT" :
++ "GF_SOFT",
++ signal->index, signal->value);
++ switch (signal->type) {
++ case SIGNAL_GPIO:
++ gpiod = gf->output_gpios->desc[signal->index];
++ gpiod_set_value_cansleep(gpiod, signal->value);
++ break;
++ case SIGNAL_SOFT:
++ soft = &gf->soft_gpios[signal->index];
++ gpio_fsm_set_soft(gf, signal->index, signal->value);
++ break;
++ }
++ }
++
++ // 2. Exit if successfully reached shutdown state
++ if (gf->shutting_down && state == state->shutdown_target) {
++ wake_up(&gf->shutdown_event);
++ return;
++ }
++
++ // 3. Schedule a timer callback if shutting down
++ if (state->shutdown_target) {
++ // Remember the absolute shutdown time in case remove is called
++ // at a later time.
++ gf->shutdown_jiffies =
++ jiffies + msecs_to_jiffies(state->shutdown_ms);
++
++ if (gf->shutting_down) {
++ gf->delay_target_state = state->shutdown_target;
++ gf->delay_ms = state->shutdown_ms;
++ mod_timer(&gf->timer, gf->shutdown_jiffies);
++ }
++ }
++
++ // During shutdown, skip everything else
++ if (gf->shutting_down)
++ return;
++
++ // Otherwise record what the shutdown time would be
++ gf->shutdown_jiffies = jiffies + msecs_to_jiffies(state->shutdown_ms);
++
++ // 4. Check soft inputs for transitions to take
++ for (i = 0; i < state->num_soft_events; i++) {
++ event = &state->soft_events[i];
++ if (gf->soft_gpios[event->index].value == event->value) {
++ if (gf->debug)
++ dev_info(gf->dev,
++ "GF_SOFT %d=%d -> %s\n", event->index,
++ event->value, event->target->name);
++ gpio_fsm_go_to_state(gf, event->target);
++ return;
++ }
++ }
++
++ // 5. Check GPIOs for transitions to take, enabling the IRQs
++ for (i = 0; i < state->num_gpio_events; i++) {
++ event = &state->gpio_events[i];
++ inp_state = &gf->input_gpio_states[event->index];
++ inp_state->target = event->target;
++ inp_state->value = event->value;
++ inp_state->enabled = true;
++
++ value = gpiod_get_value(gf->input_gpios->desc[event->index]);
++
++ // Clear stale event state
++ disable_irq(inp_state->irq);
++
++ irq_set_irq_type(inp_state->irq,
++ (inp_state->value ^ inp_state->active_low) ?
++ IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING);
++ enable_irq(inp_state->irq);
++
++ if (value == event->value && inp_state->target) {
++ if (gf->debug)
++ dev_info(gf->dev,
++ "GF_IN %d=%d -> %s\n", event->index,
++ event->value, event->target->name);
++ gpio_fsm_go_to_state(gf, event->target);
++ return;
++ }
++ }
++
++ // 6. Schedule a timer callback if delay_target
++ if (state->delay_target) {
++ gf->delay_target_state = state->delay_target;
++ gf->delay_ms = state->delay_ms;
++ mod_timer(&gf->timer,
++ jiffies + msecs_to_jiffies(state->delay_ms));
++ }
++}
++
++static void gpio_fsm_work(struct work_struct *work)
++{
++ struct input_gpio_state *inp_state;
++ struct fsm_state *new_state;
++ struct fsm_state *state;
++ struct gpio_event *gp_ev;
++ struct gpio_fsm *gf;
++ int i;
++
++ gf = container_of(work, struct gpio_fsm, work);
++ spin_lock(&gf->spinlock);
++ state = gf->current_state;
++ new_state = gf->next_state;
++ if (!new_state)
++ new_state = gf->delay_target_state;
++ gf->next_state = NULL;
++ gf->delay_target_state = NULL;
++ spin_unlock(&gf->spinlock);
++
++ if (state) {
++ /* Disable any enabled GPIO IRQs */
++ for (i = 0; i < state->num_gpio_events; i++) {
++ gp_ev = &state->gpio_events[i];
++ inp_state = &gf->input_gpio_states[gp_ev->index];
++ if (inp_state->enabled) {
++ inp_state->enabled = false;
++ irq_set_irq_type(inp_state->irq,
++ IRQF_TRIGGER_NONE);
++ }
++ }
++ }
++
++ if (new_state)
++ gpio_fsm_enter_state(gf, new_state);
++}
++
++static irqreturn_t gpio_fsm_gpio_irq_handler(int irq, void *dev_id)
++{
++ struct input_gpio_state *inp_state = dev_id;
++ struct gpio_fsm *gf = inp_state->gf;
++ struct fsm_state *target;
++
++ target = inp_state->target;
++ if (!target)
++ return IRQ_NONE;
++
++ /* If the IRQ has fired then the desired state _must_ have occurred */
++ inp_state->enabled = false;
++ irq_set_irq_type(inp_state->irq, IRQF_TRIGGER_NONE);
++ if (gf->debug)
++ dev_info(gf->dev, "GF_IN %d->%d -> %s\n",
++ inp_state->index, inp_state->value, target->name);
++ gpio_fsm_go_to_state(gf, target);
++ return IRQ_HANDLED;
++}
++
++static void gpio_fsm_timer(struct timer_list *timer)
++{
++ struct gpio_fsm *gf = container_of(timer, struct gpio_fsm, timer);
++ struct fsm_state *target;
++
++ target = gf->delay_target_state;
++ if (!target)
++ return;
++
++ if (gf->debug)
++ dev_info(gf->dev, "GF_DELAY %d -> %s\n", gf->delay_ms,
++ target->name);
++
++ gpio_fsm_go_to_state(gf, target);
++}
++
++int gpio_fsm_parse_signals(struct gpio_fsm *gf, struct fsm_state *state,
++ struct property *prop)
++{
++ const __be32 *cells = prop->value;
++ struct output_signal *signal;
++ u32 io;
++ u32 type;
++ u32 index;
++ u32 value;
++ int ret = 0;
++ int i;
++
++ if (prop->length % 8) {
++ dev_err(gf->dev, "malformed set in state %s\n",
++ state->name);
++ return -EINVAL;
++ }
++
++ state->num_signals = prop->length/8;
++ state->signals = devm_kcalloc(gf->dev, state->num_signals,
++ sizeof(struct output_signal),
++ GFP_KERNEL);
++ for (i = 0; i < state->num_signals; i++) {
++ signal = &state->signals[i];
++ io = be32_to_cpu(cells[0]);
++ type = GF_IO_TYPE(io);
++ index = GF_IO_INDEX(io);
++ value = be32_to_cpu(cells[1]);
++
++ if (type != GF_OUT && type != GF_SOFT) {
++ dev_err(gf->dev,
++ "invalid set type %d in state %s\n",
++ type, state->name);
++ ret = -EINVAL;
++ break;
++ }
++ if (type == GF_OUT && index >= gf->num_output_gpios) {
++ dev_err(gf->dev,
++ "invalid GF_OUT number %d in state %s\n",
++ index, state->name);
++ ret = -EINVAL;
++ break;
++ }
++ if (type == GF_SOFT && index >= gf->num_soft_gpios) {
++ dev_err(gf->dev,
++ "invalid GF_SOFT number %d in state %s\n",
++ index, state->name);
++ ret = -EINVAL;
++ break;
++ }
++ if (value != 0 && value != 1) {
++ dev_err(gf->dev,
++ "invalid set value %d in state %s\n",
++ value, state->name);
++ ret = -EINVAL;
++ break;
++ }
++ signal->type = (type == GF_OUT) ? SIGNAL_GPIO : SIGNAL_SOFT;
++ signal->index = index;
++ signal->value = value;
++ cells += 2;
++ }
++
++ return ret;
++}
++
++struct gpio_event *new_event(struct gpio_event **events, int *num_events)
++{
++ int num = ++(*num_events);
++ *events = krealloc(*events, num * sizeof(struct gpio_event),
++ GFP_KERNEL);
++ return *events ? *events + (num - 1) : NULL;
++}
++
++int gpio_fsm_parse_events(struct gpio_fsm *gf, struct fsm_state *state,
++ struct property *prop)
++{
++ const __be32 *cells = prop->value;
++ struct symtab_entry *sym;
++ int num_cells;
++ int ret = 0;
++ int i;
++
++ if (prop->length % 8) {
++ dev_err(gf->dev,
++ "malformed transitions from state %s to state %s\n",
++ state->name, prop->name);
++ return -EINVAL;
++ }
++
++ sym = get_symbol(&gf->symtab, prop->name);
++ num_cells = prop->length / 4;
++ i = 0;
++ while (i < num_cells) {
++ struct gpio_event *gp_ev;
++ u32 event, param;
++ u32 index;
++
++ event = be32_to_cpu(cells[i++]);
++ param = be32_to_cpu(cells[i++]);
++ index = GF_IO_INDEX(event);
++
++ switch (GF_IO_TYPE(event)) {
++ case GF_IN:
++ if (index >= gf->num_input_gpios) {
++ dev_err(gf->dev,
++ "invalid GF_IN %d in transitions from state %s to state %s\n",
++ index, state->name, prop->name);
++ return -EINVAL;
++ }
++ if (param > 1) {
++ dev_err(gf->dev,
++ "invalid GF_IN value %d in transitions from state %s to state %s\n",
++ param, state->name, prop->name);
++ return -EINVAL;
++ }
++ gp_ev = new_event(&state->gpio_events,
++ &state->num_gpio_events);
++ if (!gp_ev)
++ return -ENOMEM;
++ gp_ev->index = index;
++ gp_ev->value = param;
++ gp_ev->target = (struct fsm_state *)sym;
++ break;
++
++ case GF_SOFT:
++ if (index >= gf->num_soft_gpios) {
++ dev_err(gf->dev,
++ "invalid GF_SOFT %d in transitions from state %s to state %s\n",
++ index, state->name, prop->name);
++ return -EINVAL;
++ }
++ if (param > 1) {
++ dev_err(gf->dev,
++ "invalid GF_SOFT value %d in transitions from state %s to state %s\n",
++ param, state->name, prop->name);
++ return -EINVAL;
++ }
++ gp_ev = new_event(&state->soft_events,
++ &state->num_soft_events);
++ if (!gp_ev)
++ return -ENOMEM;
++ gp_ev->index = index;
++ gp_ev->value = param;
++ gp_ev->target = (struct fsm_state *)sym;
++ break;
++
++ case GF_DELAY:
++ if (state->delay_target) {
++ dev_err(gf->dev,
++ "state %s has multiple GF_DELAYs\n",
++ state->name);
++ return -EINVAL;
++ }
++ state->delay_target = (struct fsm_state *)sym;
++ state->delay_ms = param;
++ break;
++
++ case GF_SHUTDOWN:
++ if (state->shutdown_target == state) {
++ dev_err(gf->dev,
++ "shutdown state %s has GF_SHUTDOWN\n",
++ state->name);
++ return -EINVAL;
++ } else if (state->shutdown_target) {
++ dev_err(gf->dev,
++ "state %s has multiple GF_SHUTDOWNs\n",
++ state->name);
++ return -EINVAL;
++ }
++ state->shutdown_target =
++ (struct fsm_state *)sym;
++ state->shutdown_ms = param;
++ break;
++
++ default:
++ dev_err(gf->dev,
++ "invalid event %08x in transitions from state %s to state %s\n",
++ event, state->name, prop->name);
++ return -EINVAL;
++ }
++ }
++ if (i != num_cells) {
++ dev_err(gf->dev,
++ "malformed transitions from state %s to state %s\n",
++ state->name, prop->name);
++ return -EINVAL;
++ }
++
++ return ret;
++}
++
++int gpio_fsm_parse_state(struct gpio_fsm *gf,
++ struct fsm_state *state,
++ struct device_node *np)
++{
++ struct symtab_entry *sym;
++ struct property *prop;
++ int ret;
++
++ state->name = np->name;
++ ret = add_symbol(&gf->symtab, np->name, state);
++ if (ret) {
++ switch (ret) {
++ case -EINVAL:
++ dev_err(gf->dev, "'%s' is not a valid state name\n",
++ np->name);
++ break;
++ case -EEXIST:
++ dev_err(gf->dev, "state %s already defined\n",
++ np->name);
++ break;
++ default:
++ dev_err(gf->dev, "error %d adding state %s symbol\n",
++ ret, np->name);
++ break;
++ }
++ return ret;
++ }
++
++ for_each_property_of_node(np, prop) {
++ sym = get_symbol(&gf->symtab, prop->name);
++ if (!sym) {
++ ret = -ENOMEM;
++ break;
++ }
++
++ switch ((uintptr_t)sym->value) {
++ case SYM_SET:
++ ret = gpio_fsm_parse_signals(gf, state, prop);
++ break;
++ case SYM_START:
++ if (gf->start_state) {
++ dev_err(gf->dev, "multiple start states\n");
++ ret = -EINVAL;
++ } else {
++ gf->start_state = state;
++ }
++ break;
++ case SYM_SHUTDOWN:
++ state->shutdown_target = state;
++ gf->shutdown_state = state;
++ break;
++ case SYM_NAME:
++ /* Ignore */
++ break;
++ default:
++ /* A set of transition events to this state */
++ ret = gpio_fsm_parse_events(gf, state, prop);
++ break;
++ }
++ }
++
++ return ret;
++}
++
++static void dump_all(struct gpio_fsm *gf)
++{
++ int i, j;
++
++ dev_info(gf->dev, "Input GPIOs:\n");
++ for (i = 0; i < gf->num_input_gpios; i++)
++ dev_info(gf->dev, " %d: %p\n", i,
++ gf->input_gpios->desc[i]);
++
++ dev_info(gf->dev, "Output GPIOs:\n");
++ for (i = 0; i < gf->num_output_gpios; i++)
++ dev_info(gf->dev, " %d: %p\n", i,
++ gf->output_gpios->desc[i]);
++
++ dev_info(gf->dev, "Soft GPIOs:\n");
++ for (i = 0; i < gf->num_soft_gpios; i++)
++ dev_info(gf->dev, " %d: %s %d\n", i,
++ (gf->soft_gpios[i].dir == GPIOF_DIR_IN) ? "IN" : "OUT",
++ gf->soft_gpios[i].value);
++
++ dev_info(gf->dev, "Start state: %s\n",
++ gf->start_state ? gf->start_state->name : "-");
++
++ dev_info(gf->dev, "Shutdown timeout: %d ms\n",
++ gf->shutdown_timeout_ms);
++
++ for (i = 0; i < gf->num_states; i++) {
++ struct fsm_state *state = &gf->states[i];
++
++ dev_info(gf->dev, "State %s:\n", state->name);
++
++ if (state->shutdown_target == state)
++ dev_info(gf->dev, " Shutdown state\n");
++
++ dev_info(gf->dev, " Signals:\n");
++ for (j = 0; j < state->num_signals; j++) {
++ struct output_signal *signal = &state->signals[j];
++
++ dev_info(gf->dev, " %d: %s %d=%d\n", j,
++ (signal->type == SIGNAL_GPIO) ? "GPIO" :
++ "SOFT",
++ signal->index, signal->value);
++ }
++
++ dev_info(gf->dev, " GPIO events:\n");
++ for (j = 0; j < state->num_gpio_events; j++) {
++ struct gpio_event *event = &state->gpio_events[j];
++
++ dev_info(gf->dev, " %d: %d=%d -> %s\n", j,
++ event->index, event->value,
++ event->target->name);
++ }
++
++ dev_info(gf->dev, " Soft events:\n");
++ for (j = 0; j < state->num_soft_events; j++) {
++ struct gpio_event *event = &state->soft_events[j];
++
++ dev_info(gf->dev, " %d: %d=%d -> %s\n", j,
++ event->index, event->value,
++ event->target->name);
++ }
++
++ if (state->delay_target)
++ dev_info(gf->dev, " Delay: %d ms -> %s\n",
++ state->delay_ms, state->delay_target->name);
++
++ if (state->shutdown_target && state->shutdown_target != state)
++ dev_info(gf->dev, " Shutdown: %d ms -> %s\n",
++ state->shutdown_ms,
++ state->shutdown_target->name);
++ }
++ dev_info(gf->dev, "\n");
++}
++
++static int resolve_sym_to_state(struct gpio_fsm *gf, struct fsm_state **pstate)
++{
++ struct symtab_entry *sym = (struct symtab_entry *)*pstate;
++
++ if (!sym)
++ return -ENOMEM;
++
++ *pstate = sym->value;
++
++ if (!*pstate) {
++ dev_err(gf->dev, "state %s not defined\n",
++ sym->name);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int gpio_fsm_probe(struct platform_device *pdev)
++{
++ struct input_gpio_state *inp_state;
++ struct device *dev = &pdev->dev;
++ struct device_node *np = dev->of_node;
++ struct device_node *cp;
++ struct gpio_fsm *gf;
++ u32 debug = 0;
++ int num_states;
++ u32 num_soft_gpios;
++ int ret;
++ int i;
++ static const char *const reserved_symbols[] = {
++ [SYM_NAME] = "name",
++ [SYM_SET] = "set",
++ [SYM_START] = "start_state",
++ [SYM_SHUTDOWN] = "shutdown_state",
++ };
++
++ if (of_property_read_u32(np, "num-soft-gpios", &num_soft_gpios)) {
++ dev_err(dev, "missing 'num-soft-gpios' property\n");
++ return -EINVAL;
++ }
++
++ of_property_read_u32(np, "debug", &debug);
++
++ gf = devm_kzalloc(dev, sizeof(*gf), GFP_KERNEL);
++ if (!gf)
++ return -ENOMEM;
++
++ gf->dev = dev;
++ gf->debug = debug;
++
++ if (of_property_read_u32(np, "shutdown-timeout-ms",
++ &gf->shutdown_timeout_ms))
++ gf->shutdown_timeout_ms = 5000;
++
++ gf->num_soft_gpios = num_soft_gpios;
++ gf->soft_gpios = devm_kcalloc(dev, num_soft_gpios,
++ sizeof(struct soft_gpio), GFP_KERNEL);
++ if (!gf->soft_gpios)
++ return -ENOMEM;
++ for (i = 0; i < num_soft_gpios; i++) {
++ struct soft_gpio *sg = &gf->soft_gpios[i];
++
++ sg->dir = GPIOF_DIR_IN;
++ sg->value = 0;
++ }
++
++ gf->input_gpios = devm_gpiod_get_array_optional(dev, "input", GPIOD_IN);
++ if (IS_ERR(gf->input_gpios)) {
++ ret = PTR_ERR(gf->input_gpios);
++ dev_err(dev, "failed to get input gpios from DT - %d\n", ret);
++ return ret;
++ }
++ gf->num_input_gpios = (gf->input_gpios ? gf->input_gpios->ndescs : 0);
++
++ gf->input_gpio_states = devm_kcalloc(dev, gf->num_input_gpios,
++ sizeof(struct input_gpio_state),
++ GFP_KERNEL);
++ if (!gf->input_gpio_states)
++ return -ENOMEM;
++ for (i = 0; i < gf->num_input_gpios; i++) {
++ inp_state = &gf->input_gpio_states[i];
++ inp_state->desc = gf->input_gpios->desc[i];
++ inp_state->gf = gf;
++ inp_state->index = i;
++ inp_state->irq = gpiod_to_irq(inp_state->desc);
++ inp_state->active_low = gpiod_is_active_low(inp_state->desc);
++ if (inp_state->irq >= 0)
++ ret = devm_request_irq(gf->dev, inp_state->irq,
++ gpio_fsm_gpio_irq_handler,
++ IRQF_TRIGGER_NONE,
++ dev_name(dev),
++ inp_state);
++ else
++ ret = inp_state->irq;
++
++ if (ret) {
++ dev_err(dev,
++ "failed to get IRQ for input gpio - %d\n",
++ ret);
++ return ret;
++ }
++ }
++
++ gf->output_gpios = devm_gpiod_get_array_optional(dev, "output",
++ GPIOD_OUT_LOW);
++ if (IS_ERR(gf->output_gpios)) {
++ ret = PTR_ERR(gf->output_gpios);
++ dev_err(dev, "failed to get output gpios from DT - %d\n", ret);
++ return ret;
++ }
++ gf->num_output_gpios = (gf->output_gpios ? gf->output_gpios->ndescs :
++ 0);
++
++ num_states = of_get_child_count(np);
++ if (!num_states) {
++ dev_err(dev, "no states declared\n");
++ return -EINVAL;
++ }
++ gf->states = devm_kcalloc(dev, num_states,
++ sizeof(struct fsm_state), GFP_KERNEL);
++ if (!gf->states)
++ return -ENOMEM;
++
++ // add reserved words to the symbol table
++ for (i = 0; i < ARRAY_SIZE(reserved_symbols); i++) {
++ if (reserved_symbols[i])
++ add_symbol(&gf->symtab, reserved_symbols[i], (void *)i);
++ }
++
++ // parse the state
++ for_each_child_of_node(np, cp) {
++ struct fsm_state *state = &gf->states[gf->num_states];
++
++ ret = gpio_fsm_parse_state(gf, state, cp);
++ if (ret)
++ return ret;
++ gf->num_states++;
++ }
++
++ if (!gf->start_state) {
++ dev_err(gf->dev, "no start state defined\n");
++ return -EINVAL;
++ }
++
++ // resolve symbol pointers into state pointers
++ for (i = 0; !ret && i < gf->num_states; i++) {
++ struct fsm_state *state = &gf->states[i];
++ int j;
++
++ for (j = 0; !ret && j < state->num_gpio_events; j++) {
++ struct gpio_event *ev = &state->gpio_events[j];
++
++ ret = resolve_sym_to_state(gf, &ev->target);
++ }
++
++ for (j = 0; !ret && j < state->num_soft_events; j++) {
++ struct gpio_event *ev = &state->soft_events[j];
++
++ ret = resolve_sym_to_state(gf, &ev->target);
++ }
++
++ if (!ret) {
++ resolve_sym_to_state(gf, &state->delay_target);
++ if (state->shutdown_target != state)
++ resolve_sym_to_state(gf,
++ &state->shutdown_target);
++ }
++ }
++
++ if (!ret && gf->debug > 1)
++ dump_all(gf);
++
++ free_symbols(&gf->symtab);
++
++ if (ret)
++ return ret;
++
++ gf->gc.parent = dev;
++ gf->gc.label = np->name;
++ gf->gc.owner = THIS_MODULE;
++ gf->gc.of_node = np;
++ gf->gc.base = -1;
++ gf->gc.ngpio = num_soft_gpios;
++
++ gf->gc.get_direction = gpio_fsm_get_direction;
++ gf->gc.direction_input = gpio_fsm_direction_input;
++ gf->gc.direction_output = gpio_fsm_direction_output;
++ gf->gc.get = gpio_fsm_get;
++ gf->gc.set = gpio_fsm_set;
++ gf->gc.can_sleep = true;
++ spin_lock_init(&gf->spinlock);
++ INIT_WORK(&gf->work, gpio_fsm_work);
++ timer_setup(&gf->timer, gpio_fsm_timer, 0);
++ init_waitqueue_head(&gf->shutdown_event);
++
++ platform_set_drvdata(pdev, gf);
++
++ if (gf->debug)
++ dev_info(gf->dev, "Start -> %s\n", gf->start_state->name);
++
++ gpio_fsm_go_to_state(gf, gf->start_state);
++
++ return devm_gpiochip_add_data(dev, &gf->gc, gf);
++}
++
++static int gpio_fsm_remove(struct platform_device *pdev)
++{
++ struct gpio_fsm *gf = platform_get_drvdata(pdev);
++ int i;
++
++ if (gf->shutdown_state) {
++ if (gf->debug)
++ dev_info(gf->dev, "Shutting down...\n");
++
++ spin_lock(&gf->spinlock);
++ gf->shutting_down = true;
++ if (gf->current_state->shutdown_target &&
++ gf->current_state->shutdown_target != gf->current_state) {
++ gf->delay_target_state =
++ gf->current_state->shutdown_target;
++ mod_timer(&gf->timer, gf->shutdown_jiffies);
++ }
++ spin_unlock(&gf->spinlock);
++
++ wait_event_timeout(gf->shutdown_event,
++ gf->current_state->shutdown_target ==
++ gf->current_state,
++ msecs_to_jiffies(gf->shutdown_timeout_ms));
++ if (gf->current_state->shutdown_target == gf->current_state)
++ gpio_fsm_enter_state(gf, gf->shutdown_state);
++ }
++ cancel_work_sync(&gf->work);
++ del_timer_sync(&gf->timer);
++
++ /* Events aren't allocated from managed storage */
++ for (i = 0; i < gf->num_states; i++) {
++ kfree(gf->states[i].gpio_events);
++ kfree(gf->states[i].soft_events);
++ }
++ if (gf->debug)
++ dev_info(gf->dev, "Exiting\n");
++
++ return 0;
++}
++
++static void gpio_fsm_shutdown(struct platform_device *pdev)
++{
++ gpio_fsm_remove(pdev);
++}
++
++static const struct of_device_id gpio_fsm_ids[] = {
++ { .compatible = "rpi,gpio-fsm" },
++ { }
++};
++MODULE_DEVICE_TABLE(of, gpio_fsm_ids);
++
++static struct platform_driver gpio_fsm_driver = {
++ .driver = {
++ .name = MODULE_NAME,
++ .of_match_table = of_match_ptr(gpio_fsm_ids),
++ },
++ .probe = gpio_fsm_probe,
++ .remove = gpio_fsm_remove,
++ .shutdown = gpio_fsm_shutdown,
++};
++module_platform_driver(gpio_fsm_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>");
++MODULE_DESCRIPTION("GPIO FSM driver");
++MODULE_ALIAS("platform:gpio-fsm");
+--- /dev/null
++++ b/include/dt-bindings/gpio/gpio-fsm.h
+@@ -0,0 +1,21 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
++/*
++ * This header provides constants for binding rpi,gpio-fsm.
++ */
++
++#ifndef _DT_BINDINGS_GPIO_FSM_H
++#define _DT_BINDINGS_GPIO_FSM_H
++
++#define GF_IN 0
++#define GF_OUT 1
++#define GF_SOFT 2
++#define GF_DELAY 3
++#define GF_SHUTDOWN 4
++
++#define GF_IO(t, v) (((v) << 16) | ((t) & 0xffff))
++
++#define GF_IP(x) GF_IO(GF_IN, (x))
++#define GF_OP(x) GF_IO(GF_OUT, (x))
++#define GF_SW(x) GF_IO(GF_SOFT, (x))
++
++#endif
diff --git a/target/linux/bcm27xx/patches-5.4/950-0987-overlays-Add-fsm-demo-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0987-overlays-Add-fsm-demo-overlay.patch
new file mode 100644
index 0000000000..7b56627447
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0987-overlays-Add-fsm-demo-overlay.patch
@@ -0,0 +1,151 @@
+From d27d1447e49bc6ffa92f787f7bc5c2eea29ba7d2 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 30 Sep 2020 12:08:08 +0100
+Subject: [PATCH] overlays: Add fsm-demo overlay
+
+fsm-demo demonstrates the usage of the gpio-fsm driver. It is
+designed to be used with a set of "traffic light" LEDs on GPIOs
+7, 8 and 25.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 8 ++
+ .../boot/dts/overlays/fsm-demo-overlay.dts | 104 ++++++++++++++++++
+ 3 files changed, 113 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/fsm-demo-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -44,6 +44,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ enc28j60-spi2.dtbo \
+ exc3000.dtbo \
+ fe-pi-audio.dtbo \
++ fsm-demo.dtbo \
+ goodix.dtbo \
+ googlevoicehat-soundcard.dtbo \
+ gpio-fan.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -767,6 +767,14 @@ Load: dtoverlay=fe-pi-audio
+ Params: <None>
+
+
++Name: fsm-demo
++Info: A demonstration of the gpio-fsm driver. The GPIOs are chosen to work
++ nicely with a "traffic-light" display of red, amber and green LEDs on
++ GPIOs 7, 8 and 25 respectively.
++Load: dtoverlay=fsm-demo,<param>=<val>
++Params: fsm_debug Enable debug logging (default off)
++
++
+ 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.
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/fsm-demo-overlay.dts
+@@ -0,0 +1,104 @@
++// Demo overlay for the gpio-fsm driver
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio-fsm.h>
++
++#define BUTTON1 GF_IP(0)
++#define BUTTON2 GF_SW(0)
++#define RED GF_OP(0) // GPIO7
++#define AMBER GF_OP(1) // GPIO8
++#define GREEN GF_OP(2) // GPIO25
++
++/{
++ compatible = "brcm,bcm2835";
++
++ fragment@0 {
++ target-path = "/";
++ __overlay__ {
++ fsm_demo: fsm-demo {
++ compatible = "rpi,gpio-fsm";
++
++ debug = <0>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ num-soft-gpios = <1>;
++ gpio-line-names = "button2";
++ input-gpios = <&gpio 6 1>; // BUTTON1 (active-low)
++ output-gpios = <&gpio 7 0>, // RED
++ <&gpio 8 0>, // AMBER
++ <&gpio 25 0>; // GREEN
++ shutdown-timeout-ms = <2000>;
++
++ start {
++ start_state;
++ set = <RED 1>, <AMBER 0>, <GREEN 0>;
++ start2 = <GF_DELAY 250>;
++ };
++
++ start2 {
++ set = <RED 0>, <AMBER 1>;
++ go = <GF_DELAY 250>;
++ };
++
++ go {
++ set = <RED 0>, <AMBER 0>, <GREEN 1>;
++ ready_wait = <BUTTON1 0>;
++ shutdown1 = <GF_SHUTDOWN 0>;
++ };
++
++ ready_wait {
++ // Clear the soft GPIO
++ set = <BUTTON2 0>;
++ ready = <GF_DELAY 1000>;
++ shutdown1 = <GF_SHUTDOWN 0>;
++ };
++
++ ready {
++ stopping = <BUTTON1 1>, <BUTTON2 1>;
++ shutdown1 = <GF_SHUTDOWN 0>;
++ };
++
++ stopping {
++ set = <GREEN 0>, <AMBER 1>;
++ stopped = <GF_DELAY 1000>;
++ };
++
++ stopped {
++ set = <AMBER 0>, <RED 1>;
++ get_set = <GF_DELAY 3000>;
++ shutdown1 = <GF_SHUTDOWN 0>;
++ };
++
++ get_set {
++ set = <AMBER 1>;
++ go = <GF_DELAY 1000>;
++ };
++
++ shutdown1 {
++ set = <RED 0>, <AMBER 0>, <GREEN 1>;
++ shutdown2 = <GF_SHUTDOWN 250>;
++ };
++
++ shutdown2 {
++ set = <AMBER 1>, <GREEN 0>;
++ shutdown3 = <GF_SHUTDOWN 250>;
++ };
++
++ shutdown3 {
++ set = <RED 1>, <AMBER 0>;
++ shutdown4 = <GF_SHUTDOWN 250>;
++ };
++
++ shutdown4 {
++ shutdown_state;
++ set = <RED 0>;
++ };
++ };
++ };
++ };
++
++ __overrides__ {
++ fsm_debug = <&fsm_demo>,"debug:0";
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-0988-overlays-Add-ghost-amp-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0988-overlays-Add-ghost-amp-overlay.patch
new file mode 100644
index 0000000000..7404bf7f7a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0988-overlays-Add-ghost-amp-overlay.patch
@@ -0,0 +1,163 @@
+From 96f25d50e2352922e16ae74bb16fd8b6985f0f66 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 30 Sep 2020 12:17:48 +0100
+Subject: [PATCH] overlays: Add ghost-amp overlay
+
+Add an overlay for the Ghost amplifier.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 7 ++
+ .../boot/dts/overlays/ghost-amp-overlay.dts | 119 ++++++++++++++++++
+ 3 files changed, 127 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/ghost-amp-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -45,6 +45,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ exc3000.dtbo \
+ fe-pi-audio.dtbo \
+ fsm-demo.dtbo \
++ ghost-amp.dtbo \
+ goodix.dtbo \
+ googlevoicehat-soundcard.dtbo \
+ gpio-fan.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -775,6 +775,13 @@ Load: dtoverlay=fsm-demo,<param>=<val>
+ Params: fsm_debug Enable debug logging (default off)
+
+
++Name: ghost-amp
++Info: An overlay for the Ghost amplifier.
++Load: dtoverlay=ghost-amp,<param>=<val>
++Params: fsm_debug Enable debug logging of the GPIO FSM (default
++ off)
++
++
+ 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.
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/ghost-amp-overlay.dts
+@@ -0,0 +1,119 @@
++// Overlay for the PCM5122-based Ghost amplifier using gpio-fsm
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio-fsm.h>
++
++#define ENABLE GF_SW(0)
++#define FAULT GF_IP(0) // GPIO5
++#define RELAY1 GF_OP(0) // GPIO22
++#define RELAY2 GF_OP(1) // GPIO23
++
++/ {
++ compatible = "brcm,bcm2835";
++
++ 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 = <&amp 0 0>;
++ iqaudio-dac,auto-mute-amp;
++ status = "okay";
++ };
++ };
++
++ fragment@3 {
++ target-path = "/";
++ __overlay__ {
++ amp: ghost-amp {
++ compatible = "rpi,gpio-fsm";
++
++ debug = <0>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ num-soft-gpios = <1>;
++ gpio-line-names = "enable";
++ input-gpios = <&gpio 5 1>; // FAULT (active low)
++ output-gpios = <&gpio 22 0>, // RELAY1
++ <&gpio 23 0>; // RELAY2
++ shutdown-timeout-ms = <1000>;
++
++ amp_off {
++ start_state;
++ shutdown_state;
++
++ set = <RELAY2 0>,
++ <RELAY1 0>;
++ amp_on_1 = <ENABLE 1>;
++ fault = <FAULT 1>;
++ };
++
++ amp_on_1 {
++ set = <RELAY1 1>;
++ amp_on = <GF_DELAY 1500>;
++ amp_off = <ENABLE 0>;
++ fault = <FAULT 1>;
++ };
++
++ amp_on {
++ set = <RELAY2 1>;
++ amp_off_wait = <ENABLE 0>;
++ fault = <FAULT 1>;
++ };
++
++ amp_off_wait {
++ amp_off_1 = <GF_DELAY (30*60*1000)>,
++ <GF_SHUTDOWN 0>;
++ amp_on = <ENABLE 1>;
++ fault = <FAULT 1>;
++ };
++
++ amp_off_1 {
++ set = <RELAY2 0>;
++ amp_on = <ENABLE 1>;
++ amp_off = <GF_DELAY 100>;
++ fault = <FAULT 1>;
++ };
++
++ // Keep this a distinct state to prevent
++ // changes and for the diagnostic output
++ fault {
++ set = <RELAY2 0>,
++ <RELAY1 0>;
++ shutdown_state;
++ };
++ };
++ };
++ };
++
++ __overrides__ {
++ fsm_debug = <&amp>,"debug:0";
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-0989-Bluetooth-Disable-High-Speed-by-default.patch b/target/linux/bcm27xx/patches-5.4/950-0989-Bluetooth-Disable-High-Speed-by-default.patch
new file mode 100644
index 0000000000..03173126c4
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0989-Bluetooth-Disable-High-Speed-by-default.patch
@@ -0,0 +1,26 @@
+From 8ccf890b3514c07c0596a8a3e389e08fd00c0d8e Mon Sep 17 00:00:00 2001
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Date: Thu, 6 Aug 2020 11:17:13 -0700
+Subject: [PATCH] Bluetooth: Disable High Speed by default
+
+commit b176dd0ef6afcb3bca24f41d78b0d0b731ec2d08 upstream.
+
+Bluetooth High Speed requires hardware support which is very uncommon
+nowadays since HS has not pickup interest by the industry.
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+---
+ net/bluetooth/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/net/bluetooth/Kconfig
++++ b/net/bluetooth/Kconfig
+@@ -64,7 +64,6 @@ source "net/bluetooth/hidp/Kconfig"
+ config BT_HS
+ bool "Bluetooth High Speed (HS) features"
+ depends on BT_BREDR
+- default y
+ help
+ Bluetooth High Speed includes support for off-loading
+ Bluetooth connections via 802.11 (wifi) physical layer
diff --git a/target/linux/bcm27xx/patches-5.4/950-0990-Fixes-a-problem-when-module-probes-before-i2c-module.patch b/target/linux/bcm27xx/patches-5.4/950-0990-Fixes-a-problem-when-module-probes-before-i2c-module.patch
new file mode 100644
index 0000000000..e9397727e9
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0990-Fixes-a-problem-when-module-probes-before-i2c-module.patch
@@ -0,0 +1,46 @@
+From bc55eb17b46668e70dfbd1a091159935d8f95eb9 Mon Sep 17 00:00:00 2001
+From: Joerg Schambacher <joerg@i2audio.com>
+Date: Fri, 16 Oct 2020 15:17:07 +0200
+Subject: [PATCH] Fixes a problem when module probes before i2c
+ module is available
+
+The driver crashed while a NULL pointer returned by i2c_get_adapter()
+has been used to access the i2c bus functions.
+The headphone probing function hb_hp_probe() now returns -EPROBE_DEFER
+in case the i2c module has not been loaded yet.
+
+Signed-off-by: Joerg Schambacher <joerg@i2audio.com>
+---
+ sound/soc/bcm/hifiberry_dacplus.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/bcm/hifiberry_dacplus.c
++++ b/sound/soc/bcm/hifiberry_dacplus.c
+@@ -315,12 +315,14 @@ static int hb_hp_detect(void)
+ {
+ struct i2c_adapter *adap = i2c_get_adapter(1);
+ int ret;
+-
+ struct i2c_client tpa_i2c_client = {
+ .addr = 0x60,
+ .adapter = adap,
+ };
+
++ if (!adap)
++ return -EPROBE_DEFER; /* I2C module not yet available */
++
+ ret = i2c_smbus_read_byte(&tpa_i2c_client) >= 0;
+ i2c_put_adapter(adap);
+ return ret;
+@@ -342,7 +344,10 @@ static int snd_rpi_hifiberry_dacplus_pro
+ struct of_changeset ocs;
+
+ /* probe for head phone amp */
+- if (hb_hp_detect()) {
++ ret = hb_hp_detect();
++ if (ret < 0)
++ return ret;
++ if (ret) {
+ card->aux_dev = hifiberry_dacplus_aux_devs;
+ card->num_aux_devs =
+ ARRAY_SIZE(hifiberry_dacplus_aux_devs);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0991-uapi-Update-V4L2_CID_USER_BCM2835_ISP_BASE-due-to-up.patch b/target/linux/bcm27xx/patches-5.4/950-0991-uapi-Update-V4L2_CID_USER_BCM2835_ISP_BASE-due-to-up.patch
new file mode 100644
index 0000000000..71c27e168a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0991-uapi-Update-V4L2_CID_USER_BCM2835_ISP_BASE-due-to-up.patch
@@ -0,0 +1,41 @@
+From 90e833fddb15bbdd8aeb6285ba596b4c657383c2 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 15 Oct 2020 11:59:02 +0100
+Subject: [PATCH] uapi: Update V4L2_CID_USER_BCM2835_ISP_BASE due to
+ upstream change
+
+Commit "4e52889 media: atmel: atmel-isc-base: expose white
+balance as v4l2 controls" in the upstream kernels reserves
+(V4L2_CID_USER_BASE + 0x10c0) for use by the Atmel ISC,
+therefore we have a control collision with our existing
+define for V4L2_CID_USER_BCM2835_ISP_BASE.
+
+Update V4L2_CID_USER_BCM2835_ISP_BASE to + 0x10e0 as the
+next available block.
+
+NB ABI breakage for libcamera (the only user of these controls).
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ include/uapi/linux/v4l2-controls.h | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/include/uapi/linux/v4l2-controls.h
++++ b/include/uapi/linux/v4l2-controls.h
+@@ -192,9 +192,15 @@ enum v4l2_colorfx {
+ * We reserve 16 controls for this driver. */
+ #define V4L2_CID_USER_IMX_BASE (V4L2_CID_USER_BASE + 0x10b0)
+
++/*
++ * The base for the atmel isc driver controls.
++ * We reserve 32 controls for this driver.
++ */
++#define V4L2_CID_USER_ATMEL_ISC_BASE (V4L2_CID_USER_BASE + 0x10c0)
++
+ /* The base for the bcm2835-isp driver controls.
+ * We reserve 16 controls for this driver. */
+-#define V4L2_CID_USER_BCM2835_ISP_BASE (V4L2_CID_USER_BASE + 0x10c0)
++#define V4L2_CID_USER_BCM2835_ISP_BASE (V4L2_CID_USER_BASE + 0x10e0)
+
+ /* MPEG-class control IDs */
+ /* The MPEG controls are applicable to all codec controls
diff --git a/target/linux/bcm27xx/patches-5.4/950-0992-dtoverlays-Correct-CSI2-settings-for-ov9281.patch b/target/linux/bcm27xx/patches-5.4/950-0992-dtoverlays-Correct-CSI2-settings-for-ov9281.patch
new file mode 100644
index 0000000000..84a4e98de1
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0992-dtoverlays-Correct-CSI2-settings-for-ov9281.patch
@@ -0,0 +1,36 @@
+From ac315f66be96c5a423382efb559f193e5b786226 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 21 Oct 2020 18:33:02 +0100
+Subject: [PATCH] dtoverlays: Correct CSI2 settings for ov9281
+
+OV9281 appears to drop the clock to LP mode between frames, but
+the overlay didn't define this at both ends of the CSI2 link.
+The overlay also had an incorrect link frequency defined, not that
+the driver ever checked for one.
+
+Fix both issues.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/ov9281-overlay.dts | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/ov9281-overlay.dts
++++ b/arch/arm/boot/dts/overlays/ov9281-overlay.dts
+@@ -34,7 +34,7 @@
+ data-lanes = <1 2>;
+ clock-noncontinuous;
+ link-frequencies =
+- /bits/ 64 <456000000>;
++ /bits/ 64 <400000000>;
+ };
+ };
+ };
+@@ -50,6 +50,7 @@
+ csi1_ep: endpoint {
+ remote-endpoint = <&ov9281_0>;
+ data-lanes = <1 2>;
++ clock-noncontinuous;
+ };
+ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0993-xhci-quirks-add-link-TRB-quirk-for-VL805.patch b/target/linux/bcm27xx/patches-5.4/950-0993-xhci-quirks-add-link-TRB-quirk-for-VL805.patch
new file mode 100644
index 0000000000..3c89f1348f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0993-xhci-quirks-add-link-TRB-quirk-for-VL805.patch
@@ -0,0 +1,61 @@
+From 510fccc1a7533aa9f46d97ad500fe45ab7f91010 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.org>
+Date: Mon, 26 Oct 2020 14:03:35 +0000
+Subject: [PATCH] xhci: quirks: add link TRB quirk for VL805
+
+The VL805 controller can't cope with the TR Dequeue Pointer for an endpoint
+being set to a Link TRB. The hardware-maintained endpoint context ends up
+stuck at the address of the Link TRB, leading to erroneous ring expansion
+events whenever the enqueue pointer wraps to the dequeue position.
+
+If the search for the end of the current TD and ring cycle state lands on
+a Link TRB, move to the next segment.
+
+See: https://github.com/raspberrypi/linux/issues/3919
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/usb/host/xhci-pci.c | 1 +
+ drivers/usb/host/xhci-ring.c | 10 ++++++++++
+ drivers/usb/host/xhci.h | 1 +
+ 3 files changed, 12 insertions(+)
+
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -258,6 +258,7 @@ static void xhci_pci_quirks(struct devic
+ pdev->device == 0x3483) {
+ xhci->quirks |= XHCI_LPM_SUPPORT;
+ xhci->quirks |= XHCI_EP_CTX_BROKEN_DCS;
++ xhci->quirks |= XHCI_AVOID_DQ_ON_LINK;
+ }
+
+ if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -624,6 +624,16 @@ void xhci_find_new_dequeue_state(struct
+
+ } while (!cycle_found || !td_last_trb_found);
+
++ /*
++ * Quirk: the xHC does not correctly parse link TRBs if the HW Dequeue
++ * pointer is set to one. Advance to the next TRB (and next segment).
++ */
++ if (xhci->quirks & XHCI_AVOID_DQ_ON_LINK && trb_is_link(new_deq)) {
++ if (link_trb_toggles_cycle(new_deq))
++ state->new_cycle_state ^= 0x1;
++ next_trb(xhci, ep_ring, &new_seg, &new_deq);
++ }
++
+ state->new_deq_seg = new_seg;
+ state->new_deq_ptr = new_deq;
+
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1876,6 +1876,7 @@ struct xhci_hcd {
+ #define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(36)
+ #define XHCI_SKIP_PHY_INIT BIT_ULL(37)
+ #define XHCI_DISABLE_SPARSE BIT_ULL(38)
++#define XHCI_AVOID_DQ_ON_LINK BIT_ULL(39)
+
+ unsigned int num_active_eps;
+ unsigned int limit_active_eps;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0994-dts-Add-CM4-to-arm64-dt-files.patch b/target/linux/bcm27xx/patches-5.4/950-0994-dts-Add-CM4-to-arm64-dt-files.patch
new file mode 100644
index 0000000000..03d0fe8393
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0994-dts-Add-CM4-to-arm64-dt-files.patch
@@ -0,0 +1,28 @@
+From 0ea39ee546de55f9dcf5729f1e39ebc2747477ba Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 23 Oct 2020 15:45:11 +0100
+Subject: [PATCH] dts: Add CM4 to arm64 dt files
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm64/boot/dts/broadcom/Makefile | 3 ++-
+ arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4.dts | 1 +
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4.dts
+
+--- a/arch/arm64/boot/dts/broadcom/Makefile
++++ b/arch/arm64/boot/dts/broadcom/Makefile
+@@ -7,7 +7,8 @@ dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rp
+ dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-3-b.dtb
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-2-b.dtb
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b.dtb
+-dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb
++dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb \
++ bcm2711-rpi-cm4.dtb
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b-plus.dtb
+ dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-cm3.dtb
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-cm3.dtb
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4.dts
+@@ -0,0 +1 @@
++#include "../../../../arm/boot/dts/bcm2711-rpi-cm4.dts"
diff --git a/target/linux/bcm27xx/patches-5.4/950-0995-dts-Tidy-the-Raspberry-Pi-Makefile-entries.patch b/target/linux/bcm27xx/patches-5.4/950-0995-dts-Tidy-the-Raspberry-Pi-Makefile-entries.patch
new file mode 100644
index 0000000000..af427f44d9
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0995-dts-Tidy-the-Raspberry-Pi-Makefile-entries.patch
@@ -0,0 +1,43 @@
+From fd3620d39c813e9846ace3511bc96a868b5be61a Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 26 Oct 2020 15:01:21 +0000
+Subject: [PATCH] dts: Tidy the Raspberry Pi Makefile entries
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/Makefile | 2 +-
+ arch/arm64/boot/dts/broadcom/Makefile | 7 ++-----
+ 2 files changed, 3 insertions(+), 6 deletions(-)
+
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -10,8 +10,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
+ bcm2709-rpi-2-b.dtb \
+ bcm2710-rpi-2-b.dtb \
+ bcm2710-rpi-3-b.dtb \
+- bcm2711-rpi-4-b.dtb \
+ bcm2710-rpi-3-b-plus.dtb \
++ bcm2711-rpi-4-b.dtb \
+ bcm2710-rpi-cm3.dtb \
+ bcm2711-rpi-cm4.dtb
+
+--- a/arch/arm64/boot/dts/broadcom/Makefile
++++ b/arch/arm64/boot/dts/broadcom/Makefile
+@@ -3,15 +3,12 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rp
+ bcm2837-rpi-3-b.dtb \
+ bcm2837-rpi-3-b-plus.dtb \
+ bcm2837-rpi-cm3-io3.dtb
+-dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-2-b.dtb
+-dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-3-b.dtb
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-2-b.dtb
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b.dtb
+-dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb \
+- bcm2711-rpi-cm4.dtb
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b-plus.dtb
+-dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-cm3.dtb
++dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-cm3.dtb
++dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-cm4.dtb
+
+ subdir-y += northstar2
+ subdir-y += stingray
diff --git a/target/linux/bcm27xx/patches-5.4/950-0996-staging-bcm2835-audio-Add-disable-headphones-flag.patch b/target/linux/bcm27xx/patches-5.4/950-0996-staging-bcm2835-audio-Add-disable-headphones-flag.patch
new file mode 100644
index 0000000000..3c30745714
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0996-staging-bcm2835-audio-Add-disable-headphones-flag.patch
@@ -0,0 +1,34 @@
+From af217539bab20a3bba6e1bbd4e4c8f68e7644e50 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 26 Oct 2020 10:23:22 +0000
+Subject: [PATCH] staging: bcm2835-audio: Add disable-headphones flag
+
+Add a property to allow the headphone output to be disabled. Use an
+integer property rather than a boolean so that an overlay can clear it.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c
++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c
+@@ -381,11 +381,16 @@ static int snd_bcm2835_alsa_probe(struct
+ }
+
+ if (!enable_compat_alsa) {
++ // In this mode, enable analog output by default
++ u32 disable_headphones = 0;
++
+ if (!of_property_read_bool(dev->of_node, "brcm,disable-hdmi"))
+ set_hdmi_enables(dev);
+
+- // In this mode, always enable analog output
+- enable_headphones = true;
++ of_property_read_u32(dev->of_node,
++ "brcm,disable-headphones",
++ &disable_headphones);
++ enable_headphones = !disable_headphones;
+ } else {
+ enable_hdmi0 = enable_hdmi;
+ }
diff --git a/target/linux/bcm27xx/patches-5.4/950-0997-ARM-dts-Disable-headphone-audio-on-Zeroes-CM4.patch b/target/linux/bcm27xx/patches-5.4/950-0997-ARM-dts-Disable-headphone-audio-on-Zeroes-CM4.patch
new file mode 100644
index 0000000000..475d0a8842
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0997-ARM-dts-Disable-headphone-audio-on-Zeroes-CM4.patch
@@ -0,0 +1,42 @@
+From 9fc10178e1130b43ccc8b855a73fb22643963da0 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 26 Oct 2020 10:18:50 +0000
+Subject: [PATCH] ARM: dts: Disable headphone audio on Zeroes, CM4
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 1 +
+ arch/arm/boot/dts/bcm2708-rpi-zero.dts | 1 +
+ arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 1 +
+ 3 files changed, 3 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts
+@@ -152,6 +152,7 @@
+ &audio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&audio_pins>;
++ brcm,disable-headphones = <1>;
+ };
+
+ / {
+--- a/arch/arm/boot/dts/bcm2708-rpi-zero.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts
+@@ -106,6 +106,7 @@
+ &audio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&audio_pins>;
++ brcm,disable-headphones = <1>;
+ };
+
+ / {
+--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
+@@ -460,6 +460,7 @@
+ &audio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&audio_pins>;
++ brcm,disable-headphones = <1>;
+ };
+
+ &vc4 {
diff --git a/target/linux/bcm27xx/patches-5.4/950-0998-overlays-Enable-headphone-audio-in-audremap.patch b/target/linux/bcm27xx/patches-5.4/950-0998-overlays-Enable-headphone-audio-in-audremap.patch
new file mode 100644
index 0000000000..e206ca42ed
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0998-overlays-Enable-headphone-audio-in-audremap.patch
@@ -0,0 +1,26 @@
+From 4a69ef912ed791855fcc058230eed14342c6cd02 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 26 Oct 2020 10:21:23 +0000
+Subject: [PATCH] overlays: Enable headphone audio in audremap
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/audremap-overlay.dts | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/audremap-overlay.dts
++++ b/arch/arm/boot/dts/overlays/audremap-overlay.dts
+@@ -26,6 +26,13 @@
+ };
+ };
+
++ fragment@3 {
++ target = <&audio>;
++ __overlay__ {
++ brcm,disable-headphones = <0>;
++ };
++ };
++
+ __overrides__ {
+ swap_lr = <&frag0>, "swap_lr?";
+ enable_jack = <&frag0>, "enable_jack?";
diff --git a/target/linux/bcm27xx/patches-5.4/950-0999-rpisense-fb-Set-pseudo_pallete-to-prevent-crash-on-f.patch b/target/linux/bcm27xx/patches-5.4/950-0999-rpisense-fb-Set-pseudo_pallete-to-prevent-crash-on-f.patch
new file mode 100644
index 0000000000..66d9c694c5
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0999-rpisense-fb-Set-pseudo_pallete-to-prevent-crash-on-f.patch
@@ -0,0 +1,30 @@
+From 24a2cc7c39f7232b5256dc8adb2f2e87ee1062ec Mon Sep 17 00:00:00 2001
+From: Serge Schneider <serge@raspberrypi.com>
+Date: Mon, 26 Oct 2020 16:38:21 +0000
+Subject: [PATCH] rpisense-fb: Set pseudo_pallete to prevent crash on
+ fbcon takeover
+
+Signed-off-by: Serge Schneider <serge@raspberrypi.com>
+---
+ drivers/video/fbdev/rpisense-fb.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/video/fbdev/rpisense-fb.c
++++ b/drivers/video/fbdev/rpisense-fb.c
+@@ -52,6 +52,8 @@ static u8 gamma_low[32] = {0x00, 0x01, 0
+
+ static u8 gamma_user[32];
+
++static u32 pseudo_palette[16];
++
+ static struct rpisense_fb_param rpisense_fb_param = {
+ .vmem = NULL,
+ .vmemsize = 128,
+@@ -225,6 +227,7 @@ static int rpisense_fb_probe(struct plat
+ info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
+ info->screen_base = rpisense_fb_param.vmem;
+ info->screen_size = rpisense_fb_param.vmemsize;
++ info->pseudo_palette = pseudo_palette;
+
+ if (lowlight)
+ rpisense_fb_param.gamma = gamma_low;
diff --git a/target/linux/bcm27xx/patches-5.4/950-1000-PiFi-40-Devicetree-files.patch b/target/linux/bcm27xx/patches-5.4/950-1000-PiFi-40-Devicetree-files.patch
new file mode 100644
index 0000000000..06f5da66e7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1000-PiFi-40-Devicetree-files.patch
@@ -0,0 +1,91 @@
+From a822d6667a687451cdf65aef66ecc7fa15891205 Mon Sep 17 00:00:00 2001
+From: David Knell <david.knell@gmail.com>
+Date: Wed, 28 Oct 2020 14:20:56 +0000
+Subject: [PATCH] PiFi-40 Devicetree files
+
+Signed-off-by: David Knell <david.knell@gmail.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 6 +++
+ .../arm/boot/dts/overlays/pifi-40-overlay.dts | 50 +++++++++++++++++++
+ 3 files changed, 57 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/pifi-40-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -125,6 +125,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ pca953x.dtbo \
+ pibell.dtbo \
+ pifacedigital.dtbo \
++ pifi-40.dtbo \
+ piglow.dtbo \
+ piscreen.dtbo \
+ piscreen2r.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -2000,6 +2000,12 @@ Params: spi-present-mask 8-bit in
+ 0-3, which can be configured with JP1 and JP2.
+
+
++Name: pifi-40
++Info: Configures the PiFi 40W stereo amplifier
++Load: dtoverlay=pifi-40
++Params: <None>
++
++
+ Name: piglow
+ Info: Configures the PiGlow by pimoroni.com
+ Load: dtoverlay=piglow
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/pifi-40-overlay.dts
+@@ -0,0 +1,50 @@
++// Definitions for PiFi-40 Amp
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++/ {
++ compatible = "brcm,bcm2835";
++
++ fragment@0 {
++ target = <&i2s>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@1 {
++ target = <&i2c1>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ tas5711l: audio-codec@1a {
++ compatible = "ti,tas5711";
++ reg = <0x1a>;
++ #sound-dai-cells = <0>;
++ sound-name-prefix = "Left";
++ status = "okay";
++ };
++
++ tas5711r: audio-codec@1b {
++ compatible = "ti,tas5711";
++ reg = <0x1b>;
++ #sound-dai-cells = <0>;
++ sound-name-prefix = "Right";
++ status = "okay";
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&sound>;
++ pifi_40: __overlay__ {
++ compatible = "pifi,pifi-40";
++ audio-codec = <&tas5711l &tas5711r>;
++ i2s-controller = <&i2s>;
++ pdn-gpios = <&gpio 23 1>;
++ status = "okay";
++ };
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-1001-PiFi-40-driver-Makefile-and-Kconfig.patch b/target/linux/bcm27xx/patches-5.4/950-1001-PiFi-40-driver-Makefile-and-Kconfig.patch
new file mode 100644
index 0000000000..5c584f4971
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1001-PiFi-40-driver-Makefile-and-Kconfig.patch
@@ -0,0 +1,331 @@
+From b7bbdd72e5c9e1b7538b74deb584a7ab0f85847d Mon Sep 17 00:00:00 2001
+From: David Knell <david.knell@gmail.com>
+Date: Wed, 28 Oct 2020 14:21:37 +0000
+Subject: [PATCH] PiFi-40 driver, Makefile and Kconfig
+
+Signed-off-by: David Knell <david.knell@gmail.com>
+---
+ sound/soc/bcm/Kconfig | 8 ++
+ sound/soc/bcm/Makefile | 3 +
+ sound/soc/bcm/pifi-40.c | 282 ++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 293 insertions(+)
+ create mode 100644 sound/soc/bcm/pifi-40.c
+
+--- a/sound/soc/bcm/Kconfig
++++ b/sound/soc/bcm/Kconfig
+@@ -91,6 +91,14 @@ config SND_BCM2708_SOC_HIFIBERRY_AMP
+ help
+ Say Y or M if you want to add support for the HifiBerry Amp amplifier board.
+
++ config SND_BCM2708_SOC_PIFI_40
++ tristate "Support for the PiFi-40 amp"
++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
++ select SND_SOC_TAS571X
++ select SND_PIFI_40
++ help
++ Say Y or M if you want to add support for the PiFi40 amp board
++
+ config SND_BCM2708_SOC_RPI_CIRRUS
+ tristate "Support for Cirrus Logic Audio Card"
+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
+--- a/sound/soc/bcm/Makefile
++++ b/sound/soc/bcm/Makefile
+@@ -40,6 +40,7 @@ snd-soc-pisound-objs := pisound.o
+ snd-soc-fe-pi-audio-objs := fe-pi-audio.o
+ snd-soc-rpi-simple-soundcard-objs := rpi-simple-soundcard.o
+ snd-soc-rpi-wm8804-soundcard-objs := rpi-wm8804-soundcard.o
++snd-soc-pifi-40-objs := pifi-40.o
+
+ obj-$(CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD) += snd-soc-googlevoicehat-codec.o
+ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o
+@@ -69,3 +70,5 @@ obj-$(CONFIG_SND_PISOUND) += snd-soc-pis
+ obj-$(CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO) += snd-soc-fe-pi-audio.o
+ obj-$(CONFIG_SND_RPI_SIMPLE_SOUNDCARD) += snd-soc-rpi-simple-soundcard.o
+ obj-$(CONFIG_SND_RPI_WM8804_SOUNDCARD) += snd-soc-rpi-wm8804-soundcard.o
++obj-$(CONFIG_SND_BCM2708_SOC_PIFI_40) += snd-soc-pifi-40.o
++
+--- /dev/null
++++ b/sound/soc/bcm/pifi-40.c
+@@ -0,0 +1,282 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * ALSA ASoC Machine Driver for PiFi-40
++ *
++ * Author: David Knell <david.knell@gmail.com)
++ * based on code by Daniel Matuschek <info@crazy-audio.com>
++ * based on code by Florian Meier <florian.meier@koalo.de>
++ * Copyright (C) 2020
++ *
++ * 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 <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/gpio/consumer.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <linux/firmware.h>
++#include <linux/delay.h>
++#include <sound/tlv.h>
++
++static struct gpio_desc *pdn_gpio;
++static int vol = 0x30;
++
++// Volume control
++static int pifi_40_vol_get(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ ucontrol->value.integer.value[0] = vol;
++ ucontrol->value.integer.value[1] = vol;
++ return 0;
++}
++
++static int pifi_40_vol_set(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
++ struct snd_soc_pcm_runtime *rtd;
++ unsigned int v = ucontrol->value.integer.value[0];
++ struct snd_soc_component *dac[2];
++
++ rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
++ dac[0] = rtd->codec_dais[0]->component;
++ dac[1] = rtd->codec_dais[1]->component;
++
++ snd_soc_component_write(dac[0], 0x07, 255 - v);
++ snd_soc_component_write(dac[1], 0x07, 255 - v);
++
++ vol = v;
++ return 1;
++}
++
++static const DECLARE_TLV_DB_SCALE(digital_tlv_master, -10350, 50, 1);
++static const struct snd_kcontrol_new pifi_40_controls[] = {
++ SOC_DOUBLE_R_EXT_TLV("Master Volume", 0x00, 0x01,
++ 0x00, // Min
++ 0xff, // Max
++ 0x01, // Invert
++ pifi_40_vol_get, pifi_40_vol_set,
++ digital_tlv_master)
++};
++
++static const char * const codec_ctl_pfx[] = { "Left", "Right" };
++
++static const char * const codec_ctl_name[] = { "Master Volume",
++ "Speaker Volume",
++ "Speaker Switch" };
++
++static int snd_pifi_40_init(struct snd_soc_pcm_runtime *rtd)
++{
++ struct snd_soc_card *card = rtd->card;
++ struct snd_soc_component *dac[2];
++ struct snd_kcontrol *kctl;
++ int i, j;
++
++ dac[0] = rtd->codec_dais[0]->component;
++ dac[1] = rtd->codec_dais[1]->component;
++
++ // Set up cards - pulse power down first
++ gpiod_set_value_cansleep(pdn_gpio, 1);
++ usleep_range(1000, 10000);
++ gpiod_set_value_cansleep(pdn_gpio, 0);
++ usleep_range(20000, 30000);
++
++ // Oscillator trim
++ snd_soc_component_write(dac[0], 0x1b, 0);
++ snd_soc_component_write(dac[1], 0x1b, 0);
++ usleep_range(60000, 80000);
++
++ // Common setup
++ for (i = 0; i < 2; i++) {
++ // MCLK at 64fs, sample rate 44.1 or 48kHz
++ snd_soc_component_write(dac[i], 0x00, 0x60);
++
++ // Set up for PBTL
++ snd_soc_component_write(dac[i], 0x19, 0x3A);
++ snd_soc_component_write(dac[i], 0x25, 0x01103245);
++
++ // Master vol to -10db
++ snd_soc_component_write(dac[i], 0x07, 0x44);
++ }
++ // Inputs set to L and R respectively
++ snd_soc_component_write(dac[0], 0x20, 0x00017772);
++ snd_soc_component_write(dac[1], 0x20, 0x00107772);
++
++ // Remove codec controls
++ for (i = 0; i < 2; i++) {
++ for (j = 0; j < 3; j++) {
++ char cname[256];
++
++ sprintf(cname, "%s %s", codec_ctl_pfx[i],
++ codec_ctl_name[j]);
++ kctl = snd_soc_card_get_kcontrol(card, cname);
++ if (!kctl) {
++ pr_info("Control %s not found\n",
++ cname);
++ } else {
++ kctl->vd[0].access =
++ SNDRV_CTL_ELEM_ACCESS_READWRITE;
++ snd_ctl_remove(card->snd_card, kctl);
++ }
++ }
++ }
++
++ return 0;
++}
++
++static int snd_pifi_40_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
++ unsigned int sample_bits;
++
++ sample_bits = snd_pcm_format_physical_width(params_format(params));
++ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64);
++}
++
++static struct snd_soc_ops snd_pifi_40_ops = { .hw_params =
++ snd_pifi_40_hw_params };
++
++static struct snd_soc_dai_link_component pifi_40_codecs[] = {
++ {
++ .dai_name = "tas571x-hifi",
++ },
++ {
++ .dai_name = "tas571x-hifi",
++ },
++};
++
++SND_SOC_DAILINK_DEFS(
++ pifi_40_dai, DAILINK_COMP_ARRAY(COMP_EMPTY()),
++ DAILINK_COMP_ARRAY(COMP_CODEC("tas571x.1-001a", "tas571x-hifi"),
++ COMP_CODEC("tas571x.1-001b", "tas571x-hifi")),
++ DAILINK_COMP_ARRAY(COMP_EMPTY()));
++
++static struct snd_soc_dai_link snd_pifi_40_dai[] = {
++ {
++ .name = "PiFi40",
++ .stream_name = "PiFi40",
++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
++ SND_SOC_DAIFMT_CBS_CFS,
++ .ops = &snd_pifi_40_ops,
++ .init = snd_pifi_40_init,
++ SND_SOC_DAILINK_REG(pifi_40_dai),
++ },
++};
++
++// Machine driver
++static struct snd_soc_card snd_pifi_40 = {
++ .name = "PiFi40",
++ .owner = THIS_MODULE,
++ .dai_link = snd_pifi_40_dai,
++ .num_links = ARRAY_SIZE(snd_pifi_40_dai),
++ .controls = pifi_40_controls,
++ .num_controls = ARRAY_SIZE(pifi_40_controls)
++};
++
++static void snd_pifi_40_pdn(struct snd_soc_card *card, int on)
++{
++ if (pdn_gpio)
++ gpiod_set_value_cansleep(pdn_gpio, on ? 0 : 1);
++}
++
++static int snd_pifi_40_probe(struct platform_device *pdev)
++{
++ struct snd_soc_card *card = &snd_pifi_40;
++ int ret = 0, i = 0;
++
++ card->dev = &pdev->dev;
++ platform_set_drvdata(pdev, &snd_pifi_40);
++
++ if (pdev->dev.of_node) {
++ struct device_node *i2s_node;
++ struct snd_soc_dai_link *dai;
++
++ dai = &snd_pifi_40_dai[0];
++ i2s_node = of_parse_phandle(pdev->dev.of_node, "i2s-controller",
++ 0);
++ if (i2s_node) {
++ for (i = 0; i < card->num_links; i++) {
++ dai->cpus->dai_name = NULL;
++ dai->cpus->of_node = i2s_node;
++ dai->platforms->name = NULL;
++ dai->platforms->of_node = i2s_node;
++ }
++ }
++
++ pifi_40_codecs[0].of_node =
++ of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
++ pifi_40_codecs[1].of_node =
++ of_parse_phandle(pdev->dev.of_node, "audio-codec", 1);
++ if (!pifi_40_codecs[0].of_node || !pifi_40_codecs[1].of_node) {
++ dev_err(&pdev->dev,
++ "Property 'audio-codec' missing or invalid\n");
++ return -EINVAL;
++ }
++
++ pdn_gpio = devm_gpiod_get_optional(&pdev->dev, "pdn",
++ GPIOD_OUT_LOW);
++ if (IS_ERR(pdn_gpio)) {
++ ret = PTR_ERR(pdn_gpio);
++ dev_err(&pdev->dev, "failed to get pdn gpio: %d\n",
++ ret);
++ return ret;
++ }
++
++ ret = snd_soc_register_card(&snd_pifi_40);
++ if (ret < 0) {
++ dev_err(&pdev->dev,
++ "snd_soc_register_card() failed: %d\n", ret);
++ return ret;
++ }
++
++ return 0;
++ }
++
++ return -EINVAL;
++}
++
++static int snd_pifi_40_remove(struct platform_device *pdev)
++{
++ struct snd_soc_card *card = platform_get_drvdata(pdev);
++
++ kfree(&card->drvdata);
++ snd_pifi_40_pdn(&snd_pifi_40, 0);
++ return snd_soc_unregister_card(&snd_pifi_40);
++}
++
++static const struct of_device_id snd_pifi_40_of_match[] = {
++ {
++ .compatible = "pifi,pifi-40",
++ },
++ { /* sentinel */ },
++};
++
++MODULE_DEVICE_TABLE(of, snd_pifi_40_of_match);
++
++static struct platform_driver snd_pifi_40_driver = {
++ .driver = {
++ .name = "snd-pifi-40",
++ .owner = THIS_MODULE,
++ .of_match_table = snd_pifi_40_of_match,
++ },
++ .probe = snd_pifi_40_probe,
++ .remove = snd_pifi_40_remove,
++};
++
++module_platform_driver(snd_pifi_40_driver);
++
++MODULE_AUTHOR("David Knell <david.knell@gmail.com>");
++MODULE_DESCRIPTION("ALSA ASoC Machine Driver for PiFi-40");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/bcm27xx/patches-5.4/950-1002-dwc_otg-Minimise-header-and-fix-build-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-1002-dwc_otg-Minimise-header-and-fix-build-warnings.patch
new file mode 100644
index 0000000000..233b9f312b
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1002-dwc_otg-Minimise-header-and-fix-build-warnings.patch
@@ -0,0 +1,747 @@
+From ed478a5013976948e94834244d8e5c0abcaab5c3 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 27 Oct 2020 09:59:49 +0000
+Subject: [PATCH] dwc_otg: Minimise header and fix build warnings
+
+Delete a large amount of unused declaration from "usb.h", some of which
+were causing build warnings, and get the module building cleanly.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/usb/host/dwc_common_port/usb.h | 664 -------------------
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 4 +-
+ drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c | 2 +-
+ 3 files changed, 3 insertions(+), 667 deletions(-)
+
+--- a/drivers/usb/host/dwc_common_port/usb.h
++++ b/drivers/usb/host/dwc_common_port/usb.h
+@@ -55,12 +55,6 @@ typedef u_int8_t uByte;
+ typedef u_int8_t uWord[2];
+ typedef u_int8_t uDWord[4];
+
+-#define USETW2(w,h,l) ((w)[0] = (u_int8_t)(l), (w)[1] = (u_int8_t)(h))
+-#define UCONSTW(x) { (x) & 0xff, ((x) >> 8) & 0xff }
+-#define UCONSTDW(x) { (x) & 0xff, ((x) >> 8) & 0xff, \
+- ((x) >> 16) & 0xff, ((x) >> 24) & 0xff }
+-
+-#if 1
+ #define UGETW(w) ((w)[0] | ((w)[1] << 8))
+ #define USETW(w,v) ((w)[0] = (u_int8_t)(v), (w)[1] = (u_int8_t)((v) >> 8))
+ #define UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24))
+@@ -68,31 +62,6 @@ typedef u_int8_t uDWord[4];
+ (w)[1] = (u_int8_t)((v) >> 8), \
+ (w)[2] = (u_int8_t)((v) >> 16), \
+ (w)[3] = (u_int8_t)((v) >> 24))
+-#else
+-/*
+- * On little-endian machines that can handle unanliged accesses
+- * (e.g. i386) these macros can be replaced by the following.
+- */
+-#define UGETW(w) (*(u_int16_t *)(w))
+-#define USETW(w,v) (*(u_int16_t *)(w) = (v))
+-#define UGETDW(w) (*(u_int32_t *)(w))
+-#define USETDW(w,v) (*(u_int32_t *)(w) = (v))
+-#endif
+-
+-/*
+- * Macros for accessing UAS IU fields, which are big-endian
+- */
+-#define IUSETW2(w,h,l) ((w)[0] = (u_int8_t)(h), (w)[1] = (u_int8_t)(l))
+-#define IUCONSTW(x) { ((x) >> 8) & 0xff, (x) & 0xff }
+-#define IUCONSTDW(x) { ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \
+- ((x) >> 8) & 0xff, (x) & 0xff }
+-#define IUGETW(w) (((w)[0] << 8) | (w)[1])
+-#define IUSETW(w,v) ((w)[0] = (u_int8_t)((v) >> 8), (w)[1] = (u_int8_t)(v))
+-#define IUGETDW(w) (((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3])
+-#define IUSETDW(w,v) ((w)[0] = (u_int8_t)((v) >> 24), \
+- (w)[1] = (u_int8_t)((v) >> 16), \
+- (w)[2] = (u_int8_t)((v) >> 8), \
+- (w)[3] = (u_int8_t)(v))
+
+ #define UPACKED __attribute__((__packed__))
+
+@@ -119,29 +88,6 @@ typedef struct {
+ #define UT_ENDPOINT 0x02
+ #define UT_OTHER 0x03
+
+-#define UT_READ_DEVICE (UT_READ | UT_STANDARD | UT_DEVICE)
+-#define UT_READ_INTERFACE (UT_READ | UT_STANDARD | UT_INTERFACE)
+-#define UT_READ_ENDPOINT (UT_READ | UT_STANDARD | UT_ENDPOINT)
+-#define UT_WRITE_DEVICE (UT_WRITE | UT_STANDARD | UT_DEVICE)
+-#define UT_WRITE_INTERFACE (UT_WRITE | UT_STANDARD | UT_INTERFACE)
+-#define UT_WRITE_ENDPOINT (UT_WRITE | UT_STANDARD | UT_ENDPOINT)
+-#define UT_READ_CLASS_DEVICE (UT_READ | UT_CLASS | UT_DEVICE)
+-#define UT_READ_CLASS_INTERFACE (UT_READ | UT_CLASS | UT_INTERFACE)
+-#define UT_READ_CLASS_OTHER (UT_READ | UT_CLASS | UT_OTHER)
+-#define UT_READ_CLASS_ENDPOINT (UT_READ | UT_CLASS | UT_ENDPOINT)
+-#define UT_WRITE_CLASS_DEVICE (UT_WRITE | UT_CLASS | UT_DEVICE)
+-#define UT_WRITE_CLASS_INTERFACE (UT_WRITE | UT_CLASS | UT_INTERFACE)
+-#define UT_WRITE_CLASS_OTHER (UT_WRITE | UT_CLASS | UT_OTHER)
+-#define UT_WRITE_CLASS_ENDPOINT (UT_WRITE | UT_CLASS | UT_ENDPOINT)
+-#define UT_READ_VENDOR_DEVICE (UT_READ | UT_VENDOR | UT_DEVICE)
+-#define UT_READ_VENDOR_INTERFACE (UT_READ | UT_VENDOR | UT_INTERFACE)
+-#define UT_READ_VENDOR_OTHER (UT_READ | UT_VENDOR | UT_OTHER)
+-#define UT_READ_VENDOR_ENDPOINT (UT_READ | UT_VENDOR | UT_ENDPOINT)
+-#define UT_WRITE_VENDOR_DEVICE (UT_WRITE | UT_VENDOR | UT_DEVICE)
+-#define UT_WRITE_VENDOR_INTERFACE (UT_WRITE | UT_VENDOR | UT_INTERFACE)
+-#define UT_WRITE_VENDOR_OTHER (UT_WRITE | UT_VENDOR | UT_OTHER)
+-#define UT_WRITE_VENDOR_ENDPOINT (UT_WRITE | UT_VENDOR | UT_ENDPOINT)
+-
+ /* Requests */
+ #define UR_GET_STATUS 0x00
+ #define USTAT_STANDARD_STATUS 0x00
+@@ -243,71 +189,6 @@ typedef struct {
+ typedef struct {
+ uByte bLength;
+ uByte bDescriptorType;
+- uByte bDescriptorSubtype;
+-} UPACKED usb_descriptor_t;
+-
+-typedef struct {
+- uByte bLength;
+- uByte bDescriptorType;
+-} UPACKED usb_descriptor_header_t;
+-
+-typedef struct {
+- uByte bLength;
+- uByte bDescriptorType;
+- uWord bcdUSB;
+-#define UD_USB_2_0 0x0200
+-#define UD_IS_USB2(d) (UGETW((d)->bcdUSB) >= UD_USB_2_0)
+- uByte bDeviceClass;
+- uByte bDeviceSubClass;
+- uByte bDeviceProtocol;
+- uByte bMaxPacketSize;
+- /* The fields below are not part of the initial descriptor. */
+- uWord idVendor;
+- uWord idProduct;
+- uWord bcdDevice;
+- uByte iManufacturer;
+- uByte iProduct;
+- uByte iSerialNumber;
+- uByte bNumConfigurations;
+-} UPACKED usb_device_descriptor_t;
+-#define USB_DEVICE_DESCRIPTOR_SIZE 18
+-
+-typedef struct {
+- uByte bLength;
+- uByte bDescriptorType;
+- uWord wTotalLength;
+- uByte bNumInterface;
+- uByte bConfigurationValue;
+- uByte iConfiguration;
+-#define UC_ATT_ONE (1 << 7) /* must be set */
+-#define UC_ATT_SELFPOWER (1 << 6) /* self powered */
+-#define UC_ATT_WAKEUP (1 << 5) /* can wakeup */
+-#define UC_ATT_BATTERY (1 << 4) /* battery powered */
+- uByte bmAttributes;
+-#define UC_BUS_POWERED 0x80
+-#define UC_SELF_POWERED 0x40
+-#define UC_REMOTE_WAKEUP 0x20
+- uByte bMaxPower; /* max current in 2 mA units */
+-#define UC_POWER_FACTOR 2
+-} UPACKED usb_config_descriptor_t;
+-#define USB_CONFIG_DESCRIPTOR_SIZE 9
+-
+-typedef struct {
+- uByte bLength;
+- uByte bDescriptorType;
+- uByte bInterfaceNumber;
+- uByte bAlternateSetting;
+- uByte bNumEndpoints;
+- uByte bInterfaceClass;
+- uByte bInterfaceSubClass;
+- uByte bInterfaceProtocol;
+- uByte iInterface;
+-} UPACKED usb_interface_descriptor_t;
+-#define USB_INTERFACE_DESCRIPTOR_SIZE 9
+-
+-typedef struct {
+- uByte bLength;
+- uByte bDescriptorType;
+ uByte bEndpointAddress;
+ #define UE_GET_DIR(a) ((a) & 0x80)
+ #define UE_SET_DIR(a,d) ((a) | (((d)&1) << 7))
+@@ -332,27 +213,6 @@ typedef struct {
+ } UPACKED usb_endpoint_descriptor_t;
+ #define USB_ENDPOINT_DESCRIPTOR_SIZE 7
+
+-typedef struct ss_endpoint_companion_descriptor {
+- uByte bLength;
+- uByte bDescriptorType;
+- uByte bMaxBurst;
+-#define USSE_GET_MAX_STREAMS(a) ((a) & 0x1f)
+-#define USSE_SET_MAX_STREAMS(a, b) ((a) | ((b) & 0x1f))
+-#define USSE_GET_MAX_PACKET_NUM(a) ((a) & 0x03)
+-#define USSE_SET_MAX_PACKET_NUM(a, b) ((a) | ((b) & 0x03))
+- uByte bmAttributes;
+- uWord wBytesPerInterval;
+-} UPACKED ss_endpoint_companion_descriptor_t;
+-#define USB_SS_ENDPOINT_COMPANION_DESCRIPTOR_SIZE 6
+-
+-typedef struct {
+- uByte bLength;
+- uByte bDescriptorType;
+- uWord bString[127];
+-} UPACKED usb_string_descriptor_t;
+-#define USB_MAX_STRING_LEN 128
+-#define USB_LANGUAGE_TABLE 0 /* # of the string language id table */
+-
+ /* Hub specific request */
+ #define UR_GET_BUS_STATE 0x02
+ #define UR_CLEAR_TT_BUFFER 0x08
+@@ -411,530 +271,6 @@ typedef struct {
+ } UPACKED usb_hub_descriptor_t;
+ #define USB_HUB_DESCRIPTOR_SIZE 9 /* includes deprecated PortPowerCtrlMask */
+
+-typedef struct {
+- uByte bLength;
+- uByte bDescriptorType;
+- uWord bcdUSB;
+- uByte bDeviceClass;
+- uByte bDeviceSubClass;
+- uByte bDeviceProtocol;
+- uByte bMaxPacketSize0;
+- uByte bNumConfigurations;
+- uByte bReserved;
+-} UPACKED usb_device_qualifier_t;
+-#define USB_DEVICE_QUALIFIER_SIZE 10
+-
+-typedef struct {
+- uByte bLength;
+- uByte bDescriptorType;
+- uByte bmAttributes;
+-#define UOTG_SRP 0x01
+-#define UOTG_HNP 0x02
+-} UPACKED usb_otg_descriptor_t;
+-
+-/* OTG feature selectors */
+-#define UOTG_B_HNP_ENABLE 3
+-#define UOTG_A_HNP_SUPPORT 4
+-#define UOTG_A_ALT_HNP_SUPPORT 5
+-
+-typedef struct {
+- uWord wStatus;
+-/* Device status flags */
+-#define UDS_SELF_POWERED 0x0001
+-#define UDS_REMOTE_WAKEUP 0x0002
+-/* Endpoint status flags */
+-#define UES_HALT 0x0001
+-} UPACKED usb_status_t;
+-
+-typedef struct {
+- uWord wHubStatus;
+-#define UHS_LOCAL_POWER 0x0001
+-#define UHS_OVER_CURRENT 0x0002
+- uWord wHubChange;
+-} UPACKED usb_hub_status_t;
+-
+-typedef struct {
+- uWord wPortStatus;
+-#define UPS_CURRENT_CONNECT_STATUS 0x0001
+-#define UPS_PORT_ENABLED 0x0002
+-#define UPS_SUSPEND 0x0004
+-#define UPS_OVERCURRENT_INDICATOR 0x0008
+-#define UPS_RESET 0x0010
+-#define UPS_PORT_POWER 0x0100
+-#define UPS_LOW_SPEED 0x0200
+-#define UPS_HIGH_SPEED 0x0400
+-#define UPS_PORT_TEST 0x0800
+-#define UPS_PORT_INDICATOR 0x1000
+- uWord wPortChange;
+-#define UPS_C_CONNECT_STATUS 0x0001
+-#define UPS_C_PORT_ENABLED 0x0002
+-#define UPS_C_SUSPEND 0x0004
+-#define UPS_C_OVERCURRENT_INDICATOR 0x0008
+-#define UPS_C_PORT_RESET 0x0010
+-} UPACKED usb_port_status_t;
+-
+-#ifdef _MSC_VER
+-#include <poppack.h>
+-#endif
+-
+-/* Device class codes */
+-#define UDCLASS_IN_INTERFACE 0x00
+-#define UDCLASS_COMM 0x02
+-#define UDCLASS_HUB 0x09
+-#define UDSUBCLASS_HUB 0x00
+-#define UDPROTO_FSHUB 0x00
+-#define UDPROTO_HSHUBSTT 0x01
+-#define UDPROTO_HSHUBMTT 0x02
+-#define UDCLASS_DIAGNOSTIC 0xdc
+-#define UDCLASS_WIRELESS 0xe0
+-#define UDSUBCLASS_RF 0x01
+-#define UDPROTO_BLUETOOTH 0x01
+-#define UDCLASS_VENDOR 0xff
+-
+-/* Interface class codes */
+-#define UICLASS_UNSPEC 0x00
+-
+-#define UICLASS_AUDIO 0x01
+-#define UISUBCLASS_AUDIOCONTROL 1
+-#define UISUBCLASS_AUDIOSTREAM 2
+-#define UISUBCLASS_MIDISTREAM 3
+-
+-#define UICLASS_CDC 0x02 /* communication */
+-#define UISUBCLASS_DIRECT_LINE_CONTROL_MODEL 1
+-#define UISUBCLASS_ABSTRACT_CONTROL_MODEL 2
+-#define UISUBCLASS_TELEPHONE_CONTROL_MODEL 3
+-#define UISUBCLASS_MULTICHANNEL_CONTROL_MODEL 4
+-#define UISUBCLASS_CAPI_CONTROLMODEL 5
+-#define UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6
+-#define UISUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7
+-#define UIPROTO_CDC_AT 1
+-
+-#define UICLASS_HID 0x03
+-#define UISUBCLASS_BOOT 1
+-#define UIPROTO_BOOT_KEYBOARD 1
+-
+-#define UICLASS_PHYSICAL 0x05
+-
+-#define UICLASS_IMAGE 0x06
+-
+-#define UICLASS_PRINTER 0x07
+-#define UISUBCLASS_PRINTER 1
+-#define UIPROTO_PRINTER_UNI 1
+-#define UIPROTO_PRINTER_BI 2
+-#define UIPROTO_PRINTER_1284 3
+-
+-#define UICLASS_MASS 0x08
+-#define UISUBCLASS_RBC 1
+-#define UISUBCLASS_SFF8020I 2
+-#define UISUBCLASS_QIC157 3
+-#define UISUBCLASS_UFI 4
+-#define UISUBCLASS_SFF8070I 5
+-#define UISUBCLASS_SCSI 6
+-#define UIPROTO_MASS_CBI_I 0
+-#define UIPROTO_MASS_CBI 1
+-#define UIPROTO_MASS_BBB_OLD 2 /* Not in the spec anymore */
+-#define UIPROTO_MASS_BBB 80 /* 'P' for the Iomega Zip drive */
+-
+-#define UICLASS_HUB 0x09
+-#define UISUBCLASS_HUB 0
+-#define UIPROTO_FSHUB 0
+-#define UIPROTO_HSHUBSTT 0 /* Yes, same as previous */
+-#define UIPROTO_HSHUBMTT 1
+-
+-#define UICLASS_CDC_DATA 0x0a
+-#define UISUBCLASS_DATA 0
+-#define UIPROTO_DATA_ISDNBRI 0x30 /* Physical iface */
+-#define UIPROTO_DATA_HDLC 0x31 /* HDLC */
+-#define UIPROTO_DATA_TRANSPARENT 0x32 /* Transparent */
+-#define UIPROTO_DATA_Q921M 0x50 /* Management for Q921 */
+-#define UIPROTO_DATA_Q921 0x51 /* Data for Q921 */
+-#define UIPROTO_DATA_Q921TM 0x52 /* TEI multiplexer for Q921 */
+-#define UIPROTO_DATA_V42BIS 0x90 /* Data compression */
+-#define UIPROTO_DATA_Q931 0x91 /* Euro-ISDN */
+-#define UIPROTO_DATA_V120 0x92 /* V.24 rate adaption */
+-#define UIPROTO_DATA_CAPI 0x93 /* CAPI 2.0 commands */
+-#define UIPROTO_DATA_HOST_BASED 0xfd /* Host based driver */
+-#define UIPROTO_DATA_PUF 0xfe /* see Prot. Unit Func. Desc.*/
+-#define UIPROTO_DATA_VENDOR 0xff /* Vendor specific */
+-
+-#define UICLASS_SMARTCARD 0x0b
+-
+-/*#define UICLASS_FIRM_UPD 0x0c*/
+-
+-#define UICLASS_SECURITY 0x0d
+-
+-#define UICLASS_DIAGNOSTIC 0xdc
+-
+-#define UICLASS_WIRELESS 0xe0
+-#define UISUBCLASS_RF 0x01
+-#define UIPROTO_BLUETOOTH 0x01
+-
+-#define UICLASS_APPL_SPEC 0xfe
+-#define UISUBCLASS_FIRMWARE_DOWNLOAD 1
+-#define UISUBCLASS_IRDA 2
+-#define UIPROTO_IRDA 0
+-
+-#define UICLASS_VENDOR 0xff
+-
+-#define USB_HUB_MAX_DEPTH 5
+-
+-/*
+- * Minimum time a device needs to be powered down to go through
+- * a power cycle. XXX Are these time in the spec?
+- */
+-#define USB_POWER_DOWN_TIME 200 /* ms */
+-#define USB_PORT_POWER_DOWN_TIME 100 /* ms */
+-
+-#if 0
+-/* These are the values from the spec. */
+-#define USB_PORT_RESET_DELAY 10 /* ms */
+-#define USB_PORT_ROOT_RESET_DELAY 50 /* ms */
+-#define USB_PORT_RESET_RECOVERY 10 /* ms */
+-#define USB_PORT_POWERUP_DELAY 100 /* ms */
+-#define USB_SET_ADDRESS_SETTLE 2 /* ms */
+-#define USB_RESUME_DELAY (20*5) /* ms */
+-#define USB_RESUME_WAIT 10 /* ms */
+-#define USB_RESUME_RECOVERY 10 /* ms */
+-#define USB_EXTRA_POWER_UP_TIME 0 /* ms */
+-#else
+-/* Allow for marginal (i.e. non-conforming) devices. */
+-#define USB_PORT_RESET_DELAY 50 /* ms */
+-#define USB_PORT_ROOT_RESET_DELAY 250 /* ms */
+-#define USB_PORT_RESET_RECOVERY 250 /* ms */
+-#define USB_PORT_POWERUP_DELAY 300 /* ms */
+-#define USB_SET_ADDRESS_SETTLE 10 /* ms */
+-#define USB_RESUME_DELAY (50*5) /* ms */
+-#define USB_RESUME_WAIT 50 /* ms */
+-#define USB_RESUME_RECOVERY 50 /* ms */
+-#define USB_EXTRA_POWER_UP_TIME 20 /* ms */
+-#endif
+-
+-#define USB_MIN_POWER 100 /* mA */
+-#define USB_MAX_POWER 500 /* mA */
+-
+-#define USB_BUS_RESET_DELAY 100 /* ms XXX?*/
+-
+-#define USB_UNCONFIG_NO 0
+-#define USB_UNCONFIG_INDEX (-1)
+-
+-/*** ioctl() related stuff ***/
+-
+-struct usb_ctl_request {
+- int ucr_addr;
+- usb_device_request_t ucr_request;
+- void *ucr_data;
+- int ucr_flags;
+-#define USBD_SHORT_XFER_OK 0x04 /* allow short reads */
+- int ucr_actlen; /* actual length transferred */
+-};
+-
+-struct usb_alt_interface {
+- int uai_config_index;
+- int uai_interface_index;
+- int uai_alt_no;
+-};
+-
+-#define USB_CURRENT_CONFIG_INDEX (-1)
+-#define USB_CURRENT_ALT_INDEX (-1)
+-
+-struct usb_config_desc {
+- int ucd_config_index;
+- usb_config_descriptor_t ucd_desc;
+-};
+-
+-struct usb_interface_desc {
+- int uid_config_index;
+- int uid_interface_index;
+- int uid_alt_index;
+- usb_interface_descriptor_t uid_desc;
+-};
+-
+-struct usb_endpoint_desc {
+- int ued_config_index;
+- int ued_interface_index;
+- int ued_alt_index;
+- int ued_endpoint_index;
+- usb_endpoint_descriptor_t ued_desc;
+-};
+-
+-struct usb_full_desc {
+- int ufd_config_index;
+- u_int ufd_size;
+- u_char *ufd_data;
+-};
+-
+-struct usb_string_desc {
+- int usd_string_index;
+- int usd_language_id;
+- usb_string_descriptor_t usd_desc;
+-};
+-
+-struct usb_ctl_report_desc {
+- int ucrd_size;
+- u_char ucrd_data[1024]; /* filled data size will vary */
+-};
+-
+-typedef struct { u_int32_t cookie; } usb_event_cookie_t;
+-
+-#define USB_MAX_DEVNAMES 4
+-#define USB_MAX_DEVNAMELEN 16
+-struct usb_device_info {
+- u_int8_t udi_bus;
+- u_int8_t udi_addr; /* device address */
+- usb_event_cookie_t udi_cookie;
+- char udi_product[USB_MAX_STRING_LEN];
+- char udi_vendor[USB_MAX_STRING_LEN];
+- char udi_release[8];
+- u_int16_t udi_productNo;
+- u_int16_t udi_vendorNo;
+- u_int16_t udi_releaseNo;
+- u_int8_t udi_class;
+- u_int8_t udi_subclass;
+- u_int8_t udi_protocol;
+- u_int8_t udi_config;
+- u_int8_t udi_speed;
+-#define USB_SPEED_UNKNOWN 0
+-#define USB_SPEED_LOW 1
+-#define USB_SPEED_FULL 2
+-#define USB_SPEED_HIGH 3
+-#define USB_SPEED_VARIABLE 4
+-#define USB_SPEED_SUPER 5
+- int udi_power; /* power consumption in mA, 0 if selfpowered */
+- int udi_nports;
+- char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN];
+- u_int8_t udi_ports[16];/* hub only: addresses of devices on ports */
+-#define USB_PORT_ENABLED 0xff
+-#define USB_PORT_SUSPENDED 0xfe
+-#define USB_PORT_POWERED 0xfd
+-#define USB_PORT_DISABLED 0xfc
+-};
+-
+-struct usb_ctl_report {
+- int ucr_report;
+- u_char ucr_data[1024]; /* filled data size will vary */
+-};
+-
+-struct usb_device_stats {
+- u_long uds_requests[4]; /* indexed by transfer type UE_* */
+-};
+-
+-#define WUSB_MIN_IE 0x80
+-#define WUSB_WCTA_IE 0x80
+-#define WUSB_WCONNECTACK_IE 0x81
+-#define WUSB_WHOSTINFO_IE 0x82
+-#define WUHI_GET_CA(_bmAttributes_) ((_bmAttributes_) & 0x3)
+-#define WUHI_CA_RECONN 0x00
+-#define WUHI_CA_LIMITED 0x01
+-#define WUHI_CA_ALL 0x03
+-#define WUHI_GET_MLSI(_bmAttributes_) (((_bmAttributes_) & 0x38) >> 3)
+-#define WUSB_WCHCHANGEANNOUNCE_IE 0x83
+-#define WUSB_WDEV_DISCONNECT_IE 0x84
+-#define WUSB_WHOST_DISCONNECT_IE 0x85
+-#define WUSB_WRELEASE_CHANNEL_IE 0x86
+-#define WUSB_WWORK_IE 0x87
+-#define WUSB_WCHANNEL_STOP_IE 0x88
+-#define WUSB_WDEV_KEEPALIVE_IE 0x89
+-#define WUSB_WISOCH_DISCARD_IE 0x8A
+-#define WUSB_WRESETDEVICE_IE 0x8B
+-#define WUSB_WXMIT_PACKET_ADJUST_IE 0x8C
+-#define WUSB_MAX_IE 0x8C
+-
+-/* Device Notification Types */
+-
+-#define WUSB_DN_MIN 0x01
+-#define WUSB_DN_CONNECT 0x01
+-# define WUSB_DA_OLDCONN 0x00
+-# define WUSB_DA_NEWCONN 0x01
+-# define WUSB_DA_SELF_BEACON 0x02
+-# define WUSB_DA_DIR_BEACON 0x04
+-# define WUSB_DA_NO_BEACON 0x06
+-#define WUSB_DN_DISCONNECT 0x02
+-#define WUSB_DN_EPRDY 0x03
+-#define WUSB_DN_MASAVAILCHANGED 0x04
+-#define WUSB_DN_REMOTEWAKEUP 0x05
+-#define WUSB_DN_SLEEP 0x06
+-#define WUSB_DN_ALIVE 0x07
+-#define WUSB_DN_MAX 0x07
+-
+-#ifdef _MSC_VER
+-#include <pshpack1.h>
+-#endif
+-
+-/* WUSB Handshake Data. Used during the SET/GET HANDSHAKE requests */
+-typedef struct wusb_hndshk_data {
+- uByte bMessageNumber;
+- uByte bStatus;
+- uByte tTKID[3];
+- uByte bReserved;
+- uByte CDID[16];
+- uByte Nonce[16];
+- uByte MIC[8];
+-} UPACKED wusb_hndshk_data_t;
+-#define WUSB_HANDSHAKE_LEN_FOR_MIC 38
+-
+-/* WUSB Connection Context */
+-typedef struct wusb_conn_context {
+- uByte CHID [16];
+- uByte CDID [16];
+- uByte CK [16];
+-} UPACKED wusb_conn_context_t;
+-
+-/* WUSB Security Descriptor */
+-typedef struct wusb_security_desc {
+- uByte bLength;
+- uByte bDescriptorType;
+- uWord wTotalLength;
+- uByte bNumEncryptionTypes;
+-} UPACKED wusb_security_desc_t;
+-
+-/* WUSB Encryption Type Descriptor */
+-typedef struct wusb_encrypt_type_desc {
+- uByte bLength;
+- uByte bDescriptorType;
+-
+- uByte bEncryptionType;
+-#define WUETD_UNSECURE 0
+-#define WUETD_WIRED 1
+-#define WUETD_CCM_1 2
+-#define WUETD_RSA_1 3
+-
+- uByte bEncryptionValue;
+- uByte bAuthKeyIndex;
+-} UPACKED wusb_encrypt_type_desc_t;
+-
+-/* WUSB Key Descriptor */
+-typedef struct wusb_key_desc {
+- uByte bLength;
+- uByte bDescriptorType;
+- uByte tTKID[3];
+- uByte bReserved;
+- uByte KeyData[1]; /* variable length */
+-} UPACKED wusb_key_desc_t;
+-
+-/* WUSB BOS Descriptor (Binary device Object Store) */
+-typedef struct wusb_bos_desc {
+- uByte bLength;
+- uByte bDescriptorType;
+- uWord wTotalLength;
+- uByte bNumDeviceCaps;
+-} UPACKED wusb_bos_desc_t;
+-
+-#define USB_DEVICE_CAPABILITY_20_EXTENSION 0x02
+-typedef struct usb_dev_cap_20_ext_desc {
+- uByte bLength;
+- uByte bDescriptorType;
+- uByte bDevCapabilityType;
+-#define USB_20_EXT_LPM 0x02
+- uDWord bmAttributes;
+-} UPACKED usb_dev_cap_20_ext_desc_t;
+-
+-#define USB_DEVICE_CAPABILITY_SS_USB 0x03
+-typedef struct usb_dev_cap_ss_usb {
+- uByte bLength;
+- uByte bDescriptorType;
+- uByte bDevCapabilityType;
+-#define USB_DC_SS_USB_LTM_CAPABLE 0x02
+- uByte bmAttributes;
+-#define USB_DC_SS_USB_SPEED_SUPPORT_LOW 0x01
+-#define USB_DC_SS_USB_SPEED_SUPPORT_FULL 0x02
+-#define USB_DC_SS_USB_SPEED_SUPPORT_HIGH 0x04
+-#define USB_DC_SS_USB_SPEED_SUPPORT_SS 0x08
+- uWord wSpeedsSupported;
+- uByte bFunctionalitySupport;
+- uByte bU1DevExitLat;
+- uWord wU2DevExitLat;
+-} UPACKED usb_dev_cap_ss_usb_t;
+-
+-#define USB_DEVICE_CAPABILITY_CONTAINER_ID 0x04
+-typedef struct usb_dev_cap_container_id {
+- uByte bLength;
+- uByte bDescriptorType;
+- uByte bDevCapabilityType;
+- uByte bReserved;
+- uByte containerID[16];
+-} UPACKED usb_dev_cap_container_id_t;
+-
+-/* Device Capability Type Codes */
+-#define WUSB_DEVICE_CAPABILITY_WIRELESS_USB 0x01
+-
+-/* Device Capability Descriptor */
+-typedef struct wusb_dev_cap_desc {
+- uByte bLength;
+- uByte bDescriptorType;
+- uByte bDevCapabilityType;
+- uByte caps[1]; /* Variable length */
+-} UPACKED wusb_dev_cap_desc_t;
+-
+-/* Device Capability Descriptor */
+-typedef struct wusb_dev_cap_uwb_desc {
+- uByte bLength;
+- uByte bDescriptorType;
+- uByte bDevCapabilityType;
+- uByte bmAttributes;
+- uWord wPHYRates; /* Bitmap */
+- uByte bmTFITXPowerInfo;
+- uByte bmFFITXPowerInfo;
+- uWord bmBandGroup;
+- uByte bReserved;
+-} UPACKED wusb_dev_cap_uwb_desc_t;
+-
+-/* Wireless USB Endpoint Companion Descriptor */
+-typedef struct wusb_endpoint_companion_desc {
+- uByte bLength;
+- uByte bDescriptorType;
+- uByte bMaxBurst;
+- uByte bMaxSequence;
+- uWord wMaxStreamDelay;
+- uWord wOverTheAirPacketSize;
+- uByte bOverTheAirInterval;
+- uByte bmCompAttributes;
+-} UPACKED wusb_endpoint_companion_desc_t;
+-
+-/* Wireless USB Numeric Association M1 Data Structure */
+-typedef struct wusb_m1_data {
+- uByte version;
+- uWord langId;
+- uByte deviceFriendlyNameLength;
+- uByte sha_256_m3[32];
+- uByte deviceFriendlyName[256];
+-} UPACKED wusb_m1_data_t;
+-
+-typedef struct wusb_m2_data {
+- uByte version;
+- uWord langId;
+- uByte hostFriendlyNameLength;
+- uByte pkh[384];
+- uByte hostFriendlyName[256];
+-} UPACKED wusb_m2_data_t;
+-
+-typedef struct wusb_m3_data {
+- uByte pkd[384];
+- uByte nd;
+-} UPACKED wusb_m3_data_t;
+-
+-typedef struct wusb_m4_data {
+- uDWord _attributeTypeIdAndLength_1;
+- uWord associationTypeId;
+-
+- uDWord _attributeTypeIdAndLength_2;
+- uWord associationSubTypeId;
+-
+- uDWord _attributeTypeIdAndLength_3;
+- uDWord length;
+-
+- uDWord _attributeTypeIdAndLength_4;
+- uDWord associationStatus;
+-
+- uDWord _attributeTypeIdAndLength_5;
+- uByte chid[16];
+-
+- uDWord _attributeTypeIdAndLength_6;
+- uByte cdid[16];
+-
+- uDWord _attributeTypeIdAndLength_7;
+- uByte bandGroups[2];
+-} UPACKED wusb_m4_data_t;
+-
+ #ifdef _MSC_VER
+ #include <poppack.h>
+ #endif
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
+@@ -457,8 +457,8 @@ static void hcd_init_fiq(void *cookie)
+ otg_dev->os_dep.mphi_base + 0x1f0;
+ dwc_otg_hcd->fiq_state->mphi_regs.swirq_clr =
+ otg_dev->os_dep.mphi_base + 0x1f4;
+- DWC_WARN("Fake MPHI regs_base at 0x%08x",
+- (int)dwc_otg_hcd->fiq_state->mphi_regs.base);
++ DWC_WARN("Fake MPHI regs_base at %px",
++ dwc_otg_hcd->fiq_state->mphi_regs.base);
+ } else {
+ dwc_otg_hcd->fiq_state->mphi_regs.ctrl =
+ otg_dev->os_dep.mphi_base + 0x4c;
+--- a/drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c
+@@ -3377,7 +3377,7 @@ void predict_nextep_seq( dwc_otg_core_if
+ dtknq1_data_t dtknqr1;
+ uint32_t in_tkn_epnums[4];
+ uint8_t seqnum[MAX_EPS_CHANNELS];
+- uint8_t intkn_seq[TOKEN_Q_DEPTH];
++ uint8_t intkn_seq[1 << 5];
+ grstctl_t resetctl = {.d32 = 0 };
+ uint8_t temp;
+ int ndx = 0;
diff --git a/target/linux/bcm27xx/patches-5.4/950-1003-gpio-fsm-Fix-a-build-warning.patch b/target/linux/bcm27xx/patches-5.4/950-1003-gpio-fsm-Fix-a-build-warning.patch
new file mode 100644
index 0000000000..d9ebc3a355
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1003-gpio-fsm-Fix-a-build-warning.patch
@@ -0,0 +1,22 @@
+From 60f17bc7d9100d7c3296987498a9f2d6c13f3f02 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 27 Oct 2020 12:10:04 +0000
+Subject: [PATCH] gpio-fsm: Fix a build warning
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/gpio/gpio-fsm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpio/gpio-fsm.c
++++ b/drivers/gpio/gpio-fsm.c
+@@ -956,7 +956,8 @@ static int gpio_fsm_probe(struct platfor
+ // add reserved words to the symbol table
+ for (i = 0; i < ARRAY_SIZE(reserved_symbols); i++) {
+ if (reserved_symbols[i])
+- add_symbol(&gf->symtab, reserved_symbols[i], (void *)i);
++ add_symbol(&gf->symtab, reserved_symbols[i],
++ (void *)(uintptr_t)i);
+ }
+
+ // parse the state
diff --git a/target/linux/bcm27xx/patches-5.4/950-1004-rpivid_h625-Fix-build-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-1004-rpivid_h625-Fix-build-warnings.patch
new file mode 100644
index 0000000000..375f1cac98
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1004-rpivid_h625-Fix-build-warnings.patch
@@ -0,0 +1,68 @@
+From c23b30df4bcafaa1a2bca210bc09f65c01ace375 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 27 Oct 2020 12:10:40 +0000
+Subject: [PATCH] rpivid_h625: Fix build warnings
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/staging/media/rpivid/rpivid_h265.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/staging/media/rpivid/rpivid_h265.c
++++ b/drivers/staging/media/rpivid/rpivid_h265.c
+@@ -1341,10 +1341,10 @@ static int frame_end(struct rpivid_dev *
+
+ if (gptr_realloc_new(dev, de->cmd_copy_gptr, cmd_alloc)) {
+ v4l2_err(&dev->v4l2_dev,
+- "Alloc cmd buffer (%d): FAILED\n", cmd_alloc);
++ "Alloc cmd buffer (%zu): FAILED\n", cmd_alloc);
+ return -ENOMEM;
+ }
+- v4l2_info(&dev->v4l2_dev, "Alloc cmd buffer (%d): OK\n",
++ v4l2_info(&dev->v4l2_dev, "Alloc cmd buffer (%zu): OK\n",
+ cmd_alloc);
+ }
+
+@@ -1696,12 +1696,12 @@ static void rpivid_h265_setup(struct rpi
+ bits_alloc,
+ DMA_ATTR_FORCE_CONTIGUOUS) != 0) {
+ v4l2_err(&dev->v4l2_dev,
+- "Unable to alloc buf (%d) for bit copy\n",
++ "Unable to alloc buf (%zu) for bit copy\n",
+ bits_alloc);
+ goto fail;
+ }
+ v4l2_info(&dev->v4l2_dev,
+- "Alloc buf (%d) for bit copy OK\n",
++ "Alloc buf (%zu) for bit copy OK\n",
+ bits_alloc);
+ }
+ }
+@@ -1995,11 +1995,11 @@ static void phase1_thread(struct rpivid_
+ if (de->p1_status & STATUS_PU_EXHAUSTED) {
+ if (gptr_realloc_new(dev, pu_gptr, next_size(pu_gptr->size))) {
+ v4l2_err(&dev->v4l2_dev,
+- "%s: PU realloc (%#x) failed\n",
++ "%s: PU realloc (%zx) failed\n",
+ __func__, pu_gptr->size);
+ goto fail;
+ }
+- v4l2_info(&dev->v4l2_dev, "%s: PU realloc (%#x) OK\n",
++ v4l2_info(&dev->v4l2_dev, "%s: PU realloc (%zx) OK\n",
+ __func__, pu_gptr->size);
+ }
+
+@@ -2007,11 +2007,11 @@ static void phase1_thread(struct rpivid_
+ if (gptr_realloc_new(dev, coeff_gptr,
+ next_size(coeff_gptr->size))) {
+ v4l2_err(&dev->v4l2_dev,
+- "%s: Coeff realloc (%#x) failed\n",
++ "%s: Coeff realloc (%zx) failed\n",
+ __func__, coeff_gptr->size);
+ goto fail;
+ }
+- v4l2_info(&dev->v4l2_dev, "%s: Coeff realloc (%#x) OK\n",
++ v4l2_info(&dev->v4l2_dev, "%s: Coeff realloc (%zx) OK\n",
+ __func__, coeff_gptr->size);
+ }
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-1005-dwc_otg-Fix-more-build-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-1005-dwc_otg-Fix-more-build-warnings.patch
new file mode 100644
index 0000000000..a9f560530a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1005-dwc_otg-Fix-more-build-warnings.patch
@@ -0,0 +1,149 @@
+From 9b899afd231b7dde6084092cf46dd15c05ed8a5c Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 27 Oct 2020 12:11:56 +0000
+Subject: [PATCH] dwc_otg: Fix more build warnings
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 10 +++++----
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 23 ++++++++++++++-------
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 3 ++-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 8 +++----
+ 4 files changed, 27 insertions(+), 17 deletions(-)
+
+--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
+@@ -240,7 +240,8 @@ static int notrace fiq_increment_dma_buf
+ hcdma_data_t hcdma;
+ int i = st->channel[n].dma_info.index;
+ int len;
+- struct fiq_dma_blob *blob = (struct fiq_dma_blob *) st->dma_base;
++ struct fiq_dma_blob *blob =
++ (struct fiq_dma_blob *)(uintptr_t)st->dma_base;
+
+ len = fiq_get_xfer_len(st, n);
+ fiq_print(FIQDBG_INT, st, "LEN: %03d", len);
+@@ -249,7 +250,7 @@ static int notrace fiq_increment_dma_buf
+ if (i > 6)
+ BUG();
+
+- hcdma.d32 = (dma_addr_t) &blob->channel[n].index[i].buf[0];
++ hcdma.d32 = (u32)(uintptr_t)&blob->channel[n].index[i].buf[0];
+ FIQ_WRITE(st->dwc_regs_base + HC_START + (HC_OFFSET * n) + HC_DMA, hcdma.d32);
+ st->channel[n].dma_info.index = i;
+ return 0;
+@@ -289,7 +290,8 @@ static int notrace fiq_iso_out_advance(s
+ hcsplt_data_t hcsplt;
+ hctsiz_data_t hctsiz;
+ hcdma_data_t hcdma;
+- struct fiq_dma_blob *blob = (struct fiq_dma_blob *) st->dma_base;
++ struct fiq_dma_blob *blob =
++ (struct fiq_dma_blob *)(uintptr_t)st->dma_base;
+ int last = 0;
+ int i = st->channel[n].dma_info.index;
+
+@@ -301,7 +303,7 @@ static int notrace fiq_iso_out_advance(s
+ last = 1;
+
+ /* New DMA address - address of bounce buffer referred to in index */
+- hcdma.d32 = (dma_addr_t) blob->channel[n].index[i].buf;
++ hcdma.d32 = (u32)(uintptr_t)blob->channel[n].index[i].buf;
+ //hcdma.d32 = FIQ_READ(st->dwc_regs_base + HC_START + (HC_OFFSET * n) + HC_DMA);
+ //hcdma.d32 += st->channel[n].dma_info.slot_len[i];
+ fiq_print(FIQDBG_INT, st, "LAST: %01d ", last);
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
+@@ -1268,7 +1268,8 @@ static void assign_and_init_hc(dwc_otg_h
+ hc->multi_count = 1;
+
+ if (hcd->core_if->dma_enable) {
+- hc->xfer_buff = (uint8_t *) urb->dma + urb->actual_length;
++ hc->xfer_buff =
++ (uint8_t *)(uintptr_t)urb->dma + urb->actual_length;
+
+ /* For non-dword aligned case */
+ if (((unsigned long)hc->xfer_buff & 0x3)
+@@ -1312,7 +1313,8 @@ static void assign_and_init_hc(dwc_otg_h
+ hc->ep_is_in = 0;
+ hc->data_pid_start = DWC_OTG_HC_PID_SETUP;
+ if (hcd->core_if->dma_enable) {
+- hc->xfer_buff = (uint8_t *) urb->setup_dma;
++ hc->xfer_buff =
++ (uint8_t *)(uintptr_t)urb->setup_dma;
+ } else {
+ hc->xfer_buff = (uint8_t *) urb->setup_packet;
+ }
+@@ -1360,7 +1362,8 @@ static void assign_and_init_hc(dwc_otg_h
+
+ hc->xfer_len = 0;
+ if (hcd->core_if->dma_enable) {
+- hc->xfer_buff = (uint8_t *) hcd->status_buf_dma;
++ hc->xfer_buff = (uint8_t *)
++ (uintptr_t)hcd->status_buf_dma;
+ } else {
+ hc->xfer_buff = (uint8_t *) hcd->status_buf;
+ }
+@@ -1388,7 +1391,7 @@ static void assign_and_init_hc(dwc_otg_h
+ frame_desc->status = 0;
+
+ if (hcd->core_if->dma_enable) {
+- hc->xfer_buff = (uint8_t *) urb->dma;
++ hc->xfer_buff = (uint8_t *)(uintptr_t)urb->dma;
+ } else {
+ hc->xfer_buff = (uint8_t *) urb->buf;
+ }
+@@ -1569,8 +1572,10 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h
+ * Pointer arithmetic on hcd->fiq_state->dma_base (a dma_addr_t)
+ * to point it to the correct offset in the allocated buffers.
+ */
+- blob = (struct fiq_dma_blob *) hcd->fiq_state->dma_base;
+- st->hcdma_copy.d32 = (dma_addr_t) blob->channel[hc->hc_num].index[0].buf;
++ blob = (struct fiq_dma_blob *)
++ (uintptr_t)hcd->fiq_state->dma_base;
++ st->hcdma_copy.d32 =(u32)(uintptr_t)
++ blob->channel[hc->hc_num].index[0].buf;
+
+ /* Calculate the max number of CSPLITS such that the FIQ can time out
+ * a transaction if it fails.
+@@ -1625,8 +1630,10 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h
+ * dma_addr_t) to point it to the correct offset in the
+ * allocated buffers.
+ */
+- blob = (struct fiq_dma_blob *) hcd->fiq_state->dma_base;
+- st->hcdma_copy.d32 = (dma_addr_t) blob->channel[hc->hc_num].index[0].buf;
++ blob = (struct fiq_dma_blob *)
++ (uintptr_t)hcd->fiq_state->dma_base;
++ st->hcdma_copy.d32 = (u32)(uintptr_t)
++ blob->channel[hc->hc_num].index[0].buf;
+
+ /* fixup xfersize to the actual packet size */
+ st->hctsiz_copy.b.pid = 0;
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c
+@@ -620,7 +620,8 @@ static void init_non_isoc_dma_desc(dwc_o
+
+ if (n_desc) {
+ /* SG request - more than 1 QTDs */
+- hc->xfer_buff = (uint8_t *)qtd->urb->dma + qtd->urb->actual_length;
++ hc->xfer_buff = (uint8_t *)(uintptr_t)qtd->urb->dma +
++ qtd->urb->actual_length;
+ hc->xfer_len = qtd->urb->length - qtd->urb->actual_length;
+ }
+
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
+@@ -1857,10 +1857,10 @@ static int32_t handle_hc_ahberr_intr(dwc
+ DWC_ERROR(" Max packet size: %d\n",
+ dwc_otg_hcd_get_mps(&urb->pipe_info));
+ DWC_ERROR(" Data buffer length: %d\n", urb->length);
+- DWC_ERROR(" Transfer buffer: %p, Transfer DMA: %p\n",
+- urb->buf, (void *)urb->dma);
+- DWC_ERROR(" Setup buffer: %p, Setup DMA: %p\n",
+- urb->setup_packet, (void *)urb->setup_dma);
++ DWC_ERROR(" Transfer buffer: %p, Transfer DMA: %pad\n",
++ urb->buf, &urb->dma);
++ DWC_ERROR(" Setup buffer: %p, Setup DMA: %pad\n",
++ urb->setup_packet, &urb->setup_dma);
+ DWC_ERROR(" Interval: %d\n", urb->interval);
+
+ /* Core haltes the channel for Descriptor DMA mode */
diff --git a/target/linux/bcm27xx/patches-5.4/950-1006-bcm2708_fb-Fix-a-build-warning.patch b/target/linux/bcm27xx/patches-5.4/950-1006-bcm2708_fb-Fix-a-build-warning.patch
new file mode 100644
index 0000000000..2eb5f78dc3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1006-bcm2708_fb-Fix-a-build-warning.patch
@@ -0,0 +1,22 @@
+From 61ed3659dae5bdb4c7b1120b3ba4efd3e6abff05 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 27 Oct 2020 12:12:22 +0000
+Subject: [PATCH] bcm2708_fb: Fix a build warning
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/video/fbdev/bcm2708_fb.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/video/fbdev/bcm2708_fb.c
++++ b/drivers/video/fbdev/bcm2708_fb.c
+@@ -705,7 +705,8 @@ static long vc_mem_copy(struct bcm2708_f
+ u8 *q = (u8 *)ioparam->dst + offset;
+
+ dma_memcpy(fb, bus_addr,
+- INTALIAS_L1L2_NONALLOCATING((dma_addr_t)p), size);
++ INTALIAS_L1L2_NONALLOCATING((u32)(uintptr_t)p),
++ size);
+ if (copy_to_user(q, buf, s) != 0) {
+ pr_err("[%s]: failed to copy-to-user\n", __func__);
+ rc = -EFAULT;
diff --git a/target/linux/bcm27xx/patches-5.4/950-1007-bcm2835-pcm-Fix-up-multichannel-pcm-audio.patch b/target/linux/bcm27xx/patches-5.4/950-1007-bcm2835-pcm-Fix-up-multichannel-pcm-audio.patch
new file mode 100644
index 0000000000..a41d16edaf
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1007-bcm2835-pcm-Fix-up-multichannel-pcm-audio.patch
@@ -0,0 +1,55 @@
+From 88bddc0f26024c64e1e17562dea77d8a50e1f1d0 Mon Sep 17 00:00:00 2001
+From: Dom Cobley <popcornmix@gmail.com>
+Date: Tue, 27 Oct 2020 12:24:14 +0000
+Subject: [PATCH] bcm2835-pcm: Fix up multichannel pcm audio
+
+Fixes: a9c1660ff5f02d048c5f31abf1fd1108ccf9ef87
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+---
+ .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 21 +++++++++----------
+ 1 file changed, 10 insertions(+), 11 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c
++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c
+@@ -14,14 +14,14 @@ static const struct snd_pcm_hardware snd
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_SYNC_APPLPTR),
+ .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
+- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000,
++ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ .channels_min = 1,
+- .channels_max = 2,
+- .buffer_bytes_max = 128 * 1024,
++ .channels_max = 8,
++ .buffer_bytes_max = 512 * 1024,
+ .period_bytes_min = 1 * 1024,
+- .period_bytes_max = 128 * 1024,
++ .period_bytes_max = 512 * 1024,
+ .periods_min = 1,
+ .periods_max = 128,
+ };
+@@ -31,16 +31,15 @@ static const struct snd_pcm_hardware snd
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_SYNC_APPLPTR),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
+- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
+- SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
++ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 |
++ SNDRV_PCM_RATE_48000,
+ .rate_min = 44100,
+- .rate_max = 192000,
++ .rate_max = 48000,
+ .channels_min = 2,
+- .channels_max = 8,
+- .buffer_bytes_max = 512 * 1024,
++ .channels_max = 2,
++ .buffer_bytes_max = 128 * 1024,
+ .period_bytes_min = 1 * 1024,
+- .period_bytes_max = 512 * 1024,
++ .period_bytes_max = 128 * 1024,
+ .periods_min = 1,
+ .periods_max = 128,
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-1008-watchdog-bcm2835-Ignore-params-after-the-partition-n.patch b/target/linux/bcm27xx/patches-5.4/950-1008-watchdog-bcm2835-Ignore-params-after-the-partition-n.patch
new file mode 100644
index 0000000000..44108ecda5
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1008-watchdog-bcm2835-Ignore-params-after-the-partition-n.patch
@@ -0,0 +1,29 @@
+From 118538ed52b7dd927226837094d44a5d1cd14ab7 Mon Sep 17 00:00:00 2001
+From: Tim Gover <tim.gover@raspberrypi.org>
+Date: Thu, 22 Oct 2020 15:30:55 +0100
+Subject: [PATCH] watchdog: bcm2835: Ignore params after the
+ partition number
+
+Use sscanf to extract the partition number and ignore extra parameters
+which are only relevant to other reboot notifiers.
+---
+ drivers/watchdog/bcm2835_wdt.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/watchdog/bcm2835_wdt.c
++++ b/drivers/watchdog/bcm2835_wdt.c
+@@ -126,10 +126,12 @@ static int bcm2835_restart(struct watchd
+ {
+ struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
+
+- unsigned long long val;
++ unsigned long val;
+ u8 partition = 0;
+
+- if (data && !kstrtoull(data, 0, &val) && val <= 63)
++ // Allow extra arguments separated by spaces after
++ // the partition number.
++ if (data && sscanf(data, "%lu", &val) && val < 63)
+ partition = val;
+
+ __bcm2835_restart(wdt, partition);
diff --git a/target/linux/bcm27xx/patches-5.4/950-1009-firmware-raspberrypi-Add-support-for-tryonce-reboot-.patch b/target/linux/bcm27xx/patches-5.4/950-1009-firmware-raspberrypi-Add-support-for-tryonce-reboot-.patch
new file mode 100644
index 0000000000..4d7a83f02b
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1009-firmware-raspberrypi-Add-support-for-tryonce-reboot-.patch
@@ -0,0 +1,72 @@
+From bf41f32582df3ca5faab2cf2de15e5d4ff688822 Mon Sep 17 00:00:00 2001
+From: Tim Gover <tim.gover@raspberrypi.com>
+Date: Tue, 20 Oct 2020 11:55:37 +0100
+Subject: [PATCH] firmware: raspberrypi: Add support for tryonce
+ reboot flag
+
+Define a new mailbox (SET_REBOOT_FLAGS) which may be used to
+pass optional flags to the Raspberry Pi firmware that changes
+the behaviour of the bootloader and firmware during a reboot.
+
+Currently this just defines the 'tryboot' flag which causes
+the firmware to load tryboot.txt instead config.txt. This
+alternate configuration file can be used to specify the
+path of an alternate firmware and kernels allowing a fallback
+mechanism to be implemented for OS upgrades.
+---
+ drivers/firmware/raspberrypi.c | 25 ++++++++++++++++++++--
+ include/soc/bcm2835/raspberrypi-firmware.h | 2 ++
+ 2 files changed, 25 insertions(+), 2 deletions(-)
+
+--- a/drivers/firmware/raspberrypi.c
++++ b/drivers/firmware/raspberrypi.c
+@@ -190,6 +190,7 @@ static int rpi_firmware_notify_reboot(st
+ {
+ struct rpi_firmware *fw;
+ struct platform_device *pdev = g_pdev;
++ u32 reboot_flags = 0;
+
+ if (!pdev)
+ return 0;
+@@ -198,8 +199,28 @@ static int rpi_firmware_notify_reboot(st
+ if (!fw)
+ return 0;
+
+- (void)rpi_firmware_property(fw, RPI_FIRMWARE_NOTIFY_REBOOT,
+- 0, 0);
++ // The partition id is the first parameter followed by zero or
++ // more flags separated by spaces indicating the reason for the reboot.
++ //
++ // 'tryboot': Sets a one-shot flag which is cleared upon reboot and
++ // causes the tryboot.txt to be loaded instead of config.txt
++ // by the bootloader and the start.elf firmware.
++ //
++ // This is intended to allow automatic fallback to a known
++ // good image if an OS/FW upgrade fails.
++ //
++ // N.B. The firmware mechanism for storing reboot flags may vary
++ // on different Raspberry Pi models.
++ if (data && strstr(data, " tryboot"))
++ reboot_flags |= 0x1;
++
++ // The mailbox might have been called earlier, directly via vcmailbox
++ // so only overwrite if reboot flags are passed to the reboot command.
++ if (reboot_flags)
++ (void)rpi_firmware_property(fw, RPI_FIRMWARE_SET_REBOOT_FLAGS,
++ &reboot_flags, sizeof(reboot_flags));
++
++ (void)rpi_firmware_property(fw, RPI_FIRMWARE_NOTIFY_REBOOT, NULL, 0);
+
+ return 0;
+ }
+--- a/include/soc/bcm2835/raspberrypi-firmware.h
++++ b/include/soc/bcm2835/raspberrypi-firmware.h
+@@ -96,6 +96,8 @@ enum rpi_firmware_property_tag {
+ RPI_FIRMWARE_GET_POE_HAT_VAL = 0x00030049,
+ RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00030050,
+ RPI_FIRMWARE_NOTIFY_XHCI_RESET = 0x00030058,
++ RPI_FIRMWARE_GET_REBOOT_FLAGS = 0x00030064,
++ RPI_FIRMWARE_SET_REBOOT_FLAGS = 0x00038064,
+
+ /* Dispmanx TAGS */
+ RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001,
diff --git a/target/linux/bcm27xx/patches-5.4/950-1010-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch b/target/linux/bcm27xx/patches-5.4/950-1010-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch
new file mode 100644
index 0000000000..cf376b909e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1010-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch
@@ -0,0 +1,71 @@
+From 797cf96a09d1d4ee851a3998e590f7641cfc9b9a Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.org>
+Date: Tue, 14 May 2019 17:00:41 +0100
+Subject: [PATCH] phy: broadcom: split out the BCM54213PE from the
+ BCM54210E IDs
+
+The last nibble is a revision ID, and the 54213pe is a later rev
+than the 54210e. Running the 54210e setup code on a 54213pe results
+in a broken RGMII interface.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
+---
+ drivers/net/phy/broadcom.c | 16 +++++++++++++---
+ include/linux/brcmphy.h | 1 +
+ 2 files changed, 14 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/phy/broadcom.c
++++ b/drivers/net/phy/broadcom.c
+@@ -213,7 +213,8 @@ static void bcm54xx_adjust_rxrefclk(stru
+ /* Abort if we are using an untested phy. */
+ if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 &&
+ BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 &&
+- BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M)
++ BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M &&
++ BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54213PE)
+ return;
+
+ val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3);
+@@ -620,13 +621,21 @@ static struct phy_driver broadcom_driver
+ .config_intr = bcm_phy_config_intr,
+ }, {
+ .phy_id = PHY_ID_BCM54210E,
+- .phy_id_mask = 0xfffffff0,
++ .phy_id_mask = 0xffffffff,
+ .name = "Broadcom BCM54210E",
+ /* PHY_GBIT_FEATURES */
+ .config_init = bcm54xx_config_init,
+ .ack_interrupt = bcm_phy_ack_intr,
+ .config_intr = bcm_phy_config_intr,
+ }, {
++ .phy_id = PHY_ID_BCM54213PE,
++ .phy_id_mask = 0xffffffff,
++ .name = "Broadcom BCM54213PE",
++ /* PHY_GBIT_FEATURES */
++ .config_init = bcm54xx_config_init,
++ .ack_interrupt = bcm_phy_ack_intr,
++ .config_intr = bcm_phy_config_intr,
++}, {
+ .phy_id = PHY_ID_BCM5461,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Broadcom BCM5461",
+@@ -753,7 +762,8 @@ module_phy_driver(broadcom_drivers);
+ static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
+ { PHY_ID_BCM5411, 0xfffffff0 },
+ { PHY_ID_BCM5421, 0xfffffff0 },
+- { PHY_ID_BCM54210E, 0xfffffff0 },
++ { PHY_ID_BCM54210E, 0xffffffff },
++ { PHY_ID_BCM54213PE, 0xffffffff },
+ { PHY_ID_BCM5461, 0xfffffff0 },
+ { PHY_ID_BCM54612E, 0xfffffff0 },
+ { PHY_ID_BCM54616S, 0xfffffff0 },
+--- a/include/linux/brcmphy.h
++++ b/include/linux/brcmphy.h
+@@ -20,6 +20,7 @@
+ #define PHY_ID_BCM5411 0x00206070
+ #define PHY_ID_BCM5421 0x002060e0
+ #define PHY_ID_BCM54210E 0x600d84a0
++#define PHY_ID_BCM54213PE 0x600d84a2
+ #define PHY_ID_BCM5464 0x002060b0
+ #define PHY_ID_BCM5461 0x002060c0
+ #define PHY_ID_BCM54612E 0x03625e60
diff --git a/target/linux/bcm27xx/patches-5.4/950-1011-phy-broadcom-Add-bcm54213pe-configuration.patch b/target/linux/bcm27xx/patches-5.4/950-1011-phy-broadcom-Add-bcm54213pe-configuration.patch
new file mode 100644
index 0000000000..d4f6c24ccf
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1011-phy-broadcom-Add-bcm54213pe-configuration.patch
@@ -0,0 +1,35 @@
+From 9c08f4ff9f8f9e56011395dc064100ff6f139bdc Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 29 Oct 2020 14:10:56 +0000
+Subject: [PATCH] phy: broadcom: Add bcm54213pe configuration
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/net/phy/broadcom.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/net/phy/broadcom.c
++++ b/drivers/net/phy/broadcom.c
+@@ -43,6 +43,11 @@ static int bcm54210e_config_init(struct
+ return 0;
+ }
+
++static int bcm54213pe_config_init(struct phy_device *phydev)
++{
++ return bcm54210e_config_init(phydev);
++}
++
+ static int bcm54612e_config_init(struct phy_device *phydev)
+ {
+ int reg;
+@@ -304,6 +309,10 @@ static int bcm54xx_config_init(struct ph
+ err = bcm54210e_config_init(phydev);
+ if (err)
+ return err;
++ } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54213PE) {
++ err = bcm54213pe_config_init(phydev);
++ if (err)
++ return err;
+ } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54612E) {
+ err = bcm54612e_config_init(phydev);
+ if (err)
diff --git a/target/linux/bcm27xx/patches-5.4/950-1012-Allo-boss2-driver.patch b/target/linux/bcm27xx/patches-5.4/950-1012-Allo-boss2-driver.patch
new file mode 100644
index 0000000000..aacbc7dcbe
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1012-Allo-boss2-driver.patch
@@ -0,0 +1,1185 @@
+From 51ce8712f4633484615b9982dc48038b3b86e235 Mon Sep 17 00:00:00 2001
+From: Sudeep <sudeepkumar@cem-solutions.net>
+Date: Fri, 23 Oct 2020 15:47:17 +0530
+Subject: [PATCH] Allo boss2 driver
+
+Signed-off-by: Sudeep <sudeepkumar@cem-solutions.net>
+---
+ sound/soc/bcm/Kconfig | 9 +
+ sound/soc/bcm/Makefile | 2 +
+ sound/soc/bcm/allo-boss2-dac.c | 1133 ++++++++++++++++++++++++++++++++
+ 3 files changed, 1144 insertions(+)
+ create mode 100644 sound/soc/bcm/allo-boss2-dac.c
+
+--- a/sound/soc/bcm/Kconfig
++++ b/sound/soc/bcm/Kconfig
+@@ -258,6 +258,15 @@ config SND_BCM2708_SOC_ALLO_BOSS_DAC
+ help
+ Say Y or M if you want to add support for Allo Boss DAC.
+
++config SND_BCM2708_SOC_ALLO_BOSS2_DAC
++ tristate "Support for Allo Boss2 DAC"
++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
++ depends on I2C
++ select REGMAP_I2C
++ select SND_AUDIO_GRAPH_CARD
++ help
++ Say Y or M if you want to add support for Allo Boss2 DAC.
++
+ config SND_BCM2708_SOC_ALLO_DIGIONE
+ tristate "Support for Allo DigiOne"
+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
+--- a/sound/soc/bcm/Makefile
++++ b/sound/soc/bcm/Makefile
+@@ -33,6 +33,7 @@ snd-soc-digidac1-soundcard-objs := digid
+ snd-soc-dionaudio-loco-objs := dionaudio_loco.o
+ snd-soc-dionaudio-loco-v2-objs := dionaudio_loco-v2.o
+ snd-soc-allo-boss-dac-objs := allo-boss-dac.o
++snd-soc-allo-boss2-dac-objs := allo-boss2-dac.o
+ snd-soc-allo-piano-dac-objs := allo-piano-dac.o
+ snd-soc-allo-piano-dac-plus-objs := allo-piano-dac-plus.o
+ snd-soc-allo-katana-codec-objs := allo-katana-codec.o
+@@ -63,6 +64,7 @@ obj-$(CONFIG_SND_DIGIDAC1_SOUNDCARD) +=
+ obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO) += snd-soc-dionaudio-loco.o
+ obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2) += snd-soc-dionaudio-loco-v2.o
+ obj-$(CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC) += snd-soc-allo-boss-dac.o
++obj-$(CONFIG_SND_BCM2708_SOC_ALLO_BOSS2_DAC) += snd-soc-allo-boss2-dac.o
+ obj-$(CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC) += snd-soc-allo-piano-dac.o
+ obj-$(CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC_PLUS) += snd-soc-allo-piano-dac-plus.o
+ obj-$(CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC) += snd-soc-allo-katana-codec.o
+--- /dev/null
++++ b/sound/soc/bcm/allo-boss2-dac.c
+@@ -0,0 +1,1133 @@
++/*
++ * Driver for the ALLO KATANA CODEC
++ *
++ * Author: Jaikumar <sudeepkumar@cem-solutions.net>
++ * Copyright 2018
++ *
++ * 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 <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/gpio.h>
++#include <linux/gpio/consumer.h>
++#include <linux/platform_device.h>
++#include <linux/pm.h>
++#include <linux/i2c.h>
++#include <linux/of_device.h>
++#include <linux/regmap.h>
++#include <linux/slab.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/initval.h>
++#include <sound/tlv.h>
++#include <linux/of_gpio.h>
++#include <linux/regulator/consumer.h>
++#include <linux/pm_runtime.h>
++#include <linux/of_irq.h>
++#include <linux/completion.h>
++#include <linux/mutex.h>
++#include <linux/workqueue.h>
++#include <sound/jack.h>
++
++#include "../codecs/cs43130.h"
++
++#include <linux/clk.h>
++#include <linux/gcd.h>
++#define DEBUG
++
++#define CS43130_DSD_EN_MASK 0x10
++#define CS43130_PDN_DONE_INT_MASK 0x00
++
++static struct gpio_desc *snd_allo_clk44gpio;
++static struct gpio_desc *snd_allo_clk48gpio;
++
++struct cs43130_priv {
++ struct snd_soc_component *component;
++ struct regmap *regmap;
++ struct regulator_bulk_data supplies[CS43130_NUM_SUPPLIES];
++ struct gpio_desc *reset_gpio;
++ unsigned int dev_id; /* codec device ID */
++ int xtal_ibias;
++ /* shared by both DAIs */
++ struct mutex clk_mutex;
++ int clk_req;
++ bool pll_bypass;
++ struct completion xtal_rdy;
++ struct completion pll_rdy;
++ unsigned int mclk;
++ unsigned int mclk_int;
++ int mclk_int_src;
++
++ /* DAI specific */
++ struct cs43130_dai dais[CS43130_DAI_ID_MAX];
++
++ /* HP load specific */
++ bool dc_meas;
++ bool ac_meas;
++ bool hpload_done;
++ struct completion hpload_evt;
++ unsigned int hpload_stat;
++ u16 hpload_dc[2];
++ u16 dc_threshold[CS43130_DC_THRESHOLD];
++ u16 ac_freq[CS43130_AC_FREQ];
++ u16 hpload_ac[CS43130_AC_FREQ][2];
++ struct workqueue_struct *wq;
++ struct work_struct work;
++ struct snd_soc_jack jack;
++};
++
++static const struct reg_default cs43130_reg_defaults[] = {
++ {CS43130_SYS_CLK_CTL_1, 0x06},
++ {CS43130_SP_SRATE, 0x01},
++ {CS43130_SP_BITSIZE, 0x05},
++ {CS43130_PAD_INT_CFG, 0x03},
++ {CS43130_PWDN_CTL, 0xFE},
++ {CS43130_CRYSTAL_SET, 0x04},
++ {CS43130_PLL_SET_1, 0x00},
++ {CS43130_PLL_SET_2, 0x00},
++ {CS43130_PLL_SET_3, 0x00},
++ {CS43130_PLL_SET_4, 0x00},
++ {CS43130_PLL_SET_5, 0x40},
++ {CS43130_PLL_SET_6, 0x10},
++ {CS43130_PLL_SET_7, 0x80},
++ {CS43130_PLL_SET_8, 0x03},
++ {CS43130_PLL_SET_9, 0x02},
++ {CS43130_PLL_SET_10, 0x02},
++ {CS43130_CLKOUT_CTL, 0x00},
++ {CS43130_ASP_NUM_1, 0x01},
++ {CS43130_ASP_NUM_2, 0x00},
++ {CS43130_ASP_DEN_1, 0x08},
++ {CS43130_ASP_DEN_2, 0x00},
++ {CS43130_ASP_LRCK_HI_TIME_1, 0x1F},
++ {CS43130_ASP_LRCK_HI_TIME_2, 0x00},
++ {CS43130_ASP_LRCK_PERIOD_1, 0x3F},
++ {CS43130_ASP_LRCK_PERIOD_2, 0x00},
++ {CS43130_ASP_CLOCK_CONF, 0x0C},
++ {CS43130_ASP_FRAME_CONF, 0x0A},
++ {CS43130_XSP_NUM_1, 0x01},
++ {CS43130_XSP_NUM_2, 0x00},
++ {CS43130_XSP_DEN_1, 0x02},
++ {CS43130_XSP_DEN_2, 0x00},
++ {CS43130_XSP_LRCK_HI_TIME_1, 0x1F},
++ {CS43130_XSP_LRCK_HI_TIME_2, 0x00},
++ {CS43130_XSP_LRCK_PERIOD_1, 0x3F},
++ {CS43130_XSP_LRCK_PERIOD_2, 0x00},
++ {CS43130_XSP_CLOCK_CONF, 0x0C},
++ {CS43130_XSP_FRAME_CONF, 0x0A},
++ {CS43130_ASP_CH_1_LOC, 0x00},
++ {CS43130_ASP_CH_2_LOC, 0x00},
++ {CS43130_ASP_CH_1_SZ_EN, 0x06},
++ {CS43130_ASP_CH_2_SZ_EN, 0x0E},
++ {CS43130_XSP_CH_1_LOC, 0x00},
++ {CS43130_XSP_CH_2_LOC, 0x00},
++ {CS43130_XSP_CH_1_SZ_EN, 0x06},
++ {CS43130_XSP_CH_2_SZ_EN, 0x0E},
++ {CS43130_DSD_VOL_B, 0x78},
++ {CS43130_DSD_VOL_A, 0x78},
++ {CS43130_DSD_PATH_CTL_1, 0xA8},
++ {CS43130_DSD_INT_CFG, 0x00},
++ {CS43130_DSD_PATH_CTL_2, 0x02},
++ {CS43130_DSD_PCM_MIX_CTL, 0x00},
++ {CS43130_DSD_PATH_CTL_3, 0x40},
++ {CS43130_HP_OUT_CTL_1, 0x30},
++ {CS43130_PCM_FILT_OPT, 0x02},
++ {CS43130_PCM_VOL_B, 0x78},
++ {CS43130_PCM_VOL_A, 0x78},
++ {CS43130_PCM_PATH_CTL_1, 0xA8},
++ {CS43130_PCM_PATH_CTL_2, 0x00},
++ {CS43130_CLASS_H_CTL, 0x1E},
++ {CS43130_HP_DETECT, 0x04},
++ {CS43130_HP_LOAD_1, 0x00},
++ {CS43130_HP_MEAS_LOAD_1, 0x00},
++ {CS43130_HP_MEAS_LOAD_2, 0x00},
++ {CS43130_INT_MASK_1, 0xFF},
++ {CS43130_INT_MASK_2, 0xFF},
++ {CS43130_INT_MASK_3, 0xFF},
++ {CS43130_INT_MASK_4, 0xFF},
++ {CS43130_INT_MASK_5, 0xFF},
++};
++static bool cs43130_volatile_register(struct device *dev, unsigned int reg)
++{
++ switch (reg) {
++ case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:
++ case CS43130_HP_DC_STAT_1 ... CS43130_HP_DC_STAT_2:
++ case CS43130_HP_AC_STAT_1 ... CS43130_HP_AC_STAT_2:
++ return true;
++ default:
++ return false;
++ }
++}
++
++static const char * const pcm_spd_texts[] = {
++ "Fast",
++ "Slow",
++};
++
++static SOC_ENUM_SINGLE_DECL(pcm_spd_enum, CS43130_PCM_FILT_OPT, 7,
++ pcm_spd_texts);
++
++static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(master_tlv, -12750, 0);
++
++static const struct snd_kcontrol_new cs43130_controls[] = {
++ SOC_DOUBLE_R_TLV("Master Playback Volume", CS43130_PCM_VOL_B,
++ CS43130_PCM_VOL_A, 0, 255, 1, master_tlv),
++ SOC_DOUBLE("Master Playback Switch", CS43130_PCM_PATH_CTL_1,
++ 0, 1, 1, 1),
++ SOC_DOUBLE_R_TLV("Digital Playback Volume", CS43130_DSD_VOL_B,
++ CS43130_DSD_VOL_A, 0, 255, 1, master_tlv),
++ SOC_DOUBLE("Digital Playback Switch", CS43130_DSD_PATH_CTL_1,
++ 0, 1, 1, 1),
++ SOC_SINGLE("HV_Enable", CS43130_HP_OUT_CTL_1, 0, 1, 0),
++ SOC_ENUM("PCM Filter Speed", pcm_spd_enum),
++ SOC_SINGLE("PCM Phase Compensation", CS43130_PCM_FILT_OPT, 6, 1, 0),
++ SOC_SINGLE("PCM Nonoversample Emulate", CS43130_PCM_FILT_OPT, 5, 1, 0),
++ SOC_SINGLE("PCM High-pass Filter", CS43130_PCM_FILT_OPT, 1, 1, 0),
++ SOC_SINGLE("PCM De-emphasis Filter", CS43130_PCM_FILT_OPT, 0, 1, 0),
++};
++
++static bool cs43130_readable_register(struct device *dev, unsigned int reg)
++{
++ switch (reg) {
++ case CS43130_DEVID_AB ... CS43130_SYS_CLK_CTL_1:
++ case CS43130_SP_SRATE ... CS43130_PAD_INT_CFG:
++ case CS43130_PWDN_CTL:
++ case CS43130_CRYSTAL_SET:
++ case CS43130_PLL_SET_1 ... CS43130_PLL_SET_5:
++ case CS43130_PLL_SET_6:
++ case CS43130_PLL_SET_7:
++ case CS43130_PLL_SET_8:
++ case CS43130_PLL_SET_9:
++ case CS43130_PLL_SET_10:
++ case CS43130_CLKOUT_CTL:
++ case CS43130_ASP_NUM_1 ... CS43130_ASP_FRAME_CONF:
++ case CS43130_XSP_NUM_1 ... CS43130_XSP_FRAME_CONF:
++ case CS43130_ASP_CH_1_LOC:
++ case CS43130_ASP_CH_2_LOC:
++ case CS43130_ASP_CH_1_SZ_EN:
++ case CS43130_ASP_CH_2_SZ_EN:
++ case CS43130_XSP_CH_1_LOC:
++ case CS43130_XSP_CH_2_LOC:
++ case CS43130_XSP_CH_1_SZ_EN:
++ case CS43130_XSP_CH_2_SZ_EN:
++ case CS43130_DSD_VOL_B ... CS43130_DSD_PATH_CTL_3:
++ case CS43130_HP_OUT_CTL_1:
++ case CS43130_PCM_FILT_OPT ... CS43130_PCM_PATH_CTL_2:
++ case CS43130_CLASS_H_CTL:
++ case CS43130_HP_DETECT:
++ case CS43130_HP_STATUS:
++ case CS43130_HP_LOAD_1:
++ case CS43130_HP_MEAS_LOAD_1:
++ case CS43130_HP_MEAS_LOAD_2:
++ case CS43130_HP_DC_STAT_1:
++ case CS43130_HP_DC_STAT_2:
++ case CS43130_HP_AC_STAT_1:
++ case CS43130_HP_AC_STAT_2:
++ case CS43130_HP_LOAD_STAT:
++ case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:
++ case CS43130_INT_MASK_1 ... CS43130_INT_MASK_5:
++ return true;
++ default:
++ return false;
++ }
++}
++static bool cs43130_precious_register(struct device *dev, unsigned int reg)
++{
++ switch (reg) {
++ case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:
++ return true;
++ default:
++ return false;
++ }
++}
++static int cs43130_pcm_pdn(struct snd_soc_component *component)
++{
++ struct cs43130_priv *cs43130 =
++ snd_soc_component_get_drvdata(component);
++ int ret;
++ unsigned int reg, pdn_int;
++
++ regmap_write(cs43130->regmap, CS43130_DSD_PATH_CTL_2, 0x02);
++ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
++ CS43130_PDN_DONE_INT_MASK, 0);
++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
++ CS43130_PDN_HP_MASK, 1 << CS43130_PDN_HP_SHIFT);
++ usleep_range(10, 50);
++ ret = regmap_read(cs43130->regmap, CS43130_INT_STATUS_1, &reg);
++ pdn_int = reg & 0xFE;
++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
++ CS43130_PDN_ASP_MASK, 1 << CS43130_PDN_ASP_SHIFT);
++ return 0;
++
++}
++static int cs43130_pwr_up_asp_dac(struct snd_soc_component *component)
++{
++ struct cs43130_priv *cs43130 =
++ snd_soc_component_get_drvdata(component);
++
++ regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG,
++ CS43130_ASP_3ST_MASK, 0);
++ regmap_write(cs43130->regmap, CS43130_DXD1, 0x99);
++ regmap_write(cs43130->regmap, CS43130_DXD13, 0x20);
++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
++ CS43130_PDN_ASP_MASK, 0);
++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
++ CS43130_PDN_HP_MASK, 0);
++ usleep_range(10000, 12000);
++ regmap_write(cs43130->regmap, CS43130_DXD1, 0x00);
++ regmap_write(cs43130->regmap, CS43130_DXD13, 0x00);
++ return 0;
++}
++static int cs43130_change_clksrc(struct snd_soc_component *component,
++ enum cs43130_mclk_src_sel src)
++{
++ int ret;
++ struct cs43130_priv *cs43130 =
++ snd_soc_component_get_drvdata(component);
++ int mclk_int_decoded;
++
++ if (src == cs43130->mclk_int_src) {
++ /* clk source has not changed */
++ return 0;
++ }
++ switch (cs43130->mclk_int) {
++ case CS43130_MCLK_22M:
++ mclk_int_decoded = CS43130_MCLK_22P5;
++ break;
++ case CS43130_MCLK_24M:
++ mclk_int_decoded = CS43130_MCLK_24P5;
++ break;
++ default:
++ dev_err(component->dev, "Invalid MCLK INT freq: %u\n",
++ cs43130->mclk_int);
++ return -EINVAL;
++ }
++
++ switch (src) {
++ case CS43130_MCLK_SRC_EXT:
++ cs43130->pll_bypass = true;
++ cs43130->mclk_int_src = CS43130_MCLK_SRC_EXT;
++ if (cs43130->xtal_ibias == CS43130_XTAL_UNUSED) {
++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
++ CS43130_PDN_XTAL_MASK,
++ 1 << CS43130_PDN_XTAL_SHIFT);
++ } else {
++ reinit_completion(&cs43130->xtal_rdy);
++ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
++ CS43130_XTAL_RDY_INT_MASK, 0);
++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
++ CS43130_PDN_XTAL_MASK, 0);
++ ret = wait_for_completion_timeout(&cs43130->xtal_rdy,
++ msecs_to_jiffies(100));
++ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
++ CS43130_XTAL_RDY_INT_MASK,
++ 1 << CS43130_XTAL_RDY_INT_SHIFT);
++ if (ret == 0) {
++ dev_err(component->dev, "Timeout waiting for XTAL_READY interrupt\n");
++ return -ETIMEDOUT;
++ }
++ }
++ regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
++ CS43130_MCLK_SRC_SEL_MASK,
++ src << CS43130_MCLK_SRC_SEL_SHIFT);
++ regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
++ CS43130_MCLK_INT_MASK,
++ mclk_int_decoded << CS43130_MCLK_INT_SHIFT);
++ usleep_range(150, 200);
++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
++ CS43130_PDN_PLL_MASK,
++ 1 << CS43130_PDN_PLL_SHIFT);
++ break;
++ case CS43130_MCLK_SRC_RCO:
++ cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO;
++
++ regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
++ CS43130_MCLK_SRC_SEL_MASK,
++ src << CS43130_MCLK_SRC_SEL_SHIFT);
++ regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
++ CS43130_MCLK_INT_MASK,
++ CS43130_MCLK_22P5 << CS43130_MCLK_INT_SHIFT);
++ usleep_range(150, 200);
++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
++ CS43130_PDN_XTAL_MASK,
++ 1 << CS43130_PDN_XTAL_SHIFT);
++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
++ CS43130_PDN_PLL_MASK,
++ 1 << CS43130_PDN_PLL_SHIFT);
++ break;
++ default:
++ dev_err(component->dev, "Invalid MCLK source value\n");
++ return -EINVAL;
++ }
++
++ return 0;
++}
++static const struct cs43130_bitwidth_map cs43130_bitwidth_table[] = {
++ {8, CS43130_SP_BIT_SIZE_8, CS43130_CH_BIT_SIZE_8},
++ {16, CS43130_SP_BIT_SIZE_16, CS43130_CH_BIT_SIZE_16},
++ {24, CS43130_SP_BIT_SIZE_24, CS43130_CH_BIT_SIZE_24},
++ {32, CS43130_SP_BIT_SIZE_32, CS43130_CH_BIT_SIZE_32},
++};
++
++static const struct cs43130_bitwidth_map *cs43130_get_bitwidth_table(
++ unsigned int bitwidth)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(cs43130_bitwidth_table); i++) {
++ if (cs43130_bitwidth_table[i].bitwidth == bitwidth)
++ return &cs43130_bitwidth_table[i];
++ }
++
++ return NULL;
++}
++static int cs43130_set_bitwidth(int dai_id, unsigned int bitwidth_dai,
++ struct regmap *regmap)
++{
++ const struct cs43130_bitwidth_map *bw_map;
++
++ bw_map = cs43130_get_bitwidth_table(bitwidth_dai);
++ if (!bw_map)
++ return -EINVAL;
++
++ switch (dai_id) {
++ case CS43130_ASP_PCM_DAI:
++ case CS43130_ASP_DOP_DAI:
++ regmap_update_bits(regmap, CS43130_ASP_CH_1_SZ_EN,
++ CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
++ regmap_update_bits(regmap, CS43130_ASP_CH_2_SZ_EN,
++ CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
++ regmap_update_bits(regmap, CS43130_SP_BITSIZE,
++ CS43130_ASP_BITSIZE_MASK, bw_map->sp_bit);
++ break;
++ case CS43130_XSP_DOP_DAI:
++ regmap_update_bits(regmap, CS43130_XSP_CH_1_SZ_EN,
++ CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
++ regmap_update_bits(regmap, CS43130_XSP_CH_2_SZ_EN,
++ CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
++ regmap_update_bits(regmap, CS43130_SP_BITSIZE,
++ CS43130_XSP_BITSIZE_MASK, bw_map->sp_bit <<
++ CS43130_XSP_BITSIZE_SHIFT);
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
++}
++static const struct cs43130_rate_map cs43130_rate_table[] = {
++ {32000, CS43130_ASP_SPRATE_32K},
++ {44100, CS43130_ASP_SPRATE_44_1K},
++ {48000, CS43130_ASP_SPRATE_48K},
++ {88200, CS43130_ASP_SPRATE_88_2K},
++ {96000, CS43130_ASP_SPRATE_96K},
++ {176400, CS43130_ASP_SPRATE_176_4K},
++ {192000, CS43130_ASP_SPRATE_192K},
++ {352800, CS43130_ASP_SPRATE_352_8K},
++ {384000, CS43130_ASP_SPRATE_384K},
++};
++
++static const struct cs43130_rate_map *cs43130_get_rate_table(int fs)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(cs43130_rate_table); i++) {
++ if (cs43130_rate_table[i].fs == fs)
++ return &cs43130_rate_table[i];
++ }
++
++ return NULL;
++}
++
++static const struct cs43130_clk_gen *cs43130_get_clk_gen(int mclk_int, int fs,
++ const struct cs43130_clk_gen *clk_gen_table, int len_clk_gen_table)
++{
++ int i;
++
++ for (i = 0; i < len_clk_gen_table; i++) {
++ if (clk_gen_table[i].mclk_int == mclk_int &&
++ clk_gen_table[i].fs == fs)
++ return &clk_gen_table[i];
++ }
++ return NULL;
++}
++
++static int cs43130_set_sp_fmt(int dai_id, unsigned int bitwidth_sclk,
++ struct snd_pcm_hw_params *params,
++ struct cs43130_priv *cs43130)
++{
++ u16 frm_size;
++ u16 hi_size;
++ u8 frm_delay;
++ u8 frm_phase;
++ u8 frm_data;
++ u8 sclk_edge;
++ u8 lrck_edge;
++ u8 clk_data;
++ u8 loc_ch1;
++ u8 loc_ch2;
++ u8 dai_mode_val;
++ const struct cs43130_clk_gen *clk_gen;
++
++ switch (cs43130->dais[dai_id].dai_format) {
++ case SND_SOC_DAIFMT_I2S:
++ hi_size = bitwidth_sclk;
++ frm_delay = 2;
++ frm_phase = 0;
++ break;
++ case SND_SOC_DAIFMT_LEFT_J:
++ hi_size = bitwidth_sclk;
++ frm_delay = 2;
++ frm_phase = 1;
++ break;
++ case SND_SOC_DAIFMT_DSP_A:
++ hi_size = 1;
++ frm_delay = 2;
++ frm_phase = 1;
++ break;
++ case SND_SOC_DAIFMT_DSP_B:
++ hi_size = 1;
++ frm_delay = 0;
++ frm_phase = 1;
++ break;
++ default:
++ return -EINVAL;
++ }
++ switch (cs43130->dais[dai_id].dai_mode) {
++ case SND_SOC_DAIFMT_CBS_CFS:
++ dai_mode_val = 0;
++ break;
++ case SND_SOC_DAIFMT_CBM_CFM:
++ dai_mode_val = 1;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ frm_size = bitwidth_sclk * params_channels(params);
++ sclk_edge = 1;
++ lrck_edge = 0;
++ loc_ch1 = 0;
++ loc_ch2 = bitwidth_sclk * (params_channels(params) - 1);
++
++ frm_data = frm_delay & CS43130_SP_FSD_MASK;
++ frm_data |= (frm_phase << CS43130_SP_STP_SHIFT) & CS43130_SP_STP_MASK;
++
++ clk_data = lrck_edge & CS43130_SP_LCPOL_IN_MASK;
++ clk_data |= (lrck_edge << CS43130_SP_LCPOL_OUT_SHIFT) &
++ CS43130_SP_LCPOL_OUT_MASK;
++ clk_data |= (sclk_edge << CS43130_SP_SCPOL_IN_SHIFT) &
++ CS43130_SP_SCPOL_IN_MASK;
++ clk_data |= (sclk_edge << CS43130_SP_SCPOL_OUT_SHIFT) &
++ CS43130_SP_SCPOL_OUT_MASK;
++ clk_data |= (dai_mode_val << CS43130_SP_MODE_SHIFT) &
++ CS43130_SP_MODE_MASK;
++ switch (dai_id) {
++ case CS43130_ASP_PCM_DAI:
++ case CS43130_ASP_DOP_DAI:
++ regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_1,
++ CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
++ CS43130_SP_LCPR_LSB_DATA_SHIFT);
++ regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_2,
++ CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
++ CS43130_SP_LCPR_MSB_DATA_SHIFT);
++ regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_1,
++ CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
++ CS43130_SP_LCHI_LSB_DATA_SHIFT);
++ regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_2,
++ CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
++ CS43130_SP_LCHI_MSB_DATA_SHIFT);
++ regmap_write(cs43130->regmap, CS43130_ASP_FRAME_CONF, frm_data);
++ regmap_write(cs43130->regmap, CS43130_ASP_CH_1_LOC, loc_ch1);
++ regmap_write(cs43130->regmap, CS43130_ASP_CH_2_LOC, loc_ch2);
++ regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_1_SZ_EN,
++ CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
++ regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_2_SZ_EN,
++ CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
++ regmap_write(cs43130->regmap, CS43130_ASP_CLOCK_CONF, clk_data);
++ break;
++ case CS43130_XSP_DOP_DAI:
++ regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_1,
++ CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
++ CS43130_SP_LCPR_LSB_DATA_SHIFT);
++ regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_2,
++ CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
++ CS43130_SP_LCPR_MSB_DATA_SHIFT);
++ regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_1,
++ CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
++ CS43130_SP_LCHI_LSB_DATA_SHIFT);
++ regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_2,
++ CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
++ CS43130_SP_LCHI_MSB_DATA_SHIFT);
++ regmap_write(cs43130->regmap, CS43130_XSP_FRAME_CONF, frm_data);
++ regmap_write(cs43130->regmap, CS43130_XSP_CH_1_LOC, loc_ch1);
++ regmap_write(cs43130->regmap, CS43130_XSP_CH_2_LOC, loc_ch2);
++ regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_1_SZ_EN,
++ CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
++ regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_2_SZ_EN,
++ CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
++ regmap_write(cs43130->regmap, CS43130_XSP_CLOCK_CONF, clk_data);
++ break;
++ default:
++ return -EINVAL;
++ }
++ switch (frm_size) {
++ case 16:
++ clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
++ params_rate(params),
++ cs43130_16_clk_gen,
++ ARRAY_SIZE(cs43130_16_clk_gen));
++ break;
++ case 32:
++ clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
++ params_rate(params),
++ cs43130_32_clk_gen,
++ ARRAY_SIZE(cs43130_32_clk_gen));
++ break;
++ case 48:
++ clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
++ params_rate(params),
++ cs43130_48_clk_gen,
++ ARRAY_SIZE(cs43130_48_clk_gen));
++ break;
++ case 64:
++ clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
++ params_rate(params),
++ cs43130_64_clk_gen,
++ ARRAY_SIZE(cs43130_64_clk_gen));
++ break;
++ default:
++ return -EINVAL;
++ }
++ if (!clk_gen)
++ return -EINVAL;
++ switch (dai_id) {
++ case CS43130_ASP_PCM_DAI:
++ case CS43130_ASP_DOP_DAI:
++ regmap_write(cs43130->regmap, CS43130_ASP_DEN_1,
++ (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >>
++ CS43130_SP_M_LSB_DATA_SHIFT);
++ regmap_write(cs43130->regmap, CS43130_ASP_DEN_2,
++ (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >>
++ CS43130_SP_M_MSB_DATA_SHIFT);
++ regmap_write(cs43130->regmap, CS43130_ASP_NUM_1,
++ (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >>
++ CS43130_SP_N_LSB_DATA_SHIFT);
++ regmap_write(cs43130->regmap, CS43130_ASP_NUM_2,
++ (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >>
++ CS43130_SP_N_MSB_DATA_SHIFT);
++ break;
++ case CS43130_XSP_DOP_DAI:
++ regmap_write(cs43130->regmap, CS43130_XSP_DEN_1,
++ (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >>
++ CS43130_SP_M_LSB_DATA_SHIFT);
++ regmap_write(cs43130->regmap, CS43130_XSP_DEN_2,
++ (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >>
++ CS43130_SP_M_MSB_DATA_SHIFT);
++ regmap_write(cs43130->regmap, CS43130_XSP_NUM_1,
++ (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >>
++ CS43130_SP_N_LSB_DATA_SHIFT);
++ regmap_write(cs43130->regmap, CS43130_XSP_NUM_2,
++ (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >>
++ CS43130_SP_N_MSB_DATA_SHIFT);
++ break;
++ default:
++ return -EINVAL;
++ }
++ return 0;
++}
++
++static int cs43130_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params,
++ struct snd_soc_dai *dai)
++{
++ struct snd_soc_component *component = dai->component;
++ struct cs43130_priv *cs43130 =
++ snd_soc_component_get_drvdata(component);
++ const struct cs43130_rate_map *rate_map;
++ unsigned int sclk = cs43130->dais[dai->id].sclk;
++ unsigned int bitwidth_sclk;
++ unsigned int bitwidth_dai = (unsigned int)(params_width(params));
++ unsigned int dop_rate = (unsigned int)(params_rate(params));
++ unsigned int required_clk, ret;
++ u8 dsd_speed;
++
++ cs43130->pll_bypass = true;
++ cs43130_pcm_pdn(component);
++ mutex_lock(&cs43130->clk_mutex);
++ if (!cs43130->clk_req) {
++ /* no DAI is currently using clk */
++ if (!(CS43130_MCLK_22M % params_rate(params))) {
++ required_clk = CS43130_MCLK_22M;
++ cs43130->mclk_int = CS43130_MCLK_22M;
++ gpiod_set_value_cansleep(snd_allo_clk44gpio, 1);
++ gpiod_set_value_cansleep(snd_allo_clk48gpio, 0);
++ usleep_range(13500, 14000);
++ } else {
++ required_clk = CS43130_MCLK_24M;
++ cs43130->mclk_int = CS43130_MCLK_24M;
++ gpiod_set_value_cansleep(snd_allo_clk48gpio, 1);
++ gpiod_set_value_cansleep(snd_allo_clk44gpio, 0);
++ usleep_range(13500, 14000);
++ }
++ if (cs43130->pll_bypass)
++ cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);
++ else
++ cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);
++ }
++
++ cs43130->clk_req++;
++ mutex_unlock(&cs43130->clk_mutex);
++
++ switch (dai->id) {
++ case CS43130_ASP_DOP_DAI:
++ case CS43130_XSP_DOP_DAI:
++ /* DoP bitwidth is always 24-bit */
++ bitwidth_dai = 24;
++ sclk = params_rate(params) * bitwidth_dai *
++ params_channels(params);
++
++ switch (params_rate(params)) {
++ case 176400:
++ dsd_speed = 0;
++ break;
++ case 352800:
++ dsd_speed = 1;
++ break;
++ default:
++ dev_err(component->dev, "Rate(%u) not supported\n",
++ params_rate(params));
++ return -EINVAL;
++ }
++
++ regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
++ CS43130_DSD_SPEED_MASK,
++ dsd_speed << CS43130_DSD_SPEED_SHIFT);
++ break;
++ case CS43130_ASP_PCM_DAI:
++ rate_map = cs43130_get_rate_table(params_rate(params));
++ if (!rate_map)
++ return -EINVAL;
++
++ regmap_write(cs43130->regmap, CS43130_SP_SRATE, rate_map->val);
++ if ((dop_rate == 176400) && (bitwidth_dai == 24)) {
++ dsd_speed = 0;
++ regmap_update_bits(cs43130->regmap,
++ CS43130_DSD_PATH_CTL_2,
++ CS43130_DSD_SPEED_MASK,
++ dsd_speed << CS43130_DSD_SPEED_SHIFT);
++ regmap_update_bits(cs43130->regmap,
++ CS43130_DSD_PATH_CTL_2,
++ CS43130_DSD_SRC_MASK,
++ CS43130_DSD_SRC_ASP <<
++ CS43130_DSD_SRC_SHIFT);
++ regmap_update_bits(cs43130->regmap,
++ CS43130_DSD_PATH_CTL_2,
++ CS43130_DSD_EN_MASK, 0x01 <<
++ CS43130_DSD_EN_SHIFT);
++ }
++ break;
++ default:
++ dev_err(component->dev, "Invalid DAI (%d)\n", dai->id);
++ return -EINVAL;
++ }
++
++ switch (dai->id) {
++ case CS43130_ASP_DOP_DAI:
++ regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
++ CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_ASP <<
++ CS43130_DSD_SRC_SHIFT);
++ regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
++ CS43130_DSD_EN_MASK, 0x01 <<
++ CS43130_DSD_EN_SHIFT);
++ break;
++ case CS43130_XSP_DOP_DAI:
++ regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
++ CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_XSP <<
++ CS43130_DSD_SRC_SHIFT);
++ break;
++ }
++ if (!sclk && cs43130->dais[dai->id].dai_mode ==
++ SND_SOC_DAIFMT_CBM_CFM) {
++ /* Calculate SCLK in master mode if unassigned */
++ sclk = params_rate(params) * bitwidth_dai *
++ params_channels(params);
++ }
++ if (!sclk) {
++ /* at this point, SCLK must be set */
++ dev_err(component->dev, "SCLK freq is not set\n");
++ return -EINVAL;
++ }
++
++ bitwidth_sclk = (sclk / params_rate(params)) / params_channels(params);
++ if (bitwidth_sclk < bitwidth_dai) {
++ dev_err(component->dev, "Format not supported: SCLK freq is too low\n");
++ return -EINVAL;
++ }
++
++ dev_dbg(component->dev,
++ "sclk = %u, fs = %d, bitwidth_dai = %u\n",
++ sclk, params_rate(params), bitwidth_dai);
++
++ dev_dbg(component->dev,
++ "bitwidth_sclk = %u, num_ch = %u\n",
++ bitwidth_sclk, params_channels(params));
++
++ cs43130_set_bitwidth(dai->id, bitwidth_dai, cs43130->regmap);
++ cs43130_set_sp_fmt(dai->id, bitwidth_sclk, params, cs43130);
++ ret = cs43130_pwr_up_asp_dac(component);
++ return 0;
++}
++
++static int cs43130_hw_free(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *dai)
++{
++ struct snd_soc_component *component = dai->component;
++ struct cs43130_priv *cs43130 =
++ snd_soc_component_get_drvdata(component);
++
++ mutex_lock(&cs43130->clk_mutex);
++ cs43130->clk_req--;
++ if (!cs43130->clk_req) {
++ /* no DAI is currently using clk */
++ cs43130_change_clksrc(component, CS43130_MCLK_SRC_RCO);
++ cs43130_pcm_pdn(component);
++ }
++ mutex_unlock(&cs43130->clk_mutex);
++
++ return 0;
++}
++
++static const unsigned int cs43130_asp_src_rates[] = {
++ 32000, 44100, 48000, 88200, 96000, 176400, 192000
++};
++
++static const struct snd_pcm_hw_constraint_list cs43130_asp_constraints = {
++ .count = ARRAY_SIZE(cs43130_asp_src_rates),
++ .list = cs43130_asp_src_rates,
++};
++
++static int cs43130_pcm_startup(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *dai)
++{
++ return snd_pcm_hw_constraint_list(substream->runtime, 0,
++ SNDRV_PCM_HW_PARAM_RATE,
++ &cs43130_asp_constraints);
++}
++
++static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
++{
++ struct snd_soc_component *component = codec_dai->component;
++ struct cs43130_priv *cs43130 =
++ snd_soc_component_get_drvdata(component);
++
++ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++ case SND_SOC_DAIFMT_CBS_CFS:
++ cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS;
++ break;
++ case SND_SOC_DAIFMT_CBM_CFM:
++ cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM;
++ break;
++ default:
++ dev_err(component->dev, "unsupported mode\n");
++ return -EINVAL;
++ }
++
++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++ case SND_SOC_DAIFMT_I2S:
++ cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_I2S;
++ break;
++ case SND_SOC_DAIFMT_LEFT_J:
++ cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_LEFT_J;
++ break;
++ default:
++ dev_err(component->dev,
++ "unsupported audio format\n");
++ return -EINVAL;
++ }
++
++ dev_dbg(component->dev, "dai_id = %d, dai_mode = %u, dai_format = %u\n",
++ codec_dai->id,
++ cs43130->dais[codec_dai->id].dai_mode,
++ cs43130->dais[codec_dai->id].dai_format);
++
++ return 0;
++}
++
++static int cs43130_set_sysclk(struct snd_soc_dai *codec_dai,
++ int clk_id, unsigned int freq, int dir)
++{
++ struct snd_soc_component *component = codec_dai->component;
++ struct cs43130_priv *cs43130 =
++ snd_soc_component_get_drvdata(component);
++
++ cs43130->dais[codec_dai->id].sclk = freq;
++ dev_dbg(component->dev, "dai_id = %d, sclk = %u\n", codec_dai->id,
++ cs43130->dais[codec_dai->id].sclk);
++
++ return 0;
++}
++
++static int cs43130_component_set_sysclk(struct snd_soc_component *component,
++ int clk_id, int source,
++ unsigned int freq, int dir)
++{
++ struct cs43130_priv *cs43130 =
++ snd_soc_component_get_drvdata(component);
++
++ dev_dbg(component->dev, "clk_id = %d, source = %d, freq = %d, dir = %d\n",
++ clk_id, source, freq, dir);
++
++ switch (freq) {
++ case CS43130_MCLK_22M:
++ case CS43130_MCLK_24M:
++ cs43130->mclk = freq;
++ break;
++ default:
++ dev_err(component->dev, "Invalid MCLK INT freq: %u\n", freq);
++ return -EINVAL;
++ }
++
++ if (source == CS43130_MCLK_SRC_EXT) {
++ cs43130->pll_bypass = true;
++ } else {
++ dev_err(component->dev, "Invalid MCLK source\n");
++ return -EINVAL;
++ }
++
++ return 0;
++}
++static u16 const cs43130_ac_freq[CS43130_AC_FREQ] = {
++ 24,
++ 43,
++ 93,
++ 200,
++ 431,
++ 928,
++ 2000,
++ 4309,
++ 9283,
++ 20000,
++};
++static const struct snd_soc_dai_ops cs43130_dai_ops = {
++ .startup = cs43130_pcm_startup,
++ .hw_params = cs43130_hw_params,
++ .hw_free = cs43130_hw_free,
++ .set_sysclk = cs43130_set_sysclk,
++ .set_fmt = cs43130_pcm_set_fmt,
++};
++
++static struct snd_soc_dai_driver cs43130_codec_dai = {
++ .name = "allo-cs43130",
++ .playback = {
++ .stream_name = "Playback",
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = SNDRV_PCM_RATE_CONTINUOUS,
++ .rate_min = 44100,
++ .rate_max = 192000,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE |
++ SNDRV_PCM_FMTBIT_S24_LE |
++ SNDRV_PCM_FMTBIT_S32_LE
++
++ },
++ .ops = &cs43130_dai_ops,
++};
++
++static struct snd_soc_component_driver cs43130_component_driver = {
++ .idle_bias_on = true,
++ .controls = cs43130_controls,
++ .num_controls = ARRAY_SIZE(cs43130_controls),
++ .set_sysclk = cs43130_component_set_sysclk,
++ .idle_bias_on = 1,
++ .use_pmdown_time = 1,
++ .endianness = 1,
++ .non_legacy_dai_naming = 1,
++};
++
++static const struct regmap_config cs43130_regmap = {
++ .reg_bits = 24,
++ .pad_bits = 8,
++ .val_bits = 8,
++
++ .max_register = CS43130_LASTREG,
++ .reg_defaults = cs43130_reg_defaults,
++ .num_reg_defaults = ARRAY_SIZE(cs43130_reg_defaults),
++ .readable_reg = cs43130_readable_register,
++ .precious_reg = cs43130_precious_register,
++ .volatile_reg = cs43130_volatile_register,
++ .cache_type = REGCACHE_RBTREE,
++ /* needed for regcache_sync */
++ .use_single_read = true,
++ .use_single_write = true,
++};
++
++static u16 const cs43130_dc_threshold[CS43130_DC_THRESHOLD] = {
++ 50,
++ 120,
++};
++
++static int cs43130_handle_device_data(struct i2c_client *i2c_client,
++ struct cs43130_priv *cs43130)
++{
++ struct device_node *np = i2c_client->dev.of_node;
++ unsigned int val;
++ int i;
++
++ if (of_property_read_u32(np, "cirrus,xtal-ibias", &val) < 0) {
++ /* Crystal is unused. System clock is used for external MCLK */
++ cs43130->xtal_ibias = CS43130_XTAL_UNUSED;
++ return 0;
++ }
++
++ switch (val) {
++ case 1:
++ cs43130->xtal_ibias = CS43130_XTAL_IBIAS_7_5UA;
++ break;
++ case 2:
++ cs43130->xtal_ibias = CS43130_XTAL_IBIAS_12_5UA;
++ break;
++ case 3:
++ cs43130->xtal_ibias = CS43130_XTAL_IBIAS_15UA;
++ break;
++ default:
++ dev_err(&i2c_client->dev,
++ "Invalid cirrus,xtal-ibias value: %d\n", val);
++ return -EINVAL;
++ }
++
++ cs43130->dc_meas = of_property_read_bool(np, "cirrus,dc-measure");
++ cs43130->ac_meas = of_property_read_bool(np, "cirrus,ac-measure");
++
++ if (of_property_read_u16_array(np, "cirrus,ac-freq", cs43130->ac_freq,
++ CS43130_AC_FREQ) < 0) {
++ for (i = 0; i < CS43130_AC_FREQ; i++)
++ cs43130->ac_freq[i] = cs43130_ac_freq[i];
++ }
++
++ if (of_property_read_u16_array(np, "cirrus,dc-threshold",
++ cs43130->dc_threshold,
++ CS43130_DC_THRESHOLD) < 0) {
++ for (i = 0; i < CS43130_DC_THRESHOLD; i++)
++ cs43130->dc_threshold[i] = cs43130_dc_threshold[i];
++ }
++
++ return 0;
++}
++
++
++static int allo_cs43130_component_probe(struct i2c_client *i2c,
++ const struct i2c_device_id *id)
++{
++ struct regmap *regmap;
++ struct regmap_config config = cs43130_regmap;
++ struct device *dev = &i2c->dev;
++ struct cs43130_priv *cs43130;
++ unsigned int devid = 0;
++ unsigned int reg;
++ int ret;
++
++ regmap = devm_regmap_init_i2c(i2c, &config);
++ if (IS_ERR(regmap))
++ return PTR_ERR(regmap);
++
++ cs43130 = devm_kzalloc(dev, sizeof(struct cs43130_priv),
++ GFP_KERNEL);
++ if (!cs43130)
++ return -ENOMEM;
++
++ dev_set_drvdata(dev, cs43130);
++ cs43130->regmap = regmap;
++
++ if (i2c->dev.of_node) {
++ ret = cs43130_handle_device_data(i2c, cs43130);
++ if (ret != 0)
++ return ret;
++ }
++ usleep_range(2000, 2050);
++
++ ret = regmap_read(cs43130->regmap, CS43130_DEVID_AB, &reg);
++ devid = (reg & 0xFF) << 12;
++ ret = regmap_read(cs43130->regmap, CS43130_DEVID_CD, &reg);
++ devid |= (reg & 0xFF) << 4;
++ ret = regmap_read(cs43130->regmap, CS43130_DEVID_E, &reg);
++ devid |= (reg & 0xF0) >> 4;
++ if (devid != CS43198_CHIP_ID) {
++ dev_err(dev, "Failed to read Chip or wrong Chip id: %d\n", ret);
++ return ret;
++ }
++
++ cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO;
++ msleep(20);
++
++ ret = snd_soc_register_component(dev, &cs43130_component_driver,
++ &cs43130_codec_dai, 1);
++ if (ret != 0) {
++ dev_err(dev, "failed to register codec: %d\n", ret);
++ return ret;
++ }
++ regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG,
++ CS43130_ASP_3ST_MASK, 0);
++ regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG,
++ CS43130_XSP_3ST_MASK, 1);
++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
++ CS43130_PDN_HP_MASK, 1 << CS43130_PDN_HP_SHIFT);
++ msleep(20);
++ regmap_write(cs43130->regmap, CS43130_CLASS_H_CTL, 0x06);
++ snd_allo_clk44gpio = devm_gpiod_get(dev, "clock44", GPIOD_OUT_HIGH);
++ if (IS_ERR(snd_allo_clk44gpio))
++ dev_err(dev, "devm_gpiod_get() failed\n");
++
++ snd_allo_clk48gpio = devm_gpiod_get(dev, "clock48", GPIOD_OUT_LOW);
++ if (IS_ERR(snd_allo_clk48gpio))
++ dev_err(dev, "devm_gpiod_get() failed\n");
++
++ return 0;
++}
++
++static int allo_cs43130_component_remove(struct i2c_client *i2c)
++{
++ snd_soc_unregister_component(&i2c->dev);
++ return 0;
++}
++
++static const struct i2c_device_id allo_cs43130_component_id[] = {
++ { "allo-cs43198", },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, allo_cs43130_component_id);
++
++static const struct of_device_id allo_cs43130_codec_of_match[] = {
++ { .compatible = "allo,allo-cs43198", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, allo_cs43130_codec_of_match);
++
++static struct i2c_driver allo_cs43130_component_driver = {
++ .probe = allo_cs43130_component_probe,
++ .remove = allo_cs43130_component_remove,
++ .id_table = allo_cs43130_component_id,
++ .driver = {
++ .name = "allo-cs43198",
++ .of_match_table = allo_cs43130_codec_of_match,
++ },
++};
++
++module_i2c_driver(allo_cs43130_component_driver);
++
++MODULE_DESCRIPTION("ASoC Allo Boss2 Codec Driver");
++MODULE_AUTHOR("Sudeepkumar <sudeepkumar@cem-solutions.net>");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/bcm27xx/patches-5.4/950-1013-Add-allo-boss2-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-1013-Add-allo-boss2-overlay.patch
new file mode 100644
index 0000000000..97bc4a5757
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1013-Add-allo-boss2-overlay.patch
@@ -0,0 +1,98 @@
+From b07f4bea8e3259c30fa905b047dce73449147f58 Mon Sep 17 00:00:00 2001
+From: Sudeep <sudeepkumar@cem-solutions.net>
+Date: Fri, 23 Oct 2020 15:51:15 +0530
+Subject: [PATCH] Add allo boss2 overlay
+
+Signed-off-by: Sudeep <sudeepkumar@cem-solutions.net>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 6 ++
+ .../overlays/allo-boss2-dac-audio-overlay.dts | 57 +++++++++++++++++++
+ 3 files changed, 64 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/allo-boss2-dac-audio-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -14,6 +14,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ adv728x-m.dtbo \
+ akkordion-iqdacplus.dtbo \
+ allo-boss-dac-pcm512x-audio.dtbo \
++ allo-boss2-dac-audio.dtbo \
+ allo-digione.dtbo \
+ allo-katana-dac-audio.dtbo \
+ allo-piano-dac-pcm512x-audio.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -420,6 +420,12 @@ Params: 24db_digital_gain Allow ga
+ slave"
+
+
++Name: allo-boss2-dac-audio
++Info: Configures the Allo Boss2 DAC audio card
++Load: dtoverlay=allo-boss2-dac-audio
++Params: <None>
++
++
+ Name: allo-digione
+ Info: Configures the Allo Digione audio card
+ Load: dtoverlay=allo-digione
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/allo-boss2-dac-audio-overlay.dts
+@@ -0,0 +1,57 @@
++/* * Definitions for Allo Boss2 DAC boards
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2835";
++
++ 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-cs43130@30 {
++ #sound-dai-cells = <0>;
++ compatible = "allo,allo-cs43198";
++ clock44-gpio = <&gpio 5 0>;
++ clock48-gpio = <&gpio 6 0>;
++ reg = <0x30>;
++ port {
++ codec_endpoint: endpoint {
++ remote-endpoint = <&cpu_endpoint>;
++ };
++ };
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&sound>;
++ boss2_dac: __overlay__ {
++ compatible = "audio-graph-card";
++ label = "Allo Boss2";
++ dais = <&cpu_port>;
++ status = "okay";
++ };
++ };
++};
++
diff --git a/target/linux/bcm27xx/patches-5.4/950-1014-Revert-mailbox-avoid-timer-start-from-callback.patch b/target/linux/bcm27xx/patches-5.4/950-1014-Revert-mailbox-avoid-timer-start-from-callback.patch
new file mode 100644
index 0000000000..849bdd192e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1014-Revert-mailbox-avoid-timer-start-from-callback.patch
@@ -0,0 +1,60 @@
+From 2b7fcd18b15d9cc7b2e68deb77f4e0acfa904c41 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 3 Nov 2020 10:13:48 +0000
+Subject: [PATCH] Revert "mailbox: avoid timer start from callback"
+
+This reverts commit 6dc15642c8b830d384fd3e6c9ea63144202b8932.
+
+The Pi 400 shutdown/poweroff mechanism relies on being able to set
+a GPIO on the expander in the pm_power_off handler, something that
+requires two mailbox calls - GET_GPIO_STATE and SET_GPIO_STATE. A
+recent kernel change introduces a reasonable possibility that the
+GET call doesn't completes, and bisecting led to a commit from
+October that changes the timer usage of the mailbox.
+
+My theory is that there is a race condition in the new code that breaks
+the poll timer, but that it normally goes unnoticed because subsequent
+mailbox activity wakes it up again. The power-off mailbox calls happen
+at a time when other subsystems have been shut down, so if one of them
+fails then there is nothing to allow it to recover.
+
+Revert 6dc15642 as (at least) a workaround.
+
+See: https://github.com/raspberrypi/linux/issues/3941
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/mailbox/mailbox.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+--- a/drivers/mailbox/mailbox.c
++++ b/drivers/mailbox/mailbox.c
+@@ -82,12 +82,9 @@ static void msg_submit(struct mbox_chan
+ exit:
+ spin_unlock_irqrestore(&chan->lock, flags);
+
+- /* kick start the timer immediately to avoid delays */
+- if (!err && (chan->txdone_method & TXDONE_BY_POLL)) {
+- /* but only if not already active */
+- if (!hrtimer_active(&chan->mbox->poll_hrt))
+- hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL);
+- }
++ if (!err && (chan->txdone_method & TXDONE_BY_POLL))
++ /* kick start the timer immediately to avoid delays */
++ hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL);
+ }
+
+ static void tx_tick(struct mbox_chan *chan, int r)
+@@ -125,10 +122,11 @@ static enum hrtimer_restart txdone_hrtim
+ struct mbox_chan *chan = &mbox->chans[i];
+
+ if (chan->active_req && chan->cl) {
+- resched = true;
+ txdone = chan->mbox->ops->last_tx_done(chan);
+ if (txdone)
+ tx_tick(chan, 0);
++ else
++ resched = true;
+ }
+ }
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-1015-ARM-dts-Add-bcm2711-rpi-400.dts.patch b/target/linux/bcm27xx/patches-5.4/950-1015-ARM-dts-Add-bcm2711-rpi-400.dts.patch
new file mode 100644
index 0000000000..444c7ae3bb
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1015-ARM-dts-Add-bcm2711-rpi-400.dts.patch
@@ -0,0 +1,627 @@
+From 37034aa6ba14c346f67e8b99a317c45e40f0a2eb Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 14 Jul 2020 14:21:33 +0100
+Subject: [PATCH] ARM: dts: Add bcm2711-rpi-400.dts
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/Makefile | 1 +
+ arch/arm/boot/dts/bcm2711-rpi-400.dts | 585 ++++++++++++++++++
+ arch/arm64/boot/dts/broadcom/Makefile | 1 +
+ .../boot/dts/broadcom/bcm2711-rpi-400.dts | 1 +
+ 4 files changed, 588 insertions(+)
+ create mode 100644 arch/arm/boot/dts/bcm2711-rpi-400.dts
+ create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-400.dts
+
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -12,6 +12,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
+ bcm2710-rpi-3-b.dtb \
+ bcm2710-rpi-3-b-plus.dtb \
+ bcm2711-rpi-4-b.dtb \
++ bcm2711-rpi-400.dtb \
+ bcm2710-rpi-cm3.dtb \
+ bcm2711-rpi-cm4.dtb
+
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm2711-rpi-400.dts
+@@ -0,0 +1,585 @@
++// SPDX-License-Identifier: GPL-2.0
++/dts-v1/;
++#include "bcm2711.dtsi"
++#include "bcm2835-rpi.dtsi"
++
++/ {
++ compatible = "raspberrypi,400", "brcm,bcm2711";
++ model = "Raspberry Pi 400";
++
++ chosen {
++ /* 8250 auxiliary UART instead of pl011 */
++ stdout-path = "serial1:115200n8";
++ };
++
++ /* Will be filled by the bootloader */
++ memory@0 {
++ device_type = "memory";
++ reg = <0 0 0>;
++ };
++
++ aliases {
++ emmc2bus = &emmc2bus;
++ ethernet0 = &genet;
++ pcie0 = &pcie0;
++ };
++
++ leds {
++ act {
++ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
++ };
++
++ pwr {
++ label = "PWR";
++ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
++ default-state = "keep";
++ linux,default-trigger = "default-on";
++ };
++ };
++
++ wifi_pwrseq: wifi-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
++ };
++
++ sd_io_1v8_reg: sd_io_1v8_reg {
++ compatible = "regulator-gpio";
++ regulator-name = "vdd-sd-io";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ regulator-settling-time-us = <5000>;
++ gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>;
++ states = <1800000 0x1
++ 3300000 0x0>;
++ status = "okay";
++ };
++};
++
++&firmware {
++ expgpio: gpio {
++ compatible = "raspberrypi,firmware-gpio";
++ gpio-controller;
++ #gpio-cells = <2>;
++ gpio-line-names = "BT_ON",
++ "WL_ON",
++ "PWR_LED_OFF",
++ "GLOBAL_RESET",
++ "VDD_SD_IO_SEL",
++ "CAM_GPIO",
++ "SD_PWR_ON",
++ "SD_OC_N";
++ status = "okay";
++ };
++};
++
++&gpio {
++ /*
++ * Parts taken from rpi_SCH_4b_4p0_reduced.pdf and
++ * the official GPU firmware DT blob.
++ *
++ * Legend:
++ * "FOO" = GPIO line named "FOO" on the schematic
++ * "FOO_N" = GPIO line named "FOO" on schematic, active low
++ */
++ gpio-line-names = "ID_SDA",
++ "ID_SCL",
++ "SDA1",
++ "SCL1",
++ "GPIO_GCLK",
++ "GPIO5",
++ "GPIO6",
++ "SPI_CE1_N",
++ "SPI_CE0_N",
++ "SPI_MISO",
++ "SPI_MOSI",
++ "SPI_SCLK",
++ "GPIO12",
++ "GPIO13",
++ /* Serial port */
++ "TXD1",
++ "RXD1",
++ "GPIO16",
++ "GPIO17",
++ "GPIO18",
++ "GPIO19",
++ "GPIO20",
++ "GPIO21",
++ "GPIO22",
++ "GPIO23",
++ "GPIO24",
++ "GPIO25",
++ "GPIO26",
++ "GPIO27",
++ "RGMII_MDIO",
++ "RGMIO_MDC",
++ /* Used by BT module */
++ "CTS0",
++ "RTS0",
++ "TXD0",
++ "RXD0",
++ /* Used by Wifi */
++ "SD1_CLK",
++ "SD1_CMD",
++ "SD1_DATA0",
++ "SD1_DATA1",
++ "SD1_DATA2",
++ "SD1_DATA3",
++ /* Shared with SPI flash */
++ "PWM0_MISO",
++ "PWM1_MOSI",
++ "STATUS_LED_G_CLK",
++ "SPIFLASH_CE_N",
++ "SDA0",
++ "SCL0",
++ "RGMII_RXCLK",
++ "RGMII_RXCTL",
++ "RGMII_RXD0",
++ "RGMII_RXD1",
++ "RGMII_RXD2",
++ "RGMII_RXD3",
++ "RGMII_TXCLK",
++ "RGMII_TXCTL",
++ "RGMII_TXD0",
++ "RGMII_TXD1",
++ "RGMII_TXD2",
++ "RGMII_TXD3";
++};
++
++&pwm1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm1_0_gpio40 &pwm1_1_gpio41>;
++ status = "okay";
++};
++
++/* SDHCI is used to control the SDIO for wireless */
++&sdhci {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&emmc_gpio34>;
++ bus-width = <4>;
++ non-removable;
++ mmc-pwrseq = <&wifi_pwrseq>;
++ status = "okay";
++
++ brcmf: wifi@1 {
++ reg = <1>;
++ compatible = "brcm,bcm4329-fmac";
++ };
++};
++
++/* EMMC2 is used to drive the SD card */
++&emmc2 {
++ vqmmc-supply = <&sd_io_1v8_reg>;
++ broken-cd;
++ status = "okay";
++};
++
++&genet {
++ phy-handle = <&phy1>;
++ phy-mode = "rgmii-rxid";
++ status = "okay";
++};
++
++&genet_mdio {
++ phy1: ethernet-phy@1 {
++ /* No PHY interrupt */
++ reg = <0x1>;
++ };
++};
++
++/* uart0 communicates with the BT module */
++&uart0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32>;
++ uart-has-rtscts;
++ status = "okay";
++
++ bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ max-speed = <2000000>;
++ shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
++ };
++};
++
++/* uart1 is mapped to the pin header */
++&uart1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart1_gpio14>;
++ status = "okay";
++};
++
++&vchiq {
++ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
++};
++
++// =============================================
++// Downstream rpi- changes
++
++#include "bcm270x.dtsi"
++#include "bcm271x-rpi-bt.dtsi"
++
++/ {
++ soc {
++ /delete-node/ pixelvalve@7e807000;
++ /delete-node/ hdmi@7e902000;
++ };
++};
++
++#include "bcm2711-rpi.dtsi"
++#include "bcm283x-rpi-csi1-2lane.dtsi"
++#include "bcm283x-rpi-i2c0mux_0_44.dtsi"
++
++/ {
++ chosen {
++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1";
++ };
++
++ aliases {
++ serial0 = &uart1;
++ serial1 = &uart0;
++ mmc0 = &emmc2;
++ mmc1 = &mmcnr;
++ mmc2 = &sdhost;
++ /delete-property/ i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ /delete-property/ intc;
++ };
++
++ /delete-node/ wifi-pwrseq;
++};
++
++&mmcnr {
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdio_pins>;
++ bus-width = <4>;
++ status = "okay";
++};
++
++&uart0 {
++ pinctrl-0 = <&uart0_pins &bt_pins>;
++ status = "okay";
++};
++
++&uart1 {
++ pinctrl-0 = <&uart1_pins>;
++};
++
++&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>;
++ };
++};
++
++&gpio {
++ spi0_pins: spi0_pins {
++ brcm,pins = <9 10 11>;
++ brcm,function = <BCM2835_FSEL_ALT0>;
++ };
++
++ spi0_cs_pins: spi0_cs_pins {
++ brcm,pins = <8 7>;
++ brcm,function = <BCM2835_FSEL_GPIO_OUT>;
++ };
++
++ spi3_pins: spi3_pins {
++ brcm,pins = <1 2 3>;
++ brcm,function = <BCM2835_FSEL_ALT3>;
++ };
++
++ spi3_cs_pins: spi3_cs_pins {
++ brcm,pins = <0 24>;
++ brcm,function = <BCM2835_FSEL_GPIO_OUT>;
++ };
++
++ spi4_pins: spi4_pins {
++ brcm,pins = <5 6 7>;
++ brcm,function = <BCM2835_FSEL_ALT3>;
++ };
++
++ spi4_cs_pins: spi4_cs_pins {
++ brcm,pins = <4 25>;
++ brcm,function = <BCM2835_FSEL_GPIO_OUT>;
++ };
++
++ spi5_pins: spi5_pins {
++ brcm,pins = <13 14 15>;
++ brcm,function = <BCM2835_FSEL_ALT3>;
++ };
++
++ spi5_cs_pins: spi5_cs_pins {
++ brcm,pins = <12 26>;
++ brcm,function = <BCM2835_FSEL_GPIO_OUT>;
++ };
++
++ spi6_pins: spi6_pins {
++ brcm,pins = <19 20 21>;
++ brcm,function = <BCM2835_FSEL_ALT3>;
++ };
++
++ spi6_cs_pins: spi6_cs_pins {
++ brcm,pins = <18 27>;
++ brcm,function = <BCM2835_FSEL_GPIO_OUT>;
++ };
++
++ i2c0_pins: i2c0 {
++ brcm,pins = <0 1>;
++ brcm,function = <BCM2835_FSEL_ALT0>;
++ brcm,pull = <BCM2835_PUD_UP>;
++ };
++
++ i2c1_pins: i2c1 {
++ brcm,pins = <2 3>;
++ brcm,function = <BCM2835_FSEL_ALT0>;
++ brcm,pull = <BCM2835_PUD_UP>;
++ };
++
++ i2c3_pins: i2c3 {
++ brcm,pins = <4 5>;
++ brcm,function = <BCM2835_FSEL_ALT5>;
++ brcm,pull = <BCM2835_PUD_UP>;
++ };
++
++ i2c4_pins: i2c4 {
++ brcm,pins = <8 9>;
++ brcm,function = <BCM2835_FSEL_ALT5>;
++ brcm,pull = <BCM2835_PUD_UP>;
++ };
++
++ i2c5_pins: i2c5 {
++ brcm,pins = <12 13>;
++ brcm,function = <BCM2835_FSEL_ALT5>;
++ brcm,pull = <BCM2835_PUD_UP>;
++ };
++
++ i2c6_pins: i2c6 {
++ brcm,pins = <22 23>;
++ brcm,function = <BCM2835_FSEL_ALT5>;
++ brcm,pull = <BCM2835_PUD_UP>;
++ };
++
++ i2s_pins: i2s {
++ brcm,pins = <18 19 20 21>;
++ brcm,function = <BCM2835_FSEL_ALT0>;
++ };
++
++ sdio_pins: sdio_pins {
++ brcm,pins = <34 35 36 37 38 39>;
++ brcm,function = <BCM2835_FSEL_ALT3>; // alt3 = SD1
++ brcm,pull = <0 2 2 2 2 2>;
++ };
++
++ bt_pins: bt_pins {
++ brcm,pins = "-"; // non-empty to keep btuart happy, //4 = 0
++ // to fool pinctrl
++ brcm,function = <0>;
++ brcm,pull = <2>;
++ };
++
++ uart0_pins: uart0_pins {
++ brcm,pins = <32 33>;
++ brcm,function = <BCM2835_FSEL_ALT3>;
++ brcm,pull = <0 2>;
++ };
++
++ uart1_pins: uart1_pins {
++ brcm,pins;
++ brcm,function;
++ brcm,pull;
++ };
++
++ uart2_pins: uart2_pins {
++ brcm,pins = <0 1>;
++ brcm,function = <BCM2835_FSEL_ALT4>;
++ brcm,pull = <0 2>;
++ };
++
++ uart3_pins: uart3_pins {
++ brcm,pins = <4 5>;
++ brcm,function = <BCM2835_FSEL_ALT4>;
++ brcm,pull = <0 2>;
++ };
++
++ uart4_pins: uart4_pins {
++ brcm,pins = <8 9>;
++ brcm,function = <BCM2835_FSEL_ALT4>;
++ brcm,pull = <0 2>;
++ };
++
++ uart5_pins: uart5_pins {
++ brcm,pins = <12 13>;
++ brcm,function = <BCM2835_FSEL_ALT4>;
++ brcm,pull = <0 2>;
++ };
++};
++
++&i2c0if {
++ clock-frequency = <100000>;
++};
++
++&i2c1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c1_pins>;
++ clock-frequency = <100000>;
++};
++
++&i2s {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s_pins>;
++};
++
++/ {
++ __overrides__ {
++ /delete-property/ i2c2_baudrate;
++ /delete-property/ i2c2_iknowwhatimdoing;
++ };
++};
++
++&firmwarekms {
++ compatible = "raspberrypi,rpi-firmware-kms-2711";
++};
++
++// =============================================
++// Board specific stuff here
++
++/ {
++ sd_vcc_reg: sd_vcc_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc-sd";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ enable-active-high;
++ gpio = <&expgpio 6 GPIO_ACTIVE_HIGH>;
++ };
++
++ power_ctrl: power_ctrl {
++ compatible = "gpio-poweroff";
++ gpios = <&expgpio 5 0>;
++ force;
++ };
++};
++
++&sdhost {
++ status = "disabled";
++};
++
++&emmc2 {
++ vmmc-supply = <&sd_vcc_reg>;
++};
++
++&phy1 {
++ led-modes = <0x00 0x08>; /* link/activity link */
++};
++
++&gpio {
++ audio_pins: audio_pins {
++ brcm,pins = <40 41>;
++ brcm,function = <4>;
++ };
++};
++
++&leds {
++ act_led: act {
++ label = "led0";
++ linux,default-trigger = "default-on";
++ default-state = "on";
++ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
++ };
++
++ pwr_led: pwr {
++ label = "led1";
++ linux,default-trigger = "default-on";
++ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&pwm1 {
++ status = "disabled";
++};
++
++&audio {
++ pinctrl-names = "default";
++ pinctrl-0 = <&audio_pins>;
++ brcm,disable-headphones = <1>;
++};
++
++&vc4 {
++ status = "disabled";
++};
++
++&pixelvalve0 {
++ status = "disabled";
++};
++
++&pixelvalve1 {
++ status = "disabled";
++};
++
++&pixelvalve2 {
++ status = "disabled";
++};
++
++&pixelvalve3 {
++ status = "disabled";
++};
++
++&pixelvalve4 {
++ status = "disabled";
++};
++
++&hdmi0 {
++ status = "disabled";
++};
++
++&ddc0 {
++ status = "disabled";
++};
++
++&hdmi1 {
++ status = "disabled";
++};
++
++&ddc1 {
++ status = "disabled";
++};
++
++/ {
++ __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";
++
++ eth_led0 = <&phy1>,"led-modes:0";
++ eth_led1 = <&phy1>,"led-modes:4";
++
++ sd_poll_once = <&emmc2>, "non-removable?";
++ spi_dma4 = <&spi0>, "dmas:0=", <&dma40>,
++ <&spi0>, "dmas:8=", <&dma40>;
++ };
++};
+--- a/arch/arm64/boot/dts/broadcom/Makefile
++++ b/arch/arm64/boot/dts/broadcom/Makefile
+@@ -7,6 +7,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rp
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b.dtb
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b-plus.dtb
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb
++dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-400.dtb
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-cm3.dtb
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-cm4.dtb
+
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2711-rpi-400.dts
+@@ -0,0 +1 @@
++#include "../../../../arm/boot/dts/bcm2711-rpi-400.dts"
diff --git a/target/linux/bcm27xx/patches-5.4/950-1016-overlays-Deprecate-and-delete-the-sdtweak-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-1016-overlays-Deprecate-and-delete-the-sdtweak-overlay.patch
new file mode 100644
index 0000000000..fb0107c24d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1016-overlays-Deprecate-and-delete-the-sdtweak-overlay.patch
@@ -0,0 +1,64 @@
+From 88358069ed07f16a0aab0764ed1337e540006e29 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 4 Nov 2020 11:25:02 +0000
+Subject: [PATCH] overlays: Deprecate and delete the sdtweak overlay
+
+The sdtweak overlay has been superseded by the board-specific
+sd_* parameters such as sd_poll_once, sd_overclock etc.
+
+For example, replace:
+
+ dtoverlay=sdtweak,poll_once
+
+with:
+
+ dtparam=sd_poll_once
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/overlay_map.dts | 4 +++
+ .../arm/boot/dts/overlays/sdtweak-overlay.dts | 25 -------------------
+ 2 files changed, 4 insertions(+), 25 deletions(-)
+ delete mode 100644 arch/arm/boot/dts/overlays/sdtweak-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/overlay_map.dts
++++ b/arch/arm/boot/dts/overlays/overlay_map.dts
+@@ -61,6 +61,10 @@
+ deprecated = "use sdio,bus_width=1,gpios_22_25";
+ };
+
++ sdtweak {
++ deprecated = "use 'dtparam=sd_poll_once' etc.";
++ };
++
+ spi0-cs {
+ renamed = "spi0-2cs";
+ };
+--- a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts
++++ /dev/null
+@@ -1,25 +0,0 @@
+-/dts-v1/;
+-/plugin/;
+-
+-/* Provide backwards compatible aliases for the old sdhost dtparams. */
+-
+-/{
+- compatible = "brcm,bcm2835";
+-
+- 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 --git a/target/linux/bcm27xx/patches-5.4/950-1017-overlays-Complete-the-sdtweak-excision.patch b/target/linux/bcm27xx/patches-5.4/950-1017-overlays-Complete-the-sdtweak-excision.patch
new file mode 100644
index 0000000000..dc63f39dd7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1017-overlays-Complete-the-sdtweak-excision.patch
@@ -0,0 +1,57 @@
+From 572fe7f4e008792e3f14822d5ddddb37c86329fe Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 5 Nov 2020 09:54:33 +0000
+Subject: [PATCH] overlays: Complete the sdtweak excision
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 -
+ arch/arm/boot/dts/overlays/README | 27 ++++-----------------------
+ 2 files changed, 4 insertions(+), 24 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -159,7 +159,6 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ sc16is752-spi1.dtbo \
+ sdhost.dtbo \
+ sdio.dtbo \
+- sdtweak.dtbo \
+ sh1106-spi.dtbo \
+ smi.dtbo \
+ smi-dev.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -2407,29 +2407,10 @@ Load: <Deprecated>
+
+
+ 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,<param>=<val>
+-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)
++Info: This overlay is now deprecated. Use the sd_* dtparams in the
++ base DTB, e.g. "dtoverlay=sdtweak,poll_once" becomes
++ "dtparam=sd_poll_once".
++Load: <Deprecated>
+
+
+ Name: sh1106-spi
diff --git a/target/linux/bcm27xx/patches-5.4/950-1018-ARM-dts-bcm27xx-Remove-enable_headphones-setting.patch b/target/linux/bcm27xx/patches-5.4/950-1018-ARM-dts-bcm27xx-Remove-enable_headphones-setting.patch
new file mode 100644
index 0000000000..f3db1905c2
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1018-ARM-dts-bcm27xx-Remove-enable_headphones-setting.patch
@@ -0,0 +1,110 @@
+From f1d85a62da9a69fba1438e64b4fcc785abb6c957 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 5 Nov 2020 11:39:35 +0000
+Subject: [PATCH] ARM: dts: bcm27xx: Remove enable_headphones setting
+
+The enable_headphones parameter of the snd_bcm2835 module is forced
+to 1 if enable_compat_alsa is 0, so setting them both on the kernel
+command line is pointless (and, in the case of Pi 400 and Pi Zeroes,
+confusing).
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 2 +-
+ arch/arm/boot/dts/bcm2708-rpi-zero.dts | 2 +-
+ arch/arm/boot/dts/bcm270x.dtsi | 2 +-
+ arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 2 +-
+ arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 2 +-
+ arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 2 +-
+ arch/arm/boot/dts/bcm2711-rpi-400.dts | 2 +-
+ arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 2 +-
+ 8 files changed, 8 insertions(+), 8 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts
+@@ -11,7 +11,7 @@
+ model = "Raspberry Pi Zero W";
+
+ chosen {
+- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1";
++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1";
+ };
+
+ aliases {
+--- a/arch/arm/boot/dts/bcm2708-rpi-zero.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts
+@@ -10,7 +10,7 @@
+ model = "Raspberry Pi Zero";
+
+ chosen {
+- bootargs = "coherent_pool=1M snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1";
++ bootargs = "coherent_pool=1M snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1";
+ };
+ };
+
+--- a/arch/arm/boot/dts/bcm270x.dtsi
++++ b/arch/arm/boot/dts/bcm270x.dtsi
+@@ -3,7 +3,7 @@
+
+ / {
+ chosen {
+- bootargs = "coherent_pool=1M snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1";
++ bootargs = "coherent_pool=1M snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1";
+ /delete-property/ stdout-path;
+ };
+
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts
+@@ -12,7 +12,7 @@
+ model = "Raspberry Pi 3 Model B+";
+
+ chosen {
+- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1";
++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1";
+ };
+
+ aliases {
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
+@@ -12,7 +12,7 @@
+ model = "Raspberry Pi 3 Model B";
+
+ chosen {
+- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1";
++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1";
+ };
+
+ aliases {
+--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+@@ -234,7 +234,7 @@
+
+ / {
+ chosen {
+- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1";
++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1";
+ };
+
+ aliases {
+--- a/arch/arm/boot/dts/bcm2711-rpi-400.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-400.dts
+@@ -234,7 +234,7 @@
+
+ / {
+ chosen {
+- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1";
++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1";
+ };
+
+ aliases {
+--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
+@@ -174,7 +174,7 @@
+
+ / {
+ chosen {
+- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1";
++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1";
+ };
+
+ aliases {
diff --git a/target/linux/bcm27xx/patches-5.4/950-1019-staging-vcsm-cma-Fix-memory-leak-from-not-detaching-.patch b/target/linux/bcm27xx/patches-5.4/950-1019-staging-vcsm-cma-Fix-memory-leak-from-not-detaching-.patch
new file mode 100644
index 0000000000..992adc67fb
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1019-staging-vcsm-cma-Fix-memory-leak-from-not-detaching-.patch
@@ -0,0 +1,77 @@
+From 6ff310748f67d98d1c2c8ea75decd9dee13aa50c Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 4 Nov 2020 18:54:20 +0000
+Subject: [PATCH] staging: vcsm-cma: Fix memory leak from not
+ detaching dmabuf
+
+When importing there was a missing call to detach the buffer,
+so each import leaked the sg table entry.
+
+Actually the release process for both locally allocated and
+imported buffers is identical, so fix them to both use the same
+function.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../staging/vc04_services/vc-sm-cma/vc_sm.c | 22 ++-----------------
+ 1 file changed, 2 insertions(+), 20 deletions(-)
+
+--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c
++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c
+@@ -237,6 +237,7 @@ static void vc_sm_add_resource(struct vc
+
+ /*
+ * Cleans up imported dmabuf.
++ * Should be called with mutex held.
+ */
+ static void vc_sm_clean_up_dmabuf(struct vc_sm_buffer *buffer)
+ {
+@@ -244,7 +245,6 @@ static void vc_sm_clean_up_dmabuf(struct
+ return;
+
+ /* Handle cleaning up imported dmabufs */
+- mutex_lock(&buffer->lock);
+ if (buffer->import.sgt) {
+ dma_buf_unmap_attachment(buffer->import.attach,
+ buffer->import.sgt,
+@@ -255,7 +255,6 @@ static void vc_sm_clean_up_dmabuf(struct
+ dma_buf_detach(buffer->dma_buf, buffer->import.attach);
+ buffer->import.attach = NULL;
+ }
+- mutex_unlock(&buffer->lock);
+ }
+
+ /*
+@@ -687,23 +686,6 @@ int vc_sm_import_dmabuf_mmap(struct dma_
+ }
+
+ static
+-void vc_sm_import_dma_buf_release(struct dma_buf *dmabuf)
+-{
+- struct vc_sm_buffer *buf = dmabuf->priv;
+-
+- pr_debug("%s: Relasing dma_buf %p\n", __func__, dmabuf);
+- mutex_lock(&buf->lock);
+- if (!buf->imported)
+- return;
+-
+- buf->in_use = 0;
+-
+- vc_sm_vpu_free(buf);
+-
+- vc_sm_release_resource(buf);
+-}
+-
+-static
+ void *vc_sm_import_dma_buf_kmap(struct dma_buf *dmabuf,
+ unsigned long offset)
+ {
+@@ -753,7 +735,7 @@ static const struct dma_buf_ops dma_buf_
+ .map_dma_buf = vc_sm_import_map_dma_buf,
+ .unmap_dma_buf = vc_sm_import_unmap_dma_buf,
+ .mmap = vc_sm_import_dmabuf_mmap,
+- .release = vc_sm_import_dma_buf_release,
++ .release = vc_sm_dma_buf_release,
+ .attach = vc_sm_import_dma_buf_attach,
+ .detach = vc_sm_import_dma_buf_detatch,
+ .begin_cpu_access = vc_sm_import_dma_buf_begin_cpu_access,
diff --git a/target/linux/bcm27xx/patches-5.4/950-1020-Update-Allo-Piano-Dac-Driver-for-5.4.y-kernels.patch b/target/linux/bcm27xx/patches-5.4/950-1020-Update-Allo-Piano-Dac-Driver-for-5.4.y-kernels.patch
new file mode 100644
index 0000000000..00d319e291
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1020-Update-Allo-Piano-Dac-Driver-for-5.4.y-kernels.patch
@@ -0,0 +1,246 @@
+From 7f7ea09cdfa44c447c31db4884c1bb958d27f10a Mon Sep 17 00:00:00 2001
+From: paul-1 <6473457+paul-1@users.noreply.github.com>
+Date: Wed, 4 Nov 2020 19:11:37 -0500
+Subject: [PATCH] Update Allo Piano Dac Driver for 5.4.y kernels
+
+Add unique names to the individual dac coded drivers
+Remove some of the codec controls that are not used.
+
+Signed-off-by: Paul Hermann <paul@picoreplayer.org>
+---
+ sound/soc/bcm/allo-piano-dac-plus.c | 129 +++++++++++++++++++++-------
+ 1 file changed, 97 insertions(+), 32 deletions(-)
+
+--- a/sound/soc/bcm/allo-piano-dac-plus.c
++++ b/sound/soc/bcm/allo-piano-dac-plus.c
+@@ -2,7 +2,8 @@
+ * ALSA ASoC Machine Driver for Allo Piano DAC Plus Subwoofer
+ *
+ * Author: Baswaraj K <jaikumar@cem-solutions.net>
+- * Copyright 2016
++ * Copyright 2020
++ * based on code by David Knell <david.knell@gmail.com)
+ * based on code by Daniel Matuschek <info@crazy-audio.com>
+ * based on code by Florian Meier <florian.meier@koalo.de>
+ *
+@@ -276,8 +277,15 @@ static int snd_allo_piano_dual_mode_put(
+ PCM512x_DIGITAL_VOLUME_2, 0xff);
+
+ list_for_each_entry(kctl, &snd_card_ptr->controls, list) {
+- if (!strncmp(kctl->id.name, "Digital Playback Volume",
+- sizeof(kctl->id.name))) {
++ if (!strncmp(kctl->id.name, "Main Digital Playback Volume",
++ sizeof(kctl->id.name))) {
++ mc = (struct soc_mixer_control *)
++ kctl->private_value;
++ mc->rreg = mc->reg;
++ break;
++ }
++ if (!strncmp(kctl->id.name, "Sub Digital Playback Volume",
++ sizeof(kctl->id.name))) {
+ mc = (struct soc_mixer_control *)
+ kctl->private_value;
+ mc->rreg = mc->reg;
+@@ -291,13 +299,20 @@ static int snd_allo_piano_dual_mode_put(
+ PCM512x_DIGITAL_VOLUME_3, &right_val);
+
+ list_for_each_entry(kctl, &snd_card_ptr->controls, list) {
+- if (!strncmp(kctl->id.name, "Digital Playback Volume",
+- sizeof(kctl->id.name))) {
++ if (!strncmp(kctl->id.name, "Main Digital Playback Volume",
++ sizeof(kctl->id.name))) {
+ mc = (struct soc_mixer_control *)
+ kctl->private_value;
+ mc->rreg = PCM512x_DIGITAL_VOLUME_3;
+ break;
+ }
++ if (!strncmp(kctl->id.name, "Sub Digital Playback Volume",
++ sizeof(kctl->id.name))) {
++ mc = (struct soc_mixer_control *)
++ kctl->private_value;
++ mc->rreg = PCM512x_DIGITAL_VOLUME_2;
++ break;
++ }
+ }
+
+ snd_soc_component_write(rtd->codec_dais[0]->component,
+@@ -344,13 +359,20 @@ static int snd_allo_piano_mode_put(struc
+ PCM512x_DIGITAL_VOLUME_2, &right_val);
+
+ list_for_each_entry(kctl, &snd_card_ptr->controls, list) {
+- if (!strncmp(kctl->id.name, "Digital Playback Volume",
+- sizeof(kctl->id.name))) {
++ if (!strncmp(kctl->id.name, "Main Digital Playback Volume",
++ sizeof(kctl->id.name))) {
+ mc = (struct soc_mixer_control *)
+ kctl->private_value;
+ mc->rreg = PCM512x_DIGITAL_VOLUME_3;
+ break;
+ }
++ if (!strncmp(kctl->id.name, "Sub Digital Playback Volume",
++ sizeof(kctl->id.name))) {
++ mc = (struct soc_mixer_control *)
++ kctl->private_value;
++ mc->rreg = PCM512x_DIGITAL_VOLUME_2;
++ break;
++ }
+ }
+ snd_soc_component_write(rtd->codec_dais[0]->component,
+ PCM512x_DIGITAL_VOLUME_3, left_val);
+@@ -434,12 +456,6 @@ static int pcm512x_set_reg_sub(struct sn
+ int ret = 0;
+
+ rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
+- if (glb_ptr->dual_mode != 1) {
+- ret = snd_soc_component_write(rtd->codec_dais[1]->component,
+- PCM512x_DIGITAL_VOLUME_2, (~left_val));
+- if (ret < 0)
+- return ret;
+- }
+
+ if (digital_gain_0db_limit) {
+ ret = snd_soc_limit_volume(card, "Subwoofer Playback Volume",
+@@ -449,6 +465,13 @@ static int pcm512x_set_reg_sub(struct sn
+ ret);
+ }
+
++ if (glb_ptr->dual_mode != 1) {
++ ret = snd_soc_component_write(rtd->codec_dais[1]->component,
++ PCM512x_DIGITAL_VOLUME_2, (~left_val));
++ if (ret < 0)
++ return ret;
++ }
++
+ ret = snd_soc_component_write(rtd->codec_dais[1]->component,
+ PCM512x_DIGITAL_VOLUME_3, (~right_val));
+ if (ret < 0)
+@@ -674,7 +697,7 @@ static const struct snd_kcontrol_new all
+
+ SOC_DOUBLE_R_EXT_TLV("Subwoofer Playback Volume",
+ PCM512x_DIGITAL_VOLUME_2,
+- PCM512x_DIGITAL_VOLUME_3, 0, 255, 1,
++ PCM512x_DIGITAL_VOLUME_3, 0, 207, 1,
+ pcm512x_get_reg_sub,
+ pcm512x_set_reg_sub,
+ digital_tlv_sub),
+@@ -688,7 +711,7 @@ static const struct snd_kcontrol_new all
+
+ SOC_DOUBLE_R_EXT_TLV("Master Playback Volume",
+ PCM512x_DIGITAL_VOLUME_2,
+- PCM512x_DIGITAL_VOLUME_3, 0, 255, 1,
++ PCM512x_DIGITAL_VOLUME_3, 0, 207, 1,
+ pcm512x_get_reg_master,
+ pcm512x_set_reg_master,
+ digital_tlv_master),
+@@ -701,10 +724,28 @@ static const struct snd_kcontrol_new all
+ pcm512x_set_reg_master_switch),
+ };
+
++static const char * const codec_ctl_pfx[] = { "Main", "Sub" };
++static const char * const codec_ctl_name[] = {
++ "Digital Playback Volume",
++ "Digital Playback Switch",
++ "Auto Mute Mono Switch",
++ "Auto Mute Switch",
++ "Auto Mute Time Left",
++ "Auto Mute Time Right",
++ "Clock Missing Period",
++ "Max Overclock DAC",
++ "Max Overclock DSP",
++ "Max Overclock PLL",
++ "Volume Ramp Down Emergency Rate",
++ "Volume Ramp Down Emergency Step"
++};
++
+ static int snd_allo_piano_dac_init(struct snd_soc_pcm_runtime *rtd)
+ {
+ struct snd_soc_card *card = rtd->card;
+ struct glb_pool *glb_ptr;
++ struct snd_kcontrol *kctl;
++ int i, j;
+
+ glb_ptr = kzalloc(sizeof(struct glb_pool), GFP_KERNEL);
+ if (!glb_ptr)
+@@ -719,12 +760,37 @@ static int snd_allo_piano_dac_init(struc
+ if (digital_gain_0db_limit) {
+ int ret;
+
+- ret = snd_soc_limit_volume(card, "Digital Playback Volume",
+- 207);
+- if (ret < 0)
+- dev_warn(card->dev, "Failed to set volume limit: %d\n",
+- ret);
++ //Set volume limit on both dacs
++ for (i = 0; i < ARRAY_SIZE(codec_ctl_pfx); i++) {
++ char cname[256];
++
++ sprintf(cname, "%s %s", codec_ctl_pfx[i], codec_ctl_name[0]);
++ ret = snd_soc_limit_volume(card, cname, 207);
++ if (ret < 0)
++ dev_warn(card->dev, "Failed to set volume limit: %d\n",
++ ret);
++ }
++ }
++
++ // Remove codec controls
++ for (i = 0; i < ARRAY_SIZE(codec_ctl_pfx); i++) {
++ // Start at 1, leave the Digital Volume control.
++ for (j = 1; j < ARRAY_SIZE(codec_ctl_name); j++) {
++ char cname[256];
++
++ sprintf(cname, "%s %s", codec_ctl_pfx[i], codec_ctl_name[j]);
++ kctl = snd_soc_card_get_kcontrol(card, cname);
++ if (!kctl) {
++ dev_err(rtd->card->dev, "Control %s not found\n",
++ cname);
++ } else {
++ kctl->vd[0].access =
++ SNDRV_CTL_ELEM_ACCESS_READWRITE;
++ snd_ctl_remove(card->snd_card, kctl);
++ }
++ }
+ }
++
+ return 0;
+ }
+
+@@ -868,10 +934,10 @@ static struct snd_soc_dai_link_component
+ };
+
+ SND_SOC_DAILINK_DEFS(allo_piano_dai_plus,
+- DAILINK_COMP_ARRAY(COMP_CPU("bcm2708-i2s.0")),
+- DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "pcm512x-hifi"),
+- COMP_CODEC(NULL, "pcm512x-hifi")),
+- DAILINK_COMP_ARRAY(COMP_PLATFORM("bcm2708-i2s.0")));
++ DAILINK_COMP_ARRAY(COMP_EMPTY()),
++ DAILINK_COMP_ARRAY(COMP_CODEC("pcm512x.1-004c", "pcm512x-hifi"),
++ COMP_CODEC("pcm512x.1-004d", "pcm512x-hifi")),
++ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+ static struct snd_soc_dai_link snd_allo_piano_dac_dai[] = {
+ {
+@@ -964,17 +1030,16 @@ static int snd_allo_piano_dac_probe(stru
+ snd_allo_piano_dac.set_bias_level =
+ snd_allo_piano_set_bias_level;
+
+- ret = snd_soc_register_card(&snd_allo_piano_dac);
+- if (ret < 0) {
+- dev_err(&pdev->dev,
+- "snd_soc_register_card() failed: %d\n", ret);
+- return ret;
+- }
+-
+ if ((mute_gpio[0]) && (mute_gpio[1]))
+ snd_allo_piano_gpio_mute(&snd_allo_piano_dac);
+
+- return 0;
++ ret = devm_snd_soc_register_card(&pdev->dev, &snd_allo_piano_dac);
++
++ if (ret && ret != -EPROBE_DEFER)
++ dev_err(&pdev->dev,
++ "snd_soc_register_card() failed: %d\n", ret);
++ return ret;
++
+ }
+
+ return -EINVAL;
diff --git a/target/linux/bcm27xx/patches-5.4/950-1021-Overlay-Update-Allo-Piano-Plus-dac-driver-for-5.4.y-.patch b/target/linux/bcm27xx/patches-5.4/950-1021-Overlay-Update-Allo-Piano-Plus-dac-driver-for-5.4.y-.patch
new file mode 100644
index 0000000000..68b713d740
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1021-Overlay-Update-Allo-Piano-Plus-dac-driver-for-5.4.y-.patch
@@ -0,0 +1,30 @@
+From 244817626f3f3f5d0e5f6e2881f7046087a225ff Mon Sep 17 00:00:00 2001
+From: paul-1 <6473457+paul-1@users.noreply.github.com>
+Date: Wed, 4 Nov 2020 19:17:48 -0500
+Subject: [PATCH] Overlay: Update Allo Piano Plus dac driver for
+ 5.4.y kernels.
+
+Create unique names for the two instances of the codec driver.
+
+Signed-off-by: Paul Hermann <paul@picoreplayer.org>
+---
+ .../dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts
++++ b/arch/arm/boot/dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts
+@@ -23,12 +23,14 @@
+ #sound-dai-cells = <0>;
+ compatible = "ti,pcm5122";
+ reg = <0x4c>;
++ sound-name-prefix = "Main";
+ status = "okay";
+ };
+ allo_pcm5122_4d: pcm5122@4d {
+ #sound-dai-cells = <0>;
+ compatible = "ti,pcm5122";
+ reg = <0x4d>;
++ sound-name-prefix = "Sub";
+ status = "okay";
+ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-1022-Update-volume-controls-in-Allo-Piano-Dac-Plus.patch b/target/linux/bcm27xx/patches-5.4/950-1022-Update-volume-controls-in-Allo-Piano-Dac-Plus.patch
new file mode 100644
index 0000000000..ab5448a6ba
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1022-Update-volume-controls-in-Allo-Piano-Dac-Plus.patch
@@ -0,0 +1,141 @@
+From cc1a511f1a582e2fbf9fa1e257f6b88cbcc2e0d9 Mon Sep 17 00:00:00 2001
+From: paul-1 <6473457+paul-1@users.noreply.github.com>
+Date: Sat, 7 Nov 2020 12:01:44 -0500
+Subject: [PATCH] Update volume controls in Allo Piano Dac Plus
+
+Put control scaling back to 255.
+Clean up what master/sub volume controls set in codec.
+Remove more unneeded mixer controls.
+
+Signed-off-by: Paul Hermann <paul@picoreplayer.org>
+---
+ sound/soc/bcm/allo-piano-dac-plus.c | 56 +++++++++++++++++------------
+ 1 file changed, 33 insertions(+), 23 deletions(-)
+
+--- a/sound/soc/bcm/allo-piano-dac-plus.c
++++ b/sound/soc/bcm/allo-piano-dac-plus.c
+@@ -420,6 +420,7 @@ static int pcm512x_get_reg_sub(struct sn
+ unsigned int right_val = 0;
+ int ret;
+ rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
++
+ ret = snd_soc_component_read(rtd->codec_dais[1]->component,
+ PCM512x_DIGITAL_VOLUME_3, &right_val);
+ if (ret < 0)
+@@ -465,17 +466,20 @@ static int pcm512x_set_reg_sub(struct sn
+ ret);
+ }
+
+- if (glb_ptr->dual_mode != 1) {
++ // When in Dual Mono, Sub vol control should not set anything.
++ if (glb_ptr->dual_mode != 1) { //Not in Dual Mono mode
++
+ ret = snd_soc_component_write(rtd->codec_dais[1]->component,
+ PCM512x_DIGITAL_VOLUME_2, (~left_val));
+ if (ret < 0)
+ return ret;
+- }
+
+- ret = snd_soc_component_write(rtd->codec_dais[1]->component,
+- PCM512x_DIGITAL_VOLUME_3, (~right_val));
+- if (ret < 0)
+- return ret;
++ ret = snd_soc_component_write(rtd->codec_dais[1]->component,
++ PCM512x_DIGITAL_VOLUME_3, (~right_val));
++ if (ret < 0)
++ return ret;
++
++ }
+
+ return 1;
+ }
+@@ -540,7 +544,7 @@ static int pcm512x_get_reg_master(struct
+ if ( ret < 0)
+ return ret;
+
+- if (glb_ptr->dual_mode == 1) {
++ if (glb_ptr->dual_mode == 1) { // in Dual Mono mode
+ ret = snd_soc_component_read(rtd->codec_dais[1]->component,
+ PCM512x_DIGITAL_VOLUME_3, &right_val);
+ if (ret < 0)
+@@ -582,8 +586,21 @@ static int pcm512x_set_reg_master(struct
+ ret);
+ }
+
+- if (glb_ptr->dual_mode != 1) {
++ if (glb_ptr->dual_mode == 1) { //in Dual Mono Mode
++
++ ret = snd_soc_component_write(rtd->codec_dais[0]->component,
++ PCM512x_DIGITAL_VOLUME_2, (~left_val));
++ if (ret < 0)
++ return ret;
++
+ ret = snd_soc_component_write(rtd->codec_dais[1]->component,
++ PCM512x_DIGITAL_VOLUME_3, (~right_val));
++ if (ret < 0)
++ return ret;
++
++ } else {
++
++ ret = snd_soc_component_write(rtd->codec_dais[0]->component,
+ PCM512x_DIGITAL_VOLUME_2, (~left_val));
+ if (ret < 0)
+ return ret;
+@@ -594,16 +611,6 @@ static int pcm512x_set_reg_master(struct
+ return ret;
+
+ }
+-
+- ret = snd_soc_component_write(rtd->codec_dais[1]->component,
+- PCM512x_DIGITAL_VOLUME_3, (~right_val));
+- if (ret < 0)
+- return ret;
+-
+- ret = snd_soc_component_write(rtd->codec_dais[0]->component,
+- PCM512x_DIGITAL_VOLUME_2, (~left_val));
+- if (ret < 0)
+- return ret;
+ return 1;
+ }
+
+@@ -697,7 +704,7 @@ static const struct snd_kcontrol_new all
+
+ SOC_DOUBLE_R_EXT_TLV("Subwoofer Playback Volume",
+ PCM512x_DIGITAL_VOLUME_2,
+- PCM512x_DIGITAL_VOLUME_3, 0, 207, 1,
++ PCM512x_DIGITAL_VOLUME_3, 0, 255, 1,
+ pcm512x_get_reg_sub,
+ pcm512x_set_reg_sub,
+ digital_tlv_sub),
+@@ -711,7 +718,7 @@ static const struct snd_kcontrol_new all
+
+ SOC_DOUBLE_R_EXT_TLV("Master Playback Volume",
+ PCM512x_DIGITAL_VOLUME_2,
+- PCM512x_DIGITAL_VOLUME_3, 0, 207, 1,
++ PCM512x_DIGITAL_VOLUME_3, 0, 255, 1,
+ pcm512x_get_reg_master,
+ pcm512x_set_reg_master,
+ digital_tlv_master),
+@@ -737,7 +744,11 @@ static const char * const codec_ctl_name
+ "Max Overclock DSP",
+ "Max Overclock PLL",
+ "Volume Ramp Down Emergency Rate",
+- "Volume Ramp Down Emergency Step"
++ "Volume Ramp Down Emergency Step",
++ "Volume Ramp Up Rate",
++ "Volume Ramp Down Rate",
++ "Volume Ramp Up Step",
++ "Volume Ramp Down Step"
+ };
+
+ static int snd_allo_piano_dac_init(struct snd_soc_pcm_runtime *rtd)
+@@ -774,8 +785,7 @@ static int snd_allo_piano_dac_init(struc
+
+ // Remove codec controls
+ for (i = 0; i < ARRAY_SIZE(codec_ctl_pfx); i++) {
+- // Start at 1, leave the Digital Volume control.
+- for (j = 1; j < ARRAY_SIZE(codec_ctl_name); j++) {
++ for (j = 0; j < ARRAY_SIZE(codec_ctl_name); j++) {
+ char cname[256];
+
+ sprintf(cname, "%s %s", codec_ctl_pfx[i], codec_ctl_name[j]);
diff --git a/target/linux/bcm27xx/patches-5.4/950-1023-media-i2c-imx219-Selection-compliance-fixes.patch b/target/linux/bcm27xx/patches-5.4/950-1023-media-i2c-imx219-Selection-compliance-fixes.patch
new file mode 100644
index 0000000000..600e25ed26
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1023-media-i2c-imx219-Selection-compliance-fixes.patch
@@ -0,0 +1,80 @@
+From de47ea073936726d9a5ad843908fd3074c1fb8f0 Mon Sep 17 00:00:00 2001
+From: Hans Verkuil <hverkuil@xs4all.nl>
+Date: Wed, 5 Aug 2020 12:57:21 +0200
+Subject: [PATCH] media: i2c: imx219: Selection compliance fixes
+
+To comply with the intended usage of the V4L2 selection target when
+used to retrieve a sensor image properties, adjust the rectangles
+returned by the imx219 driver.
+
+The top/left crop coordinates of the TGT_CROP rectangle were set to
+(0, 0) instead of (8, 8) which is the offset from the larger physical
+pixel array rectangle. This was also a mismatch with the default values
+crop rectangle value, so this is corrected. Found with v4l2-compliance.
+
+While at it, add V4L2_SEL_TGT_CROP_BOUNDS support: CROP_DEFAULT and
+CROP_BOUNDS have the same size as the non-active pixels are not readable
+using the selection API. Found with v4l2-compliance.
+
+Fixes: e6d4ef7d58aa7 ("media: i2c: imx219: Implement get_selection")
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+[reword commit message, use macros for pixel offsets]
+Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
+---
+ drivers/media/i2c/imx219.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/drivers/media/i2c/imx219.c
++++ b/drivers/media/i2c/imx219.c
+@@ -485,8 +485,8 @@ static const struct imx219_mode supporte
+ .width = 3280,
+ .height = 2464,
+ .crop = {
+- .left = 0,
+- .top = 0,
++ .left = IMX219_PIXEL_ARRAY_LEFT,
++ .top = IMX219_PIXEL_ARRAY_TOP,
+ .width = 3280,
+ .height = 2464
+ },
+@@ -501,8 +501,8 @@ static const struct imx219_mode supporte
+ .width = 1920,
+ .height = 1080,
+ .crop = {
+- .left = 680,
+- .top = 692,
++ .left = 688,
++ .top = 700,
+ .width = 1920,
+ .height = 1080
+ },
+@@ -517,8 +517,8 @@ static const struct imx219_mode supporte
+ .width = 1640,
+ .height = 1232,
+ .crop = {
+- .left = 0,
+- .top = 0,
++ .left = IMX219_PIXEL_ARRAY_LEFT,
++ .top = IMX219_PIXEL_ARRAY_TOP,
+ .width = 3280,
+ .height = 2464
+ },
+@@ -533,8 +533,8 @@ static const struct imx219_mode supporte
+ .width = 640,
+ .height = 480,
+ .crop = {
+- .left = 1000,
+- .top = 752,
++ .left = 1008,
++ .top = 760,
+ .width = 1280,
+ .height = 960
+ },
+@@ -1093,6 +1093,7 @@ static int imx219_get_selection(struct v
+ return 0;
+
+ case V4L2_SEL_TGT_CROP_DEFAULT:
++ case V4L2_SEL_TGT_CROP_BOUNDS:
+ sel->r.top = IMX219_PIXEL_ARRAY_TOP;
+ sel->r.left = IMX219_PIXEL_ARRAY_LEFT;
+ sel->r.width = IMX219_PIXEL_ARRAY_WIDTH;
diff --git a/target/linux/bcm27xx/patches-5.4/950-1024-media-bcm2835-unicam-Correctly-handle-error-propagat.patch b/target/linux/bcm27xx/patches-5.4/950-1024-media-bcm2835-unicam-Correctly-handle-error-propagat.patch
new file mode 100644
index 0000000000..906e45b1bc
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1024-media-bcm2835-unicam-Correctly-handle-error-propagat.patch
@@ -0,0 +1,27 @@
+From 85dae0158c3ba741e2cb815879b4d5d55b3254d7 Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Wed, 2 Dec 2020 15:22:23 +0000
+Subject: [PATCH] media: bcm2835-unicam: Correctly handle error
+ propagation for stream on
+
+On a failure in start_streaming(), the error code would not propagate to
+the calling function on all conditions. This would cause the userland
+caller to not know of the failure.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ drivers/media/platform/bcm2835/bcm2835-unicam.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -1730,8 +1730,7 @@ err_disable_unicam:
+ unicam_disable(dev);
+ clk_disable_unprepare(dev->clock);
+ err_vpu_clock:
+- ret = clk_set_min_rate(dev->vpu_clock, 0);
+- if (ret)
++ if (clk_set_min_rate(dev->vpu_clock, 0))
+ unicam_err(dev, "failed to reset the VPU clock\n");
+ clk_disable_unprepare(dev->vpu_clock);
+ err_pm_put:
diff --git a/target/linux/bcm27xx/patches-5.4/950-1025-media-bcm2835-unicam-Return-early-from-stop_streamin.patch b/target/linux/bcm27xx/patches-5.4/950-1025-media-bcm2835-unicam-Return-early-from-stop_streamin.patch
new file mode 100644
index 0000000000..92c699a08b
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1025-media-bcm2835-unicam-Return-early-from-stop_streamin.patch
@@ -0,0 +1,64 @@
+From 1e888ff376c880b2803aecea3f69d28dc2ae4349 Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Wed, 2 Dec 2020 15:26:09 +0000
+Subject: [PATCH] media: bcm2835-unicam: Return early from
+ stop_streaming() if stopped
+
+clk_disable_unprepare() is called unconditionally in stop_streaming().
+This is incorrect in the cases where start_streaming() fails, and
+unprepares all clocks as part of the failure cleanup. To avoid this,
+ensure that clk_disable_unprepare() is only called in stop_streaming()
+if the clocks are in a prepared state.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ drivers/media/platform/bcm2835/bcm2835-unicam.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -426,6 +426,8 @@ struct unicam_device {
+ struct clk *clock;
+ /* vpu clock handle */
+ struct clk *vpu_clock;
++ /* clock status for error handling */
++ bool clocks_enabled;
+ /* V4l2 device */
+ struct v4l2_device v4l2_dev;
+ struct media_device mdev;
+@@ -1724,6 +1726,7 @@ static int unicam_start_streaming(struct
+ goto err_disable_unicam;
+ }
+
++ dev->clocks_enabled = true;
+ return 0;
+
+ err_disable_unicam:
+@@ -1750,8 +1753,6 @@ static void unicam_stop_streaming(struct
+ node->streaming = false;
+
+ if (node->pad_id == IMAGE_PAD) {
+- int ret;
+-
+ /*
+ * Stop streaming the sensor and disable the peripheral.
+ * We cannot continue streaming embedded data with the
+@@ -1762,12 +1763,13 @@ static void unicam_stop_streaming(struct
+
+ unicam_disable(dev);
+
+- ret = clk_set_min_rate(dev->vpu_clock, 0);
+- if (ret)
+- unicam_err(dev, "failed to reset the min VPU clock\n");
++ if (dev->clocks_enabled) {
++ if (clk_set_min_rate(dev->vpu_clock, 0))
++ unicam_err(dev, "failed to reset the min VPU clock\n");
+
+- clk_disable_unprepare(dev->vpu_clock);
+- clk_disable_unprepare(dev->clock);
++ clk_disable_unprepare(dev->vpu_clock);
++ clk_disable_unprepare(dev->clock);
++ }
+ unicam_runtime_put(dev);
+
+ } else if (node->pad_id == METADATA_PAD) {
diff --git a/target/linux/bcm27xx/patches-5.4/950-1026-media-bcm2835-unicam-Clear-clock-state-when-stopping.patch b/target/linux/bcm27xx/patches-5.4/950-1026-media-bcm2835-unicam-Clear-clock-state-when-stopping.patch
new file mode 100644
index 0000000000..3163107124
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1026-media-bcm2835-unicam-Clear-clock-state-when-stopping.patch
@@ -0,0 +1,25 @@
+From 210f956f55dcc457386d8a4c9b4b5803c671d28a Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Wed, 2 Dec 2020 16:48:41 +0000
+Subject: [PATCH] media: bcm2835-unicam: Clear clock state when
+ stopping streaming
+
+Commit 65e08c465020d4c5b51afb452efc2246d80fd66f failed to clear the
+clock state when the device stopped streaming. Fix this, as it might
+again cause the same problems when doing an unprepare.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ drivers/media/platform/bcm2835/bcm2835-unicam.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -1769,6 +1769,7 @@ static void unicam_stop_streaming(struct
+
+ clk_disable_unprepare(dev->vpu_clock);
+ clk_disable_unprepare(dev->clock);
++ dev->clocks_enabled = false;
+ }
+ unicam_runtime_put(dev);
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-1027-ARM-dts-CM4-audio-pins-are-not-connected.patch b/target/linux/bcm27xx/patches-5.4/950-1027-ARM-dts-CM4-audio-pins-are-not-connected.patch
new file mode 100644
index 0000000000..8ac82438e7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1027-ARM-dts-CM4-audio-pins-are-not-connected.patch
@@ -0,0 +1,21 @@
+From a679b9471f0ed1496b7d853becf38001282a738f Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 7 Dec 2020 09:35:57 +0000
+Subject: [PATCH] ARM: dts: CM4 audio pins are not connected
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
+@@ -434,8 +434,6 @@
+
+ &gpio {
+ audio_pins: audio_pins {
+- brcm,pins = <40 41>;
+- brcm,function = <4>;
+ };
+ };
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-1028-overlays-Add-PCF85063-and-PCF85063A-to-i2c-rtc.patch b/target/linux/bcm27xx/patches-5.4/950-1028-overlays-Add-PCF85063-and-PCF85063A-to-i2c-rtc.patch
new file mode 100644
index 0000000000..f55f9f6836
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1028-overlays-Add-PCF85063-and-PCF85063A-to-i2c-rtc.patch
@@ -0,0 +1,339 @@
+From ecfd415e5ae3fc05bf0c2b16a80f1d3e00447896 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 7 Dec 2020 08:49:53 +0000
+Subject: [PATCH] overlays: Add PCF85063 and PCF85063A to i2c-rtc
+
+Add support for the PCF85063 and PCF85063A RTC devices to the
+i2c-rtc overlay.
+
+Also enable the device to be used on i2c0 (i2c_vc) on GPIOs 0&1 (use
+parameter "i2c0") and GPIOs 44 & 45 (use parameter "i2c_csi_dsi").
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 8 ++
+ .../arm/boot/dts/overlays/i2c-rtc-overlay.dts | 98 ++++++++++---------
+ 2 files changed, 61 insertions(+), 45 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1243,6 +1243,10 @@ Params: abx80x Select o
+
+ pcf2129 Select the PCF2129 device
+
++ pcf85063 Select the PCF85363 device
++
++ pcf85063a Select the PCF85363A device
++
+ pcf8523 Select the PCF8523 device
+
+ pcf85363 Select the PCF85363 device
+@@ -1255,6 +1259,10 @@ Params: abx80x Select o
+
+ sd3078 Select the ZXW Shenzhen whwave SD3078 device
+
++ i2c0 Choose the I2C0 bus on GPIOs 0&1
++
++ i2c_csi_dsi Choose the I2C0 bus on GPIOs 44&45
++
+ addr Sets the address for the RTC. Note that the
+ device must be configured to use the specified
+ address.
+--- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts
++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts
+@@ -6,235 +6,238 @@
+ compatible = "brcm,bcm2835";
+
+ fragment@0 {
+- target = <&i2c_arm>;
++ target = <&i2cbus>;
+ __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>;
++ target = <&i2cbus>;
+ __dormant__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+- status = "okay";
+
+ ds1307: ds1307@68 {
+ compatible = "dallas,ds1307";
+ reg = <0x68>;
+- status = "okay";
+ };
+ };
+ };
+
+ fragment@2 {
+- target = <&i2c_arm>;
++ target = <&i2cbus>;
+ __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>;
++ target = <&i2cbus>;
+ __dormant__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+- status = "okay";
+
+ ds3231: ds3231@68 {
+ compatible = "maxim,ds3231";
+ reg = <0x68>;
+- status = "okay";
+ };
+ };
+ };
+
+ fragment@4 {
+- target = <&i2c_arm>;
++ target = <&i2cbus>;
+ __dormant__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+- status = "okay";
+
+ mcp7940x: mcp7940x@6f {
+ compatible = "microchip,mcp7940x";
+ reg = <0x6f>;
+- status = "okay";
+ };
+ };
+ };
+
+ fragment@5 {
+- target = <&i2c_arm>;
++ target = <&i2cbus>;
+ __dormant__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+- status = "okay";
+
+ mcp7941x: mcp7941x@6f {
+ compatible = "microchip,mcp7941x";
+ reg = <0x6f>;
+- status = "okay";
+ };
+ };
+ };
+
+ fragment@6 {
+- target = <&i2c_arm>;
++ target = <&i2cbus>;
+ __dormant__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+- status = "okay";
+
+ pcf2127@51 {
+ compatible = "nxp,pcf2127";
+ reg = <0x51>;
+- status = "okay";
+ };
+ };
+ };
+
+ fragment@7 {
+- target = <&i2c_arm>;
++ target = <&i2cbus>;
+ __dormant__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+- status = "okay";
+
+ pcf8523: pcf8523@68 {
+ compatible = "nxp,pcf8523";
+ reg = <0x68>;
+- status = "okay";
+ };
+ };
+ };
+
+ fragment@8 {
+- target = <&i2c_arm>;
++ target = <&i2cbus>;
+ __dormant__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+- status = "okay";
+
+ pcf8563: pcf8563@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+- status = "okay";
+ };
+ };
+ };
+
+ fragment@9 {
+- target = <&i2c_arm>;
++ target = <&i2cbus>;
+ __dormant__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+- status = "okay";
+
+ m41t62: m41t62@68 {
+ compatible = "st,m41t62";
+ reg = <0x68>;
+- status = "okay";
+ };
+ };
+ };
+
+ fragment@10 {
+- target = <&i2c_arm>;
++ target = <&i2cbus>;
+ __dormant__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+- status = "okay";
+
+ rv3028: rv3028@52 {
+ compatible = "microcrystal,rv3028";
+ reg = <0x52>;
+- status = "okay";
+ };
+ };
+ };
+
+ fragment@11 {
+- target = <&i2c_arm>;
++ target = <&i2cbus>;
+ __dormant__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+- status = "okay";
+
+ pcf2129@51 {
+ compatible = "nxp,pcf2129";
+ reg = <0x51>;
+- status = "okay";
+ };
+ };
+ };
+
+ fragment@12 {
+- target = <&i2c_arm>;
++ target = <&i2cbus>;
+ __dormant__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+- status = "okay";
+
+ pcf85363@51 {
+ compatible = "nxp,pcf85363";
+ reg = <0x51>;
+- status = "okay";
+ };
+ };
+ };
+
+ fragment@13 {
+- target = <&i2c_arm>;
++ target = <&i2cbus>;
+ __dormant__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+- status = "okay";
+
+ rv1805: rv1805@69 {
+ compatible = "microcrystal,rv1805";
+ reg = <0x69>;
+ abracon,tc-diode = "standard";
+ abracon,tc-resistor = <0>;
+- status = "okay";
+ };
+ };
+ };
+
+ fragment@14 {
+- target = <&i2c_arm>;
++ target = <&i2cbus>;
+ __dormant__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+- status = "okay";
+
+ sd3078: sd3078@32 {
+ compatible = "whwave,sd3078";
+ reg = <0x32>;
+- status = "okay";
+ };
+ };
+ };
+
++ fragment@15 {
++ target = <&i2cbus>;
++ __dormant__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ pcf85063@51 {
++ compatible = "nxp,pcf85063";
++ reg = <0x51>;
++ };
++ };
++ };
++
++ fragment@16 {
++ target = <&i2cbus>;
++ __dormant__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ pcf85063a@51 {
++ compatible = "nxp,pcf85063a";
++ reg = <0x51>;
++ };
++ };
++ };
++
++ frag100: fragment@100 {
++ target = <&i2c_arm>;
++ i2cbus: __overlay__ {
++ status = "okay";
++ };
++ };
++
+ __overrides__ {
+ abx80x = <0>,"+0";
+ ds1307 = <0>,"+1";
+@@ -251,6 +254,11 @@
+ pcf85363 = <0>,"+12";
+ rv1805 = <0>,"+13";
+ sd3078 = <0>,"+14";
++ pcf85063 = <0>,"+15";
++ pcf85063a = <0>,"+16";
++
++ i2c0 = <&frag100>, "target:0=",<&i2c0>;
++ i2c_csi_dsi = <&frag100>, "target:0=",<&i2c_csi_dsi>;
+
+ addr = <&abx80x>, "reg:0",
+ <&ds1307>, "reg:0",
diff --git a/target/linux/bcm27xx/patches-5.4/950-1029-overlays-Fix-cut-and-paste-error-in-README.patch b/target/linux/bcm27xx/patches-5.4/950-1029-overlays-Fix-cut-and-paste-error-in-README.patch
new file mode 100644
index 0000000000..4741daec7c
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1029-overlays-Fix-cut-and-paste-error-in-README.patch
@@ -0,0 +1,24 @@
+From 27f9953df117db0f38c5e597290435ecd6f3ed10 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 7 Dec 2020 17:18:39 +0000
+Subject: [PATCH] overlays: Fix cut-and-paste error in README
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1243,9 +1243,9 @@ Params: abx80x Select o
+
+ pcf2129 Select the PCF2129 device
+
+- pcf85063 Select the PCF85363 device
++ pcf85063 Select the PCF85063 device
+
+- pcf85063a Select the PCF85363A device
++ pcf85063a Select the PCF85063A device
+
+ pcf8523 Select the PCF8523 device
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-1030-media-i2c-imx477-Selection-compliance-fixes.patch b/target/linux/bcm27xx/patches-5.4/950-1030-media-i2c-imx477-Selection-compliance-fixes.patch
new file mode 100644
index 0000000000..e2ed71be39
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1030-media-i2c-imx477-Selection-compliance-fixes.patch
@@ -0,0 +1,80 @@
+From cf3885ed8bb4194c5653a9a933b4ea669cdb51c2 Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Wed, 9 Dec 2020 11:30:12 +0000
+Subject: [PATCH] media: i2c: imx477: Selection compliance fixes
+
+To comply with the intended usage of the V4L2 selection target when
+used to retrieve a sensor image properties, adjust the rectangles
+returned by the imx477 driver.
+
+The top/left crop coordinates of the TGT_CROP rectangle were set to
+(0, 0) instead of (8, 16) which is the offset from the larger physical
+pixel array rectangle. This was also a mismatch with the default values
+crop rectangle value, so this is corrected. Found with v4l2-compliance.
+
+While at it, add V4L2_SEL_TGT_CROP_BOUNDS support: CROP_DEFAULT and
+CROP_BOUNDS have the same size as the non-active pixels are not readable
+using the selection API. Found with v4l2-compliance.
+
+This commit mirrors 543790f777ba1b3264c168c653db6d415e7c983f done for
+the imx219 sensor.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ drivers/media/i2c/imx477.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/drivers/media/i2c/imx477.c
++++ b/drivers/media/i2c/imx477.c
+@@ -900,8 +900,8 @@ static const struct imx477_mode supporte
+ .height = 3040,
+ .line_length_pix = 0x5dc0,
+ .crop = {
+- .left = 0,
+- .top = 0,
++ .left = IMX477_PIXEL_ARRAY_LEFT,
++ .top = IMX477_PIXEL_ARRAY_TOP,
+ .width = 4056,
+ .height = 3040,
+ },
+@@ -924,8 +924,8 @@ static const struct imx477_mode supporte
+ .height = 1520,
+ .line_length_pix = 0x31c4,
+ .crop = {
+- .left = 0,
+- .top = 0,
++ .left = IMX477_PIXEL_ARRAY_LEFT,
++ .top = IMX477_PIXEL_ARRAY_TOP,
+ .width = 4056,
+ .height = 3040,
+ },
+@@ -948,8 +948,8 @@ static const struct imx477_mode supporte
+ .height = 1080,
+ .line_length_pix = 0x31c4,
+ .crop = {
+- .left = 0,
+- .top = 440,
++ .left = IMX477_PIXEL_ARRAY_LEFT,
++ .top = IMX477_PIXEL_ARRAY_TOP + 440,
+ .width = 4056,
+ .height = 2600,
+ },
+@@ -983,8 +983,8 @@ static const struct imx477_mode supporte
+ * rectangle once the driver is expanded to represent
+ * its processing blocks with multiple subdevs.
+ */
+- .left = 4,
+- .top = 0,
++ .left = IMX477_PIXEL_ARRAY_LEFT + 4,
++ .top = IMX477_PIXEL_ARRAY_TOP,
+ .width = 4052,
+ .height = 3040,
+ },
+@@ -1696,6 +1696,7 @@ static int imx477_get_selection(struct v
+ return 0;
+
+ case V4L2_SEL_TGT_CROP_DEFAULT:
++ case V4L2_SEL_TGT_CROP_BOUNDS:
+ sel->r.left = IMX477_PIXEL_ARRAY_LEFT;
+ sel->r.top = IMX477_PIXEL_ARRAY_TOP;
+ sel->r.width = IMX477_PIXEL_ARRAY_WIDTH;
diff --git a/target/linux/bcm27xx/patches-5.4/950-1031-net-lan78xx-Ack-pending-PHY-ints-when-resetting.patch b/target/linux/bcm27xx/patches-5.4/950-1031-net-lan78xx-Ack-pending-PHY-ints-when-resetting.patch
new file mode 100644
index 0000000000..2dc2a13cb7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1031-net-lan78xx-Ack-pending-PHY-ints-when-resetting.patch
@@ -0,0 +1,32 @@
+From 598d6389f41c1e01b70df7d8b1056c3839e0c1c2 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 15 Dec 2020 16:38:37 +0000
+Subject: [PATCH] net: lan78xx: Ack pending PHY ints when resetting
+
+lan78xx_link_reset explicitly clears the MAC's view of the PHY's IRQ
+status. In doing so it potentially leaves the PHY with a pending
+interrupt that will never be acknowledged, at which point no further
+interrupts will be generated.
+
+Avoid the problem by acknowledging any pending PHY interrupt after
+clearing the MAC's status bit.
+
+See: https://github.com/raspberrypi/linux/issues/2937
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/net/usb/lan78xx.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -1181,6 +1181,9 @@ static int lan78xx_link_reset(struct lan
+ if (unlikely(ret < 0))
+ return -EIO;
+
++ /* Acknowledge any pending PHY interrupt, lest it be the last */
++ phy_read(phydev, LAN88XX_INT_STS);
++
+ phy_read_status(phydev);
+
+ if (!phydev->link && dev->link_on) {
diff --git a/target/linux/bcm27xx/patches-5.4/950-1032-overlays-mpu6050-Add-addr-parameter.patch b/target/linux/bcm27xx/patches-5.4/950-1032-overlays-mpu6050-Add-addr-parameter.patch
new file mode 100644
index 0000000000..543b07ad08
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1032-overlays-mpu6050-Add-addr-parameter.patch
@@ -0,0 +1,36 @@
+From fcf08ed99d1421158ca913a7b6a4893c31ee1bd5 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 15 Dec 2020 17:02:17 +0000
+Subject: [PATCH] overlays: mpu6050: Add 'addr' parameter
+
+The mpu6050 starts up at address 0x68 by default, but can be set to
+0x69 if the ADO pin is pulled high. Give the overlay an addr parameter
+to allow devices at the alternate address to be used.
+
+See: https://github.com/Hexxeh/rpi-firmware/issues/252
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 1 +
+ arch/arm/boot/dts/overlays/mpu6050-overlay.dts | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1876,6 +1876,7 @@ Name: mpu6050
+ Info: Overlay for i2c connected mpu6050 imu
+ Load: dtoverlay=mpu6050,<param>=<val>
+ Params: interrupt GPIO pin for interrupt (default 4)
++ addr I2C address of the device (default 0x68)
+
+
+ Name: mz61581
+--- a/arch/arm/boot/dts/overlays/mpu6050-overlay.dts
++++ b/arch/arm/boot/dts/overlays/mpu6050-overlay.dts
+@@ -24,5 +24,6 @@
+
+ __overrides__ {
+ interrupt = <&mpu6050>,"interrupts:0";
++ addr = <&mpu6050>,"reg:0";
+ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-1033-overlays-Add-missing-addresses-to-ads1015-ads1115.patch b/target/linux/bcm27xx/patches-5.4/950-1033-overlays-Add-missing-addresses-to-ads1015-ads1115.patch
new file mode 100644
index 0000000000..6db63af319
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1033-overlays-Add-missing-addresses-to-ads1015-ads1115.patch
@@ -0,0 +1,41 @@
+From 0a8f3e6fcdbad71c0c7e993f27117f3873438e5d Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 16 Dec 2020 09:28:17 +0000
+Subject: [PATCH] overlays: Add missing addresses to ads1015/ads1115
+
+The overlays for the ads1015 and ads1115 I2C ADCs omitted the addresses
+in the main device node names. As well as breaking the conventions for
+I2C devices, this prevents the firmware from renaming them when the
+"reg" property is modified, which in turn stops the overlays from being
+instantiated multiple times.
+
+See: https://www.raspberrypi.org/forums/viewtopic.php?f=107&t=294465
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/ads1015-overlay.dts | 2 +-
+ arch/arm/boot/dts/overlays/ads1115-overlay.dts | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/ads1015-overlay.dts
++++ b/arch/arm/boot/dts/overlays/ads1015-overlay.dts
+@@ -13,7 +13,7 @@
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+- ads1015: ads1015 {
++ ads1015: ads1015@48 {
+ compatible = "ti,ads1015";
+ status = "okay";
+ #address-cells = <1>;
+--- a/arch/arm/boot/dts/overlays/ads1115-overlay.dts
++++ b/arch/arm/boot/dts/overlays/ads1115-overlay.dts
+@@ -15,7 +15,7 @@
+ #size-cells = <0>;
+ status = "okay";
+
+- ads1115: ads1115 {
++ ads1115: ads1115@48 {
+ compatible = "ti,ads1115";
+ status = "okay";
+ #address-cells = <1>;
diff --git a/target/linux/bcm27xx/patches-5.4/950-1034-media-i2c-ov5647-Selection-compliance-fixes.patch b/target/linux/bcm27xx/patches-5.4/950-1034-media-i2c-ov5647-Selection-compliance-fixes.patch
new file mode 100644
index 0000000000..58ba7e16e6
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1034-media-i2c-ov5647-Selection-compliance-fixes.patch
@@ -0,0 +1,88 @@
+From f05add64bf89b04310bc78606a5c70c0e97cb8b8 Mon Sep 17 00:00:00 2001
+From: Paul Elder <paul.elder@ideasonboard.com>
+Date: Tue, 22 Dec 2020 14:27:46 +0900
+Subject: [PATCH] media: i2c: ov5647: Selection compliance fixes
+
+To comply with the intended usage of the V4L2 selection target when
+used to retrieve a sensor image properties, adjust the rectangles
+returned by the ov5647 driver.
+
+The top/left crop coordinates of the TGT_CROP rectangle were set to
+(0, 0) instead of (16, 16) which is the offset from the larger physical
+pixel array rectangle. This was also a mismatch with the default values
+crop rectangle value, so this is corrected. Found with v4l2-compliance.
+
+While at it, add V4L2_SEL_TGT_CROP_BOUNDS support: CROP_DEFAULT and
+CROP_BOUNDS have the same size as the non-active pixels are not readable
+using the selection API. Found with v4l2-compliance.
+
+Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
+---
+ drivers/media/i2c/ov5647.c | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+--- a/drivers/media/i2c/ov5647.c
++++ b/drivers/media/i2c/ov5647.c
+@@ -606,8 +606,8 @@ static struct ov5647_mode supported_mode
+ .height = 480
+ },
+ .crop = {
+- .left = 0,
+- .top = 0,
++ .left = OV5647_PIXEL_ARRAY_LEFT,
++ .top = OV5647_PIXEL_ARRAY_TOP,
+ .width = 1280,
+ .height = 960,
+ },
+@@ -632,8 +632,8 @@ static struct ov5647_mode supported_mode
+ .height = 1944
+ },
+ .crop = {
+- .left = 0,
+- .top = 0,
++ .left = OV5647_PIXEL_ARRAY_LEFT,
++ .top = OV5647_PIXEL_ARRAY_TOP,
+ .width = 2592,
+ .height = 1944
+ },
+@@ -656,8 +656,8 @@ static struct ov5647_mode supported_mode
+ .height = 1080
+ },
+ .crop = {
+- .left = 348,
+- .top = 434,
++ .left = 364,
++ .top = 450,
+ .width = 1928,
+ .height = 1080,
+ },
+@@ -679,8 +679,8 @@ static struct ov5647_mode supported_mode
+ .height = 972
+ },
+ .crop = {
+- .left = 0,
+- .top = 0,
++ .left = OV5647_PIXEL_ARRAY_LEFT,
++ .top = OV5647_PIXEL_ARRAY_TOP,
+ .width = 2592,
+ .height = 1944,
+ },
+@@ -703,8 +703,8 @@ static struct ov5647_mode supported_mode
+ .height = 480
+ },
+ .crop = {
+- .left = 16,
+- .top = 0,
++ .left = OV5647_PIXEL_ARRAY_LEFT,
++ .top = OV5647_PIXEL_ARRAY_TOP,
+ .width = 2560,
+ .height = 1920,
+ },
+@@ -1080,6 +1080,7 @@ static int ov5647_get_selection(struct v
+ return 0;
+
+ case V4L2_SEL_TGT_CROP_DEFAULT:
++ case V4L2_SEL_TGT_CROP_BOUNDS:
+ sel->r.top = OV5647_PIXEL_ARRAY_TOP;
+ sel->r.left = OV5647_PIXEL_ARRAY_LEFT;
+ sel->r.width = OV5647_PIXEL_ARRAY_WIDTH;
diff --git a/target/linux/bcm27xx/patches-5.4/950-1035-Add-overlay-for-Seeed-Studio-CAN-BUS-FD-HAT-4034.patch b/target/linux/bcm27xx/patches-5.4/950-1035-Add-overlay-for-Seeed-Studio-CAN-BUS-FD-HAT-4034.patch
new file mode 100644
index 0000000000..a5bbbdd4e6
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1035-Add-overlay-for-Seeed-Studio-CAN-BUS-FD-HAT-4034.patch
@@ -0,0 +1,217 @@
+From 4a314a9b9d91cacbf6be9dd521cf3abd3ae8bcef Mon Sep 17 00:00:00 2001
+From: menschel <menschel.p@posteo.de>
+Date: Wed, 30 Dec 2020 21:55:34 +0100
+Subject: [PATCH] Add overlay for Seeed Studio CAN BUS FD HAT (#4034)
+
+This patch adds the overlay for the Seeed Studio CAN BUS FD HAT
+with two CAN FD Channels and an RTC.
+https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html
+
+The overlay was generated by
+ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 \
+ mcp251xfd-overlay.dts,spi0-1,interrupt=24 \
+ i2c-rtc-overlay.dts,pcf85063
+
+
+Also, add description on how to generate overlays
+
+Signed-off-by: Patrick Menschel <menschel.p@posteo.de>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 46 +++++++
+ .../dts/overlays/seeed-can-fd-hat-overlay.dts | 117 ++++++++++++++++++
+ 3 files changed, 164 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/seeed-can-fd-hat-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -159,6 +159,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ sc16is752-spi1.dtbo \
+ sdhost.dtbo \
+ sdio.dtbo \
++ seeed-can-fd-hat.dtbo \
+ sh1106-spi.dtbo \
+ smi.dtbo \
+ smi-dev.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -81,6 +81,44 @@ Parameters usually have default values,
+ mandatory. See the list of overlays below for a description of the parameters
+ and their defaults.
+
++Making new Overlays based on existing Overlays
++==============================================
++
++Recent overlays have been designed in a more general way, so that they can be
++adapted to hardware by changing their parameters. When you have additional
++hardware with more than one device of a kind, you end up using the same overlay
++multiple times with other parameters, e.g.
++
++ # 2 CAN FD interfaces on spi but with different pins
++ dtoverlay=mcp251xfd,spi0-0,interrupt=25
++ dtoverlay=mcp251xfd,spi0-1,interrupt=24
++
++ # a realtime clock on i2c
++ dtoverlay=i2c-rtc,pcf85063
++
++While this approach does work, it requires knowledge about the hardware design.
++It is more feasible to simplify things for the end user by providing a single
++overlay as it is done the traditional way.
++
++A new overlay can be generated by using ovmerge utility.
++https://github.com/raspberrypi/utils/blob/master/ovmerge/ovmerge
++
++To generate an overlay for the above configuration we pass the configuration
++to ovmerge and add the -c flag.
++
++ ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 \
++ mcp251xfd-overlay.dts,spi0-1,interrupt=24 \
++ i2c-rtc-overlay.dts,pcf85063 \
++ >> merged-overlay.dts
++
++The -c option writes the command above as a comment into the overlay as
++a marker that this overlay is generated and how it was generated.
++After compiling the overlay it can be loaded in a single line.
++
++ dtoverlay=merged
++
++It does the same as the original configuration but without parameters.
++
+ The Overlay and Parameter Reference
+ ===================================
+
+@@ -2422,6 +2460,14 @@ Info: This overlay is now deprecated.
+ Load: <Deprecated>
+
+
++Name: seeed-can-fd-hat
++Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels and an
++ RTC.
++ https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html
++Load: dtoverlay=seeed-can-fd-hat
++Params: <None>
++
++
+ Name: sh1106-spi
+ Info: Overlay for SH1106 OLED via SPI using fbtft staging driver.
+ Load: dtoverlay=sh1106-spi,<param>=<val>
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/seeed-can-fd-hat-overlay.dts
+@@ -0,0 +1,117 @@
++// redo: ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 mcp251xfd-overlay.dts,spi0-1,interrupt=24 i2c-rtc-overlay.dts,pcf85063
++
++// Device tree overlay for https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html
++
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/pinctrl/bcm2835.h>
++
++/ {
++ compatible = "brcm,bcm2835";
++ fragment@0 {
++ target = <&spidev0>;
++ __overlay__ {
++ status = "disabled";
++ };
++ };
++ fragment@1 {
++ target = <&gpio>;
++ __overlay__ {
++ mcp251xfd_pins: mcp251xfd_spi0_0_pins {
++ brcm,pins = <25>;
++ brcm,function = <BCM2835_FSEL_GPIO_IN>;
++ };
++ };
++ };
++ fragment@2 {
++ target-path = "/clocks";
++ __overlay__ {
++ clk_mcp251xfd_osc: mcp251xfd-spi0-0-osc {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <40000000>;
++ };
++ };
++ };
++ fragment@3 {
++ target = <&spi0>;
++ __overlay__ {
++ status = "okay";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ mcp251xfd@0 {
++ compatible = "microchip,mcp251xfd";
++ reg = <0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&mcp251xfd_pins>;
++ spi-max-frequency = <20000000>;
++ interrupt-parent = <&gpio>;
++ interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&clk_mcp251xfd_osc>;
++ };
++ };
++ };
++ fragment@4 {
++ target = <&spidev1>;
++ __overlay__ {
++ status = "disabled";
++ };
++ };
++ fragment@5 {
++ target = <&gpio>;
++ __overlay__ {
++ mcp251xfd_pins_1: mcp251xfd_spi0_1_pins {
++ brcm,pins = <24>;
++ brcm,function = <BCM2835_FSEL_GPIO_IN>;
++ };
++ };
++ };
++ fragment@6 {
++ target-path = "/clocks";
++ __overlay__ {
++ clk_mcp251xfd_osc_1: mcp251xfd-spi0-1-osc {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <40000000>;
++ };
++ };
++ };
++ fragment@7 {
++ target = <&spi0>;
++ __overlay__ {
++ status = "okay";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ mcp251xfd@1 {
++ compatible = "microchip,mcp251xfd";
++ reg = <1>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&mcp251xfd_pins_1>;
++ spi-max-frequency = <20000000>;
++ interrupt-parent = <&gpio>;
++ interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&clk_mcp251xfd_osc_1>;
++ };
++ };
++ };
++ fragment@8 {
++ target = <&i2cbus>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ pcf85063@51 {
++ compatible = "nxp,pcf85063";
++ reg = <0x51>;
++ };
++ };
++ };
++ fragment@9 {
++ target = <&i2c_arm>;
++ i2cbus: __overlay__ {
++ status = "okay";
++ };
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-1036-overlays-Rebuild-upstream-with-latest-ovmerge.patch b/target/linux/bcm27xx/patches-5.4/950-1036-overlays-Rebuild-upstream-with-latest-ovmerge.patch
new file mode 100644
index 0000000000..b2e32cd9aa
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1036-overlays-Rebuild-upstream-with-latest-ovmerge.patch
@@ -0,0 +1,173 @@
+From 6091a6c5536f422df652c4a14725de7dd1fc5e0f Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 30 Dec 2020 20:00:38 +0000
+Subject: [PATCH] overlays: Rebuild "upstream" with latest ovmerge
+
+The latest ovmerge drops disabled fragments, causing the "upstream"
+overlay to change.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ .../boot/dts/overlays/upstream-overlay.dts | 38 +++++++------------
+ .../dts/overlays/upstream-pi4-overlay.dts | 28 +-------------
+ 2 files changed, 15 insertions(+), 51 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/upstream-overlay.dts
++++ b/arch/arm/boot/dts/overlays/upstream-overlay.dts
+@@ -8,96 +8,84 @@
+ / {
+ compatible = "brcm,bcm2835";
+ fragment@0 {
+- target = <&cma>;
+- __dormant__ {
+- size = <0x10000000>;
+- };
+- };
+- fragment@1 {
+ target = <&i2c2>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+- fragment@2 {
++ fragment@1 {
+ target = <&fb>;
+ __overlay__ {
+ status = "disabled";
+ };
+ };
+- fragment@3 {
++ fragment@2 {
+ target = <&pixelvalve0>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+- fragment@4 {
++ fragment@3 {
+ target = <&pixelvalve1>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+- fragment@5 {
++ fragment@4 {
+ target = <&pixelvalve2>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+- fragment@6 {
++ fragment@5 {
+ target = <&hvs>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+- fragment@7 {
++ fragment@6 {
+ target = <&hdmi>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+- fragment@8 {
++ fragment@7 {
+ target = <&v3d>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+- fragment@9 {
++ fragment@8 {
+ target = <&vc4>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+- fragment@10 {
++ fragment@9 {
+ target = <&clocks>;
+ __overlay__ {
+ claim-clocks = <BCM2835_PLLD_DSI0 BCM2835_PLLD_DSI1 BCM2835_PLLH_AUX BCM2835_PLLH_PIX>;
+ };
+ };
+- fragment@11 {
++ fragment@10 {
+ target = <&vec>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+- fragment@12 {
++ fragment@11 {
+ target = <&txp>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+- fragment@13 {
+- target = <&hdmi>;
+- __dormant__ {
+- dmas;
+- };
+- };
+- fragment@14 {
++ fragment@12 {
+ target = <&audio>;
+ __overlay__ {
+ brcm,disable-hdmi;
+ };
+ };
+- fragment@15 {
++ fragment@13 {
+ target = <&usb>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+--- a/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts
++++ b/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts
+@@ -110,42 +110,18 @@
+ };
+ };
+ fragment@17 {
+- target = <&hdmi0>;
+- __dormant__ {
+- dmas;
+- };
+- };
+- fragment@18 {
+- target = <&hdmi1>;
+- __dormant__ {
+- dmas;
+- };
+- };
+- fragment@19 {
+ target = <&audio>;
+ __overlay__ {
+ brcm,disable-hdmi;
+ };
+ };
+- fragment@20 {
++ fragment@18 {
+ target = <&dvp>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+- fragment@21 {
+- target = <&pixelvalve3>;
+- __dormant__ {
+- status = "okay";
+- };
+- };
+- fragment@22 {
+- target = <&vec>;
+- __dormant__ {
+- status = "okay";
+- };
+- };
+- fragment@23 {
++ fragment@19 {
+ target = <&usb>;
+ #address-cells = <1>;
+ #size-cells = <1>;
diff --git a/target/linux/bcm27xx/patches-5.4/950-1037-overlays-give-Seeed-Studio-CAN-BUS-FD-HAT-a-v2-postf.patch b/target/linux/bcm27xx/patches-5.4/950-1037-overlays-give-Seeed-Studio-CAN-BUS-FD-HAT-a-v2-postf.patch
new file mode 100644
index 0000000000..185c16c800
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1037-overlays-give-Seeed-Studio-CAN-BUS-FD-HAT-a-v2-postf.patch
@@ -0,0 +1,286 @@
+From 6b458078a50b9332e799e045f91c288a7ff8d8ca Mon Sep 17 00:00:00 2001
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+Date: Sat, 2 Jan 2021 21:08:59 +0100
+Subject: [PATCH] overlays: give Seeed Studio CAN BUS FD HAT a -v2
+ postfix
+
+There are several versions of the Seeed Studio CAN BUS FD HAT. This is the
+second version, based on the mcp2518fd, so give it a -v2 postfix.
+
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+---
+ arch/arm/boot/dts/overlays/Makefile | 2 +-
+ arch/arm/boot/dts/overlays/README | 8 ++++----
+ ...fd-hat-overlay.dts => seeed-can-fd-hat-v2-overlay.dts} | 0
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+ rename arch/arm/boot/dts/overlays/{seeed-can-fd-hat-overlay.dts => seeed-can-fd-hat-v2-overlay.dts} (100%)
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -159,7 +159,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ sc16is752-spi1.dtbo \
+ sdhost.dtbo \
+ sdio.dtbo \
+- seeed-can-fd-hat.dtbo \
++ seeed-can-fd-hat-v2.dtbo \
+ sh1106-spi.dtbo \
+ smi.dtbo \
+ smi-dev.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -2460,11 +2460,11 @@ Info: This overlay is now deprecated.
+ Load: <Deprecated>
+
+
+-Name: seeed-can-fd-hat
+-Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels and an
+- RTC.
++Name: seeed-can-fd-hat-v2
++Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels
++ (based on the mcp2518fd) and an RTC.
+ https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html
+-Load: dtoverlay=seeed-can-fd-hat
++Load: dtoverlay=seeed-can-fd-hat-v2
+ Params: <None>
+
+
+--- a/arch/arm/boot/dts/overlays/seeed-can-fd-hat-overlay.dts
++++ /dev/null
+@@ -1,117 +0,0 @@
+-// redo: ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 mcp251xfd-overlay.dts,spi0-1,interrupt=24 i2c-rtc-overlay.dts,pcf85063
+-
+-// Device tree overlay for https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html
+-
+-/dts-v1/;
+-/plugin/;
+-
+-#include <dt-bindings/gpio/gpio.h>
+-#include <dt-bindings/interrupt-controller/irq.h>
+-#include <dt-bindings/pinctrl/bcm2835.h>
+-
+-/ {
+- compatible = "brcm,bcm2835";
+- fragment@0 {
+- target = <&spidev0>;
+- __overlay__ {
+- status = "disabled";
+- };
+- };
+- fragment@1 {
+- target = <&gpio>;
+- __overlay__ {
+- mcp251xfd_pins: mcp251xfd_spi0_0_pins {
+- brcm,pins = <25>;
+- brcm,function = <BCM2835_FSEL_GPIO_IN>;
+- };
+- };
+- };
+- fragment@2 {
+- target-path = "/clocks";
+- __overlay__ {
+- clk_mcp251xfd_osc: mcp251xfd-spi0-0-osc {
+- #clock-cells = <0>;
+- compatible = "fixed-clock";
+- clock-frequency = <40000000>;
+- };
+- };
+- };
+- fragment@3 {
+- target = <&spi0>;
+- __overlay__ {
+- status = "okay";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- mcp251xfd@0 {
+- compatible = "microchip,mcp251xfd";
+- reg = <0>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&mcp251xfd_pins>;
+- spi-max-frequency = <20000000>;
+- interrupt-parent = <&gpio>;
+- interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
+- clocks = <&clk_mcp251xfd_osc>;
+- };
+- };
+- };
+- fragment@4 {
+- target = <&spidev1>;
+- __overlay__ {
+- status = "disabled";
+- };
+- };
+- fragment@5 {
+- target = <&gpio>;
+- __overlay__ {
+- mcp251xfd_pins_1: mcp251xfd_spi0_1_pins {
+- brcm,pins = <24>;
+- brcm,function = <BCM2835_FSEL_GPIO_IN>;
+- };
+- };
+- };
+- fragment@6 {
+- target-path = "/clocks";
+- __overlay__ {
+- clk_mcp251xfd_osc_1: mcp251xfd-spi0-1-osc {
+- #clock-cells = <0>;
+- compatible = "fixed-clock";
+- clock-frequency = <40000000>;
+- };
+- };
+- };
+- fragment@7 {
+- target = <&spi0>;
+- __overlay__ {
+- status = "okay";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- mcp251xfd@1 {
+- compatible = "microchip,mcp251xfd";
+- reg = <1>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&mcp251xfd_pins_1>;
+- spi-max-frequency = <20000000>;
+- interrupt-parent = <&gpio>;
+- interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
+- clocks = <&clk_mcp251xfd_osc_1>;
+- };
+- };
+- };
+- fragment@8 {
+- target = <&i2cbus>;
+- __overlay__ {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- pcf85063@51 {
+- compatible = "nxp,pcf85063";
+- reg = <0x51>;
+- };
+- };
+- };
+- fragment@9 {
+- target = <&i2c_arm>;
+- i2cbus: __overlay__ {
+- status = "okay";
+- };
+- };
+-};
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/seeed-can-fd-hat-v2-overlay.dts
+@@ -0,0 +1,117 @@
++// redo: ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 mcp251xfd-overlay.dts,spi0-1,interrupt=24 i2c-rtc-overlay.dts,pcf85063
++
++// Device tree overlay for https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html
++
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/pinctrl/bcm2835.h>
++
++/ {
++ compatible = "brcm,bcm2835";
++ fragment@0 {
++ target = <&spidev0>;
++ __overlay__ {
++ status = "disabled";
++ };
++ };
++ fragment@1 {
++ target = <&gpio>;
++ __overlay__ {
++ mcp251xfd_pins: mcp251xfd_spi0_0_pins {
++ brcm,pins = <25>;
++ brcm,function = <BCM2835_FSEL_GPIO_IN>;
++ };
++ };
++ };
++ fragment@2 {
++ target-path = "/clocks";
++ __overlay__ {
++ clk_mcp251xfd_osc: mcp251xfd-spi0-0-osc {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <40000000>;
++ };
++ };
++ };
++ fragment@3 {
++ target = <&spi0>;
++ __overlay__ {
++ status = "okay";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ mcp251xfd@0 {
++ compatible = "microchip,mcp251xfd";
++ reg = <0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&mcp251xfd_pins>;
++ spi-max-frequency = <20000000>;
++ interrupt-parent = <&gpio>;
++ interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&clk_mcp251xfd_osc>;
++ };
++ };
++ };
++ fragment@4 {
++ target = <&spidev1>;
++ __overlay__ {
++ status = "disabled";
++ };
++ };
++ fragment@5 {
++ target = <&gpio>;
++ __overlay__ {
++ mcp251xfd_pins_1: mcp251xfd_spi0_1_pins {
++ brcm,pins = <24>;
++ brcm,function = <BCM2835_FSEL_GPIO_IN>;
++ };
++ };
++ };
++ fragment@6 {
++ target-path = "/clocks";
++ __overlay__ {
++ clk_mcp251xfd_osc_1: mcp251xfd-spi0-1-osc {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <40000000>;
++ };
++ };
++ };
++ fragment@7 {
++ target = <&spi0>;
++ __overlay__ {
++ status = "okay";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ mcp251xfd@1 {
++ compatible = "microchip,mcp251xfd";
++ reg = <1>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&mcp251xfd_pins_1>;
++ spi-max-frequency = <20000000>;
++ interrupt-parent = <&gpio>;
++ interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&clk_mcp251xfd_osc_1>;
++ };
++ };
++ };
++ fragment@8 {
++ target = <&i2cbus>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ pcf85063@51 {
++ compatible = "nxp,pcf85063";
++ reg = <0x51>;
++ };
++ };
++ };
++ fragment@9 {
++ target = <&i2c_arm>;
++ i2cbus: __overlay__ {
++ status = "okay";
++ };
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-1038-overlays-Add-overlay-for-Seeed-Studio-CAN-BUS-FD-HAT.patch b/target/linux/bcm27xx/patches-5.4/950-1038-overlays-Add-overlay-for-Seeed-Studio-CAN-BUS-FD-HAT.patch
new file mode 100644
index 0000000000..6ae1680d88
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1038-overlays-Add-overlay-for-Seeed-Studio-CAN-BUS-FD-HAT.patch
@@ -0,0 +1,192 @@
+From 42c792400770ec57cafce87cb9594a948d6c0700 Mon Sep 17 00:00:00 2001
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+Date: Sat, 2 Jan 2021 21:38:58 +0100
+Subject: [PATCH] overlays: Add overlay for Seeed Studio CAN BUS FD
+ HAT v1 (based on mcp2517fd)
+
+This patch adds the overlay for the Seeed Studio CAN BUS FD HAT v1 with two CAN
+FD Channels (based on mcp2517fd).
+
+https://www.seeedstudio.com/2-Channel-CAN-BUS-FD-Shield-for-Raspberry-Pi-p-4072.html
+
+The overlay was generated by:
+ovmerge -c spi1-1cs-overlay.dts,cs0_pin=18,cs0_spidev=false \
+ mcp251xfd-overlay.dts,spi0-0,interrupt=25 \
+ mcp251xfd-overlay.dts,spi1-0,interrupt=24
+
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 8 +
+ .../overlays/seeed-can-fd-hat-v1-overlay.dts | 138 ++++++++++++++++++
+ 3 files changed, 147 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/seeed-can-fd-hat-v1-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -159,6 +159,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ sc16is752-spi1.dtbo \
+ sdhost.dtbo \
+ sdio.dtbo \
++ seeed-can-fd-hat-v1.dtbo \
+ seeed-can-fd-hat-v2.dtbo \
+ sh1106-spi.dtbo \
+ smi.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -2460,6 +2460,14 @@ Info: This overlay is now deprecated.
+ Load: <Deprecated>
+
+
++Name: seeed-can-fd-hat-v1
++Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels
++ (based on the mcp2517fd).
++ https://www.seeedstudio.com/2-Channel-CAN-BUS-FD-Shield-for-Raspberry-Pi-p-4072.html
++Load: dtoverlay=seeed-can-fd-hat-v1
++Params: <None>
++
++
+ Name: seeed-can-fd-hat-v2
+ Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels
+ (based on the mcp2518fd) and an RTC.
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/seeed-can-fd-hat-v1-overlay.dts
+@@ -0,0 +1,138 @@
++// redo: ovmerge -c spi1-1cs-overlay.dts,cs0_pin=18,cs0_spidev=false mcp251xfd-overlay.dts,spi0-0,interrupt=25 mcp251xfd-overlay.dts,spi1-0,interrupt=24
++
++// Device tree overlay for https://www.seeedstudio.com/2-Channel-CAN-BUS-FD-Shield-for-Raspberry-Pi-p-4072.html
++
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/pinctrl/bcm2835.h>
++
++/ {
++ compatible = "brcm,bcm2835";
++ fragment@0 {
++ target = <&gpio>;
++ __overlay__ {
++ spi1_pins: spi1_pins {
++ brcm,pins = <19 20 21>;
++ brcm,function = <3>;
++ };
++ spi1_cs_pins: spi1_cs_pins {
++ brcm,pins = <18>;
++ brcm,function = <1>;
++ };
++ };
++ };
++ fragment@1 {
++ target = <&spi1>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi1_pins &spi1_cs_pins>;
++ cs-gpios = <&gpio 18 1>;
++ status = "okay";
++ spidev@0 {
++ compatible = "spidev";
++ reg = <0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ spi-max-frequency = <125000000>;
++ status = "disabled";
++ };
++ };
++ };
++ fragment@2 {
++ target = <&aux>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++ fragment@3 {
++ target = <&spidev0>;
++ __overlay__ {
++ status = "disabled";
++ };
++ };
++ fragment@4 {
++ target = <&gpio>;
++ __overlay__ {
++ mcp251xfd_pins: mcp251xfd_spi0_0_pins {
++ brcm,pins = <25>;
++ brcm,function = <BCM2835_FSEL_GPIO_IN>;
++ };
++ };
++ };
++ fragment@5 {
++ target-path = "/clocks";
++ __overlay__ {
++ clk_mcp251xfd_osc: mcp251xfd-spi0-0-osc {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <40000000>;
++ };
++ };
++ };
++ fragment@6 {
++ target = <&spi0>;
++ __overlay__ {
++ status = "okay";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ mcp251xfd@0 {
++ compatible = "microchip,mcp251xfd";
++ reg = <0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&mcp251xfd_pins>;
++ spi-max-frequency = <20000000>;
++ interrupt-parent = <&gpio>;
++ interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&clk_mcp251xfd_osc>;
++ };
++ };
++ };
++ fragment@7 {
++ target-path = "spi1/spidev@0";
++ __overlay__ {
++ status = "disabled";
++ };
++ };
++ fragment@8 {
++ target = <&gpio>;
++ __overlay__ {
++ mcp251xfd_pins_1: mcp251xfd_spi1_0_pins {
++ brcm,pins = <24>;
++ brcm,function = <BCM2835_FSEL_GPIO_IN>;
++ };
++ };
++ };
++ fragment@9 {
++ target-path = "/clocks";
++ __overlay__ {
++ clk_mcp251xfd_osc_1: mcp251xfd-spi1-0-osc {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <40000000>;
++ };
++ };
++ };
++ fragment@10 {
++ target = <&spi1>;
++ __overlay__ {
++ status = "okay";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ mcp251xfd@0 {
++ compatible = "microchip,mcp251xfd";
++ reg = <0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&mcp251xfd_pins_1>;
++ spi-max-frequency = <20000000>;
++ interrupt-parent = <&gpio>;
++ interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&clk_mcp251xfd_osc_1>;
++ };
++ };
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-1039-overlays-add-wm8960-soundcard-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-1039-overlays-add-wm8960-soundcard-overlay.patch
new file mode 100644
index 0000000000..fa2f54cacf
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1039-overlays-add-wm8960-soundcard-overlay.patch
@@ -0,0 +1,129 @@
+From 4b26aad69c65e141e7ad5187c558d20304eb4bd8 Mon Sep 17 00:00:00 2001
+From: Aaron Shaw <shawaj@gmail.com>
+Date: Sat, 2 Jan 2021 02:34:03 +0000
+Subject: [PATCH] overlays: add wm8960-soundcard overlay
+
+add overlay for waveshare wm8960 simple-audio-card
+
+Change-type: patch
+Signed-off-by: Aaron Shaw <shawaj@gmail.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 3 +-
+ arch/arm/boot/dts/overlays/README | 7 ++
+ .../dts/overlays/wm8960-soundcard-overlay.dts | 82 +++++++++++++++++++
+ 3 files changed, 91 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm/boot/dts/overlays/wm8960-soundcard-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -210,7 +210,8 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ w1-gpio.dtbo \
+ w1-gpio-pullup.dtbo \
+ w5500.dtbo \
+- wittypi.dtbo
++ wittypi.dtbo \
++ wm8960-soundcard.dtbo
+
+ targets += dtbs dtbs_install
+ targets += $(dtbo-y)
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -3073,6 +3073,13 @@ Params: led_gpio GPIO for
+ "default-on")
+
+
++Name: wm8960-soundcard
++Info: Overlay for the Waveshare wm8960 soundcard
++Load: dtoverlay=wm8960-soundcard,<param>=<val>
++Params: alsaname Changes the card name in ALSA
++ compatible Changes the codec compatibility
++
++
+ Troubleshooting
+ ===============
+
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/wm8960-soundcard-overlay.dts
+@@ -0,0 +1,82 @@
++// Definitions for Waveshare WM8960 https://github.com/waveshare/WM8960-Audio-HAT
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2835";
++
++ fragment@0 {
++ target = <&i2s>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@1 {
++ target-path="/";
++ __overlay__ {
++ wm8960_mclk: wm8960_mclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <12288000>;
++ };
++ };
++ };
++ fragment@2 {
++ target = <&i2c1>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ wm8960: wm8960 {
++ compatible = "wlf,wm8960";
++ reg = <0x1a>;
++ #sound-dai-cells = <0>;
++ AVDD-supply = <&vdd_5v0_reg>;
++ DVDD-supply = <&vdd_3v3_reg>;
++ };
++ };
++ };
++
++
++ fragment@3 {
++ target = <&sound>;
++ slave_overlay: __overlay__ {
++ compatible = "simple-audio-card";
++ simple-audio-card,format = "i2s";
++ simple-audio-card,name = "wm8960-soundcard";
++ status = "okay";
++
++ simple-audio-card,widgets =
++ "Microphone", "Mic Jack",
++ "Line", "Line In",
++ "Line", "Line Out",
++ "Speaker", "Speaker",
++ "Headphone", "Headphone Jack";
++ simple-audio-card,routing =
++ "Headphone Jack", "HP_L",
++ "Headphone Jack", "HP_R",
++ "Speaker", "SPK_LP",
++ "Speaker", "SPK_LN",
++ "LINPUT1", "Mic Jack",
++ "LINPUT3", "Mic Jack",
++ "RINPUT1", "Mic Jack",
++ "RINPUT2", "Mic Jack";
++
++ simple-audio-card,cpu {
++ sound-dai = <&i2s>;
++ };
++ dailink0_slave: simple-audio-card,codec {
++ sound-dai = <&wm8960>;
++ clocks = <&wm8960_mclk>;
++ clock-names = "mclk";
++ };
++ };
++ };
++
++ __overrides__ {
++ alsaname = <&slave_overlay>,"simple-audio-card,name";
++ compatible = <&wm8960>,"compatible";
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-1040-overlays-add-spi-override-to-merus-amp-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-1040-overlays-add-spi-override-to-merus-amp-overlay.patch
new file mode 100644
index 0000000000..213d29367d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1040-overlays-add-spi-override-to-merus-amp-overlay.patch
@@ -0,0 +1,44 @@
+From 2b4ffcc3d1a589154928830e56d4b8efdf15e368 Mon Sep 17 00:00:00 2001
+From: Aaron Shaw <shawaj@gmail.com>
+Date: Sat, 26 Dec 2020 03:13:14 +0000
+Subject: [PATCH] overlays: add spi override to merus-amp overlay
+
+adds an override to the merus-amp overlay to turn the spi bus off
+
+Change-type: patch
+Signed-off-by: Aaron Shaw <shawaj@gmail.com>
+---
+ arch/arm/boot/dts/overlays/README | 4 ++--
+ arch/arm/boot/dts/overlays/merus-amp-overlay.dts | 10 ++++++++++
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1870,8 +1870,8 @@ Params: speed Display
+
+ Name: merus-amp
+ Info: Configures the merus-amp audio card
+-Load: dtoverlay=merus-amp
+-Params: <None>
++Load: dtoverlay=merus-amp,<param>=<val>
++Params: spioff Turn SPI bus off
+
+
+ Name: midi-uart0
+--- a/arch/arm/boot/dts/overlays/merus-amp-overlay.dts
++++ b/arch/arm/boot/dts/overlays/merus-amp-overlay.dts
+@@ -57,4 +57,14 @@
+ status = "okay";
+ };
+ };
++
++ fragment@4 {
++ target = <&spi0>;
++ frag4: __overlay__ {
++ };
++ };
++
++ __overrides__ {
++ spioff = <&frag4>, "status=disabled";
++ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-1041-overlays-seeed-can-fd-hat-clarify-how-to-identify-HA.patch b/target/linux/bcm27xx/patches-5.4/950-1041-overlays-seeed-can-fd-hat-clarify-how-to-identify-HA.patch
new file mode 100644
index 0000000000..d622888e1f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1041-overlays-seeed-can-fd-hat-clarify-how-to-identify-HA.patch
@@ -0,0 +1,45 @@
+From 426116286821ed9ce10e415ffdebb2c55e728050 Mon Sep 17 00:00:00 2001
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+Date: Sat, 9 Jan 2021 17:03:32 +0100
+Subject: [PATCH] overlays: seeed-can-fd-hat: clarify how to identify
+ HAT version
+
+It turns out the used CAN SPI chip is not a good way to identify the version of
+the CAN HAT.
+
+There are two different board layouts of the Seeed Studio CAN BUS FD HAT. The
+v1 board doesn't have a battery holder, while the v2 board has. Update the
+overlay README accordinly.
+
+Link: https://github.com/Seeed-Studio/seeed-linux-dtoverlays/issues/13
+Cc: Patrick Menschel <menschel.p@posteo.de>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+---
+ arch/arm/boot/dts/overlays/README | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -2461,16 +2461,18 @@ Load: <Deprecated>
+
+
+ Name: seeed-can-fd-hat-v1
+-Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels
+- (based on the mcp2517fd).
++Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD
++ channels without RTC. Use this overlay if your HAT has no
++ battery holder.
+ https://www.seeedstudio.com/2-Channel-CAN-BUS-FD-Shield-for-Raspberry-Pi-p-4072.html
+ Load: dtoverlay=seeed-can-fd-hat-v1
+ Params: <None>
+
+
+ Name: seeed-can-fd-hat-v2
+-Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels
+- (based on the mcp2518fd) and an RTC.
++Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD
++ channels and an RTC. Use this overlay if your HAT has a
++ battery holder.
+ https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html
+ Load: dtoverlay=seeed-can-fd-hat-v2
+ Params: <None>
diff --git a/target/linux/bcm27xx/patches-5.4/950-1042-uapi-bcm2835-isp-Add-colour-denoise-configuration.patch b/target/linux/bcm27xx/patches-5.4/950-1042-uapi-bcm2835-isp-Add-colour-denoise-configuration.patch
new file mode 100644
index 0000000000..48ffc017f0
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1042-uapi-bcm2835-isp-Add-colour-denoise-configuration.patch
@@ -0,0 +1,56 @@
+From b920f23b301503d6127f3fcdc3c88e24aa470679 Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Thu, 14 Jan 2021 09:18:42 +0000
+Subject: [PATCH] uapi: bcm2835-isp: Add colour denoise configuration
+
+Add a configuration structure for colour denoise to the bcm2835_isp
+driver.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ include/uapi/linux/bcm2835-isp.h | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+--- a/include/uapi/linux/bcm2835-isp.h
++++ b/include/uapi/linux/bcm2835-isp.h
+@@ -31,6 +31,8 @@
+ (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0007)
+ #define V4L2_CID_USER_BCM2835_ISP_DPC \
+ (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0008)
++#define V4L2_CID_USER_BCM2835_ISP_CDN \
++ (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0009)
+
+ /*
+ * All structs below are directly mapped onto the equivalent structs in
+@@ -176,6 +178,31 @@ struct bcm2835_isp_gamma {
+ };
+
+ /**
++ * enum bcm2835_isp_cdn_mode - Mode of operation for colour denoise.
++ *
++ * @CDN_MODE_FAST: Fast (but lower quality) colour denoise
++ * algorithm, typically used for video recording.
++ * @CDN_HIGH_QUALITY: High quality (but slower) colour denoise
++ * algorithm, typically used for stills capture.
++ */
++enum bcm2835_isp_cdn_mode {
++ CDN_MODE_FAST = 0,
++ CDN_MODE_HIGH_QUALITY = 1,
++};
++
++/**
++ * struct bcm2835_isp_cdn - Colour denoise parameters set with the
++ * V4L2_CID_USER_BCM2835_ISP_CDN ctrl.
++ *
++ * @enabled: Enable colour denoise.
++ * @mode: Colour denoise operating mode (see enum &bcm2835_isp_cdn_mode)
++ */
++struct bcm2835_isp_cdn {
++ __u32 enabled;
++ __u32 mode;
++};
++
++/**
+ * struct bcm2835_isp_denoise - Denoise parameters set with the
+ * V4L2_CID_USER_BCM2835_ISP_DENOISE ctrl.
+ *
diff --git a/target/linux/bcm27xx/patches-5.4/950-1043-staging-vc04_services-ISP-Add-colour-denoise-control.patch b/target/linux/bcm27xx/patches-5.4/950-1043-staging-vc04_services-ISP-Add-colour-denoise-control.patch
new file mode 100644
index 0000000000..6df7a0c49c
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1043-staging-vc04_services-ISP-Add-colour-denoise-control.patch
@@ -0,0 +1,75 @@
+From 29ec709794ac2aae569c8d486dd19a7d731cfeeb Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Thu, 14 Jan 2021 09:20:52 +0000
+Subject: [PATCH] staging: vc04_services: ISP: Add colour denoise
+ control
+
+Add colour denoise control to the bcm2835 driver through a new v4l2
+control: V4L2_CID_USER_BCM2835_ISP_CDN.
+
+Add the accompanying MMAL configuration structure definitions as well.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ .../vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c | 5 +++++
+ .../vc04_services/bcm2835-isp/bcm2835_isp_ctrls.h | 5 +++++
+ .../vc04_services/vchiq-mmal/mmal-parameters.h | 13 +++++++++++++
+ 3 files changed, 23 insertions(+)
+
+--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
+@@ -776,6 +776,11 @@ static int bcm2835_isp_s_ctrl(struct v4l
+ ctrl->p_new.p_u8,
+ sizeof(struct bcm2835_isp_denoise));
+ break;
++ case V4L2_CID_USER_BCM2835_ISP_CDN:
++ ret = set_isp_param(node, MMAL_PARAMETER_CDN,
++ ctrl->p_new.p_u8,
++ sizeof(struct bcm2835_isp_cdn));
++ break;
+ case V4L2_CID_USER_BCM2835_ISP_SHARPEN:
+ ret = set_isp_param(node, MMAL_PARAMETER_SHARPEN,
+ ctrl->p_new.p_u8,
+--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_ctrls.h
++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_ctrls.h
+@@ -57,6 +57,11 @@ static const struct bcm2835_isp_custom_c
+ .size = sizeof(struct bcm2835_isp_denoise),
+ .flags = 0
+ }, {
++ .name = "Colour Denoise",
++ .id = V4L2_CID_USER_BCM2835_ISP_CDN,
++ .size = sizeof(struct bcm2835_isp_cdn),
++ .flags = 0
++ }, {
+ .name = "Defective Pixel Correction",
+ .id = V4L2_CID_USER_BCM2835_ISP_DPC,
+ .size = sizeof(struct bcm2835_isp_dpc),
+--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
+@@ -277,6 +277,8 @@ enum mmal_parameter_camera_type {
+ MMAL_PARAMETER_DPC,
+ /**< Tales a @ref MMAP_PARAMETER_GAMMA_T */
+ MMAL_PARAMETER_GAMMA,
++ /**< Takes a @ref MMAL_PARAMETER_CDN_T */
++ MMAL_PARAMETER_CDN,
+ };
+
+ struct mmal_parameter_rational {
+@@ -910,6 +912,17 @@ struct mmal_parameter_gamma {
+ u16 y[MMAL_NUM_GAMMA_PTS];
+ };
+
++enum mmal_parameter_cdn_mode {
++ MMAL_PARAM_CDN_FAST = 0,
++ MMAL_PARAM_CDN_HIGH_QUALITY = 1,
++ MMAL_PARAM_CDN_DUMMY = 0x7FFFFFFF
++};
++
++struct mmal_parameter_colour_denoise {
++ u32 enabled;
++ enum mmal_parameter_cdn_mode mode;
++};
++
+ struct mmal_parameter_denoise {
+ u32 enabled;
+ u32 constant;
diff --git a/target/linux/bcm27xx/patches-5.4/950-1044-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-1044-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch
new file mode 100644
index 0000000000..24292fe13b
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1044-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch
@@ -0,0 +1,31 @@
+From 6f36a21e2a77b33eed45159a1556a4dd77422976 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 29 Jan 2021 10:34:11 +0000
+Subject: [PATCH] kbuild: Silence unavoidable dtc overlay warnings
+
+Much effort has been put into finding ways to avoid warnings from dtc
+about overlays, usually to do with the presence of #address-cells and
+size-cells, but not exclusively so. Since the issues being warned about
+are harmless, suppress the warnings to declutter the build output and
+to avoid alarming users.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ scripts/Makefile.lib | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/scripts/Makefile.lib
++++ b/scripts/Makefile.lib
+@@ -306,6 +306,12 @@ cmd_dtco = mkdir -p $(dir ${dtc-tmp}) ;
+ $(DTC) -@ -H epapr -O dtb -o $@ -b 0 \
+ -i $(dir $<) $(DTC_FLAGS) \
+ -Wno-interrupts_property \
++ -Wno-label_is_string \
++ -Wno-reg_format \
++ -Wno-pci_device_bus_num \
++ -Wno-i2c_bus_reg \
++ -Wno-spi_bus_reg \
++ -Wno-avoid_default_addr_size \
+ -d $(depfile).dtc.tmp $(dtc-tmp) ; \
+ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-1045-Adds-the-DT-overlays-to-support-Hifiberry-AMP100.patch b/target/linux/bcm27xx/patches-5.4/950-1045-Adds-the-DT-overlays-to-support-Hifiberry-AMP100.patch
new file mode 100644
index 0000000000..24ff1b3a34
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1045-Adds-the-DT-overlays-to-support-Hifiberry-AMP100.patch
@@ -0,0 +1,132 @@
+From d689ccf52fb81664b7eccb91dc05a93d64ba793c Mon Sep 17 00:00:00 2001
+From: Joerg Schambacher <joerg@i2audio.com>
+Date: Fri, 29 Jan 2021 08:26:44 +0100
+Subject: [PATCH] Adds the DT-overlays to support Hifiberry AMP100
+
+Adds new DT-overlay to control AMP100.
+
+Signed-off-by: Joerg Schambacher <joerg@hifiberry.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 30 ++++++++-
+ .../dts/overlays/hifiberry-amp100-overlay.dts | 64 +++++++++++++++++++
+ 3 files changed, 94 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm/boot/dts/overlays/hifiberry-amp100-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -60,6 +60,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ hd44780-lcd.dtbo \
+ hdmi-backlight-hwhack-gpio.dtbo \
+ hifiberry-amp.dtbo \
++ hifiberry-amp100.dtbo \
+ hifiberry-dac.dtbo \
+ hifiberry-dacplus.dtbo \
+ hifiberry-dacplusadc.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1045,8 +1045,36 @@ Load: dtoverlay=hifiberry-amp
+ Params: <None>
+
+
++Name: hifiberry-amp100
++Info: Configures the HifiBerry AMP100 audio card
++Load: dtoverlay=hifiberry-amp100,<param>=<val>
++Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec
++ Digital volume control. Enable with
++ "dtoverlay=hifiberry-amp100,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.
++ leds_off If set to 'true' the onboard indicator LEDs
++ are switched off at all times.
++ auto_mute If set to 'true' the amplifier is automatically
++ muted when the DAC is not playing.
++ mute_ext_ctl The amplifier's HW mute control is enabled
++ in ALSA mixer and set to <val>.
++ Will be overwritten by ALSA user settings.
++
++
+ Name: hifiberry-dac
+-Info: Configures the HifiBerry DAC audio card
++Info: Configures the HifiBerry DAC audio cards
+ Load: dtoverlay=hifiberry-dac
+ Params: <None>
+
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/hifiberry-amp100-overlay.dts
+@@ -0,0 +1,64 @@
++// Definitions for HiFiBerry AMP100
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2835";
++
++ fragment@0 {
++ target-path = "/";
++ __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";
++ mute-gpio = <&gpio 4 0>;
++ reset-gpio = <&gpio 17 0x11>;
++ };
++ };
++
++ __overrides__ {
++ 24db_digital_gain =
++ <&hifiberry_dacplus>,"hifiberry,24db_digital_gain?";
++ slave = <&hifiberry_dacplus>,"hifiberry-dacplus,slave?";
++ leds_off = <&hifiberry_dacplus>,"hifiberry-dacplus,leds_off?";
++ mute_ext_ctl = <&hifiberry_dacplus>,"hifiberry-dacplus,mute_ext_ctl:0";
++ auto_mute = <&hifiberry_dacplus>,"hifiberry-dacplus,auto_mute?";
++ };
++};
diff --git a/target/linux/bcm27xx/patches-5.4/950-1046-Enhances-the-Hifiberry-DAC-driver-for-Hifiberry-AMP1.patch b/target/linux/bcm27xx/patches-5.4/950-1046-Enhances-the-Hifiberry-DAC-driver-for-Hifiberry-AMP1.patch
new file mode 100644
index 0000000000..4e15285220
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1046-Enhances-the-Hifiberry-DAC-driver-for-Hifiberry-AMP1.patch
@@ -0,0 +1,238 @@
+From 0b584f3c2808dba8dc9e74a628b65008302804a5 Mon Sep 17 00:00:00 2001
+From: Joerg Schambacher <joerg@i2audio.com>
+Date: Fri, 29 Jan 2021 16:16:39 +0100
+Subject: [PATCH] Enhances the Hifiberry DAC+ driver for Hifiberry
+ AMP100 support
+
+Adds the necessary GPIO handling and ALSA mixer extensions.
+Also fixes a problem with the PLL/CLK control when switching sample rates.
+Thanks to Clive Messer for the support!
+
+Signed-off-by: Joerg Schambacher <joerg@hifiberry.com>
+---
+ sound/soc/bcm/hifiberry_dacplus.c | 124 ++++++++++++++++++++++++++----
+ 1 file changed, 111 insertions(+), 13 deletions(-)
+
+--- a/sound/soc/bcm/hifiberry_dacplus.c
++++ b/sound/soc/bcm/hifiberry_dacplus.c
+@@ -1,10 +1,10 @@
+ /*
+- * ASoC Driver for HiFiBerry DAC+ / DAC Pro
++ * ASoC Driver for HiFiBerry DAC+ / DAC Pro / AMP100
+ *
+ * Author: Daniel Matuschek, Stuart MacLean <stuart@hifiberry.com>
+ * Copyright 2014-2015
+ * based on code by Florian Meier <florian.meier@koalo.de>
+- * Headphone added by Joerg Schambacher, joerg@i2audio.com
++ * Headphone/AMP100 Joerg Schambacher <joerg@hifiberry.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+@@ -17,6 +17,8 @@
+ */
+
+ #include <linux/module.h>
++#include <linux/gpio/consumer.h>
++#include <../drivers/gpio/gpiolib.h>
+ #include <linux/platform_device.h>
+ #include <linux/kernel.h>
+ #include <linux/clk.h>
+@@ -53,6 +55,47 @@ static bool slave;
+ static bool snd_rpi_hifiberry_is_dacpro;
+ static bool digital_gain_0db_limit = true;
+ static bool leds_off;
++static bool auto_mute;
++static int mute_ext_ctl;
++static int mute_ext;
++static struct gpio_desc *snd_mute_gpio;
++static struct gpio_desc *snd_reset_gpio;
++static struct snd_soc_card snd_rpi_hifiberry_dacplus;
++
++static int snd_rpi_hifiberry_dacplus_mute_set(int mute)
++{
++ gpiod_set_value_cansleep(snd_mute_gpio, mute);
++ return 1;
++}
++
++static int snd_rpi_hifiberry_dacplus_mute_get(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ ucontrol->value.integer.value[0] = mute_ext;
++
++ return 0;
++}
++
++static int snd_rpi_hifiberry_dacplus_mute_put(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ if (mute_ext == ucontrol->value.integer.value[0])
++ return 0;
++
++ mute_ext = ucontrol->value.integer.value[0];
++
++ return snd_rpi_hifiberry_dacplus_mute_set(mute_ext);
++}
++
++static const char * const mute_text[] = {"Play", "Mute"};
++static const struct soc_enum hb_dacplus_opt_mute_enum =
++ SOC_ENUM_SINGLE_EXT(2, mute_text);
++
++static const struct snd_kcontrol_new hb_dacplus_opt_mute_controls[] = {
++ SOC_ENUM_EXT("Mute(ext)", hb_dacplus_opt_mute_enum,
++ snd_rpi_hifiberry_dacplus_mute_get,
++ snd_rpi_hifiberry_dacplus_mute_put),
++};
+
+ static void snd_rpi_hifiberry_dacplus_select_clk(struct snd_soc_component *component,
+ int clk_id)
+@@ -68,6 +111,7 @@ static void snd_rpi_hifiberry_dacplus_se
+ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x24, 0x04);
+ break;
+ }
++ usleep_range(2000, 2100);
+ }
+
+ static void snd_rpi_hifiberry_dacplus_clk_gpio(struct snd_soc_component *component)
+@@ -85,13 +129,6 @@ static bool snd_rpi_hifiberry_dacplus_is
+ return (!(sck & 0x40));
+ }
+
+-static bool snd_rpi_hifiberry_dacplus_is_sclk_sleep(
+- struct snd_soc_component *component)
+-{
+- msleep(2);
+- return snd_rpi_hifiberry_dacplus_is_sclk(component);
+-}
+-
+ static bool snd_rpi_hifiberry_dacplus_is_pro_card(struct snd_soc_component *component)
+ {
+ bool isClk44EN, isClk48En, isNoClk;
+@@ -99,13 +136,13 @@ static bool snd_rpi_hifiberry_dacplus_is
+ snd_rpi_hifiberry_dacplus_clk_gpio(component);
+
+ snd_rpi_hifiberry_dacplus_select_clk(component, HIFIBERRY_DACPRO_CLK44EN);
+- isClk44EN = snd_rpi_hifiberry_dacplus_is_sclk_sleep(component);
++ isClk44EN = snd_rpi_hifiberry_dacplus_is_sclk(component);
+
+ snd_rpi_hifiberry_dacplus_select_clk(component, HIFIBERRY_DACPRO_NOCLOCK);
+- isNoClk = snd_rpi_hifiberry_dacplus_is_sclk_sleep(component);
++ isNoClk = snd_rpi_hifiberry_dacplus_is_sclk(component);
+
+ snd_rpi_hifiberry_dacplus_select_clk(component, HIFIBERRY_DACPRO_CLK48EN);
+- isClk48En = snd_rpi_hifiberry_dacplus_is_sclk_sleep(component);
++ isClk48En = snd_rpi_hifiberry_dacplus_is_sclk(component);
+
+ return (isClk44EN && isClk48En && !isNoClk);
+ }
+@@ -149,6 +186,7 @@ static int snd_rpi_hifiberry_dacplus_ini
+ {
+ struct snd_soc_component *component = rtd->codec_dai->component;
+ struct pcm512x_priv *priv;
++ struct snd_soc_card *card = &snd_rpi_hifiberry_dacplus;
+
+ if (slave)
+ snd_rpi_hifiberry_is_dacpro = false;
+@@ -187,6 +225,20 @@ static int snd_rpi_hifiberry_dacplus_ini
+ if (ret < 0)
+ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret);
+ }
++ if (snd_reset_gpio) {
++ gpiod_set_value_cansleep(snd_reset_gpio, 0);
++ msleep(1);
++ gpiod_set_value_cansleep(snd_reset_gpio, 1);
++ msleep(1);
++ gpiod_set_value_cansleep(snd_reset_gpio, 0);
++ }
++
++ if (mute_ext_ctl)
++ snd_soc_add_card_controls(card, hb_dacplus_opt_mute_controls,
++ ARRAY_SIZE(hb_dacplus_opt_mute_controls));
++
++ if (snd_mute_gpio)
++ gpiod_set_value_cansleep(snd_mute_gpio, mute_ext);
+
+ return 0;
+ }
+@@ -254,6 +306,8 @@ static int snd_rpi_hifiberry_dacplus_sta
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_component *component = rtd->codec_dai->component;
+
++ if (auto_mute)
++ gpiod_set_value_cansleep(snd_mute_gpio, 0);
+ if (leds_off)
+ return 0;
+ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x08, 0x08);
+@@ -267,6 +321,8 @@ static void snd_rpi_hifiberry_dacplus_sh
+ struct snd_soc_component *component = rtd->codec_dai->component;
+
+ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x08, 0x00);
++ if (auto_mute)
++ gpiod_set_value_cansleep(snd_mute_gpio, 1);
+ }
+
+ /* machine stream operations */
+@@ -342,6 +398,8 @@ static int snd_rpi_hifiberry_dacplus_pro
+ struct device_node *tpa_node;
+ struct property *tpa_prop;
+ struct of_changeset ocs;
++ struct property *pp;
++ int tmp;
+
+ /* probe for head phone amp */
+ ret = hb_hp_detect();
+@@ -396,6 +454,39 @@ static int snd_rpi_hifiberry_dacplus_pro
+ "hifiberry-dacplus,slave");
+ leds_off = of_property_read_bool(pdev->dev.of_node,
+ "hifiberry-dacplus,leds_off");
++ auto_mute = of_property_read_bool(pdev->dev.of_node,
++ "hifiberry-dacplus,auto_mute");
++
++ /*
++ * check for HW MUTE as defined in DT-overlay
++ * active high, therefore default to HIGH to MUTE
++ */
++ snd_mute_gpio = devm_gpiod_get_optional(&pdev->dev,
++ "mute", GPIOD_OUT_HIGH);
++ if (IS_ERR(snd_mute_gpio)) {
++ dev_err(&pdev->dev, "Can't allocate GPIO (HW-MUTE)");
++ return PTR_ERR(snd_mute_gpio);
++ }
++
++ /* add ALSA control if requested in DT-overlay (AMP100) */
++ pp = of_find_property(pdev->dev.of_node,
++ "hifiberry-dacplus,mute_ext_ctl", &tmp);
++ if (pp) {
++ if (!of_property_read_u32(pdev->dev.of_node,
++ "hifiberry-dacplus,mute_ext_ctl", &mute_ext)) {
++ /* ALSA control will be used */
++ mute_ext_ctl = 1;
++ }
++ }
++
++ /* check for HW RESET (AMP100) */
++ snd_reset_gpio = devm_gpiod_get_optional(&pdev->dev,
++ "reset", GPIOD_OUT_HIGH);
++ if (IS_ERR(snd_reset_gpio)) {
++ dev_err(&pdev->dev, "Can't allocate GPIO (HW-RESET)");
++ return PTR_ERR(snd_reset_gpio);
++ }
++
+ }
+
+ ret = devm_snd_soc_register_card(&pdev->dev,
+@@ -403,7 +494,14 @@ static int snd_rpi_hifiberry_dacplus_pro
+ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "snd_soc_register_card() failed: %d\n", ret);
+-
++ if (!ret) {
++ if (snd_mute_gpio)
++ dev_info(&pdev->dev, "GPIO%i for HW-MUTE selected",
++ gpio_chip_hwgpio(snd_mute_gpio));
++ if (snd_reset_gpio)
++ dev_info(&pdev->dev, "GPIO%i for HW-RESET selected",
++ gpio_chip_hwgpio(snd_reset_gpio));
++ }
+ return ret;
+ }
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-1047-ARM-dts-Declare-Pi400-and-CM4-have-no-audio-pins.patch b/target/linux/bcm27xx/patches-5.4/950-1047-ARM-dts-Declare-Pi400-and-CM4-have-no-audio-pins.patch
new file mode 100644
index 0000000000..c7d7c66d44
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1047-ARM-dts-Declare-Pi400-and-CM4-have-no-audio-pins.patch
@@ -0,0 +1,41 @@
+From 747df57eabbe2e3b5bd47e268aa42658a57749ca Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 3 Feb 2021 16:23:43 +0000
+Subject: [PATCH] ARM: dts: Declare Pi400 and CM4 have no audio pins
+
+The audio_pins node is left as a placeholder for the audremap overlay,
+and it must have (empty) brcm,function and brcm,pins properties
+otherwise it will be rejected by the pinctrl driver.
+
+See: https://www.raspberrypi.org/forums/viewtopic.php?f=98&t=301891
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2711-rpi-400.dts | 4 ++--
+ arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 2 ++
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi-400.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-400.dts
+@@ -495,8 +495,8 @@
+
+ &gpio {
+ audio_pins: audio_pins {
+- brcm,pins = <40 41>;
+- brcm,function = <4>;
++ brcm,pins = <>;
++ brcm,function = <>;
+ };
+ };
+
+--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts
+@@ -434,6 +434,8 @@
+
+ &gpio {
+ audio_pins: audio_pins {
++ brcm,pins = <>;
++ brcm,function = <>;
+ };
+ };
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-1048-Hifiberry-DAC-ADC-Pro-fix-for-the-PLL-when-changing-.patch b/target/linux/bcm27xx/patches-5.4/950-1048-Hifiberry-DAC-ADC-Pro-fix-for-the-PLL-when-changing-.patch
new file mode 100644
index 0000000000..47ecb8b2ce
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-1048-Hifiberry-DAC-ADC-Pro-fix-for-the-PLL-when-changing-.patch
@@ -0,0 +1,56 @@
+From c70ae3d1923339746d156bd1d723d141113183aa Mon Sep 17 00:00:00 2001
+From: Joerg Schambacher <joerg@i2audio.com>
+Date: Mon, 1 Feb 2021 16:53:46 +0100
+Subject: [PATCH] Hifiberry DAC+ADC Pro fix for the PLL when changing
+ sample rates
+
+Adds 2 msecs delay when switching between oscillators to allow
+correct PLL settling.
+Thanks to Clive Messer for the support!
+
+Signed-off-by: Joerg Schambacher <joerg@hifiberry.com>
+---
+ sound/soc/bcm/hifiberry_dacplusadcpro.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+--- a/sound/soc/bcm/hifiberry_dacplusadcpro.c
++++ b/sound/soc/bcm/hifiberry_dacplusadcpro.c
+@@ -190,6 +190,7 @@ static void snd_rpi_hifiberry_dacplusadc
+ PCM512x_GPIO_CONTROL_1, 0x24, 0x04);
+ break;
+ }
++ usleep_range(2000, 2100);
+ }
+
+ static void snd_rpi_hifiberry_dacplusadcpro_clk_gpio(struct snd_soc_component *component)
+@@ -207,13 +208,6 @@ static bool snd_rpi_hifiberry_dacplusadc
+ return (!(sck & 0x40));
+ }
+
+-static bool snd_rpi_hifiberry_dacplusadcpro_is_sclk_sleep(
+- struct snd_soc_component *component)
+-{
+- msleep(2);
+- return snd_rpi_hifiberry_dacplusadcpro_is_sclk(component);
+-}
+-
+ static bool snd_rpi_hifiberry_dacplusadcpro_is_pro_card(struct snd_soc_component *component)
+ {
+ bool isClk44EN, isClk48En, isNoClk;
+@@ -221,13 +215,13 @@ static bool snd_rpi_hifiberry_dacplusadc
+ snd_rpi_hifiberry_dacplusadcpro_clk_gpio(component);
+
+ snd_rpi_hifiberry_dacplusadcpro_select_clk(component, HIFIBERRY_DACPRO_CLK44EN);
+- isClk44EN = snd_rpi_hifiberry_dacplusadcpro_is_sclk_sleep(component);
++ isClk44EN = snd_rpi_hifiberry_dacplusadcpro_is_sclk(component);
+
+ snd_rpi_hifiberry_dacplusadcpro_select_clk(component, HIFIBERRY_DACPRO_NOCLOCK);
+- isNoClk = snd_rpi_hifiberry_dacplusadcpro_is_sclk_sleep(component);
++ isNoClk = snd_rpi_hifiberry_dacplusadcpro_is_sclk(component);
+
+ snd_rpi_hifiberry_dacplusadcpro_select_clk(component, HIFIBERRY_DACPRO_CLK48EN);
+- isClk48En = snd_rpi_hifiberry_dacplusadcpro_is_sclk_sleep(component);
++ isClk48En = snd_rpi_hifiberry_dacplusadcpro_is_sclk(component);
+
+ return (isClk44EN && isClk48En && !isNoClk);
+ }