From 25475a095ec71f55826a5864e78e09c27031f179 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 8 Jan 2013 22:20:16 +0000 Subject: [PATCH] mvebu: add inital support for Marvell Armada XP/370 SoCs This brings in the initial support for the Marvell Armada XP/370 SoCs. Successfully tested on RD-A370-A1 and DB-MV784MP-GP boards the following interfaces: - Ethernet - SDIO - GPIOs - SATA Signed-off-by: Florian Fainelli SVN-Revision: 35058 --- target/linux/generic/config-3.8 | 1 + target/linux/mvebu/Makefile | 24 ++ target/linux/mvebu/config-default | 255 ++++++++++++++++++ target/linux/mvebu/image/Makefile | 51 ++++ ...bu_remove_inappropriate_init_tagging.patch | 28 ++ .../002-dma_mv_xor_fix_error_handling.patch | 38 +++ ...dma_mv_xor_fix_error_handling_clocks.patch | 35 +++ ...net_mvneta_fix_driver_operations_smp.patch | 75 ++++++ ...mvebu_use_global_interrupts_for_gpio.patch | 174 ++++++++++++ .../006-mmc_mvsdio_use_slot_gpio.patch | 101 +++++++ .../007-mmc_mvsdio_use_slot_gpio_for_cd.patch | 105 ++++++++ ...sdio_implement_a_device_tree_binding.patch | 169 ++++++++++++ .../009-mmc_mvsdio_add_pinctrl.patch | 48 ++++ .../010-arm_mvebu_add_dt_info_a370.patch | 30 +++ ...1-arm_mvebu_add_pin_mux_options_a370.patch | 38 +++ ...12-arm_mvebu_add_pin_mux_options_axp.patch | 69 +++++ ...arm_mvebu_enable_sd_cart_slot_axp_db.patch | 29 ++ ...rm_mvebu_enable_sd_card_slot_a370_db.patch | 46 ++++ ...rm_mvebu_enable_sd_card_slot_mirabox.patch | 31 +++ ...016-arm_cache_l2x0_aurora_invalidate.patch | 52 ++++ ...cache_l2x0_aurora_use_writel_relaxed.patch | 45 ++++ .../018-arm_mvebu_dw_apb_uart.patch | 88 ++++++ 22 files changed, 1532 insertions(+) create mode 100644 target/linux/mvebu/Makefile create mode 100644 target/linux/mvebu/config-default create mode 100644 target/linux/mvebu/image/Makefile create mode 100644 target/linux/mvebu/patches-3.8/001-clk_mvebu_remove_inappropriate_init_tagging.patch create mode 100644 target/linux/mvebu/patches-3.8/002-dma_mv_xor_fix_error_handling.patch create mode 100644 target/linux/mvebu/patches-3.8/003-dma_mv_xor_fix_error_handling_clocks.patch create mode 100644 target/linux/mvebu/patches-3.8/004-net_mvneta_fix_driver_operations_smp.patch create mode 100644 target/linux/mvebu/patches-3.8/005-arm_mvebu_use_global_interrupts_for_gpio.patch create mode 100644 target/linux/mvebu/patches-3.8/006-mmc_mvsdio_use_slot_gpio.patch create mode 100644 target/linux/mvebu/patches-3.8/007-mmc_mvsdio_use_slot_gpio_for_cd.patch create mode 100644 target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch create mode 100644 target/linux/mvebu/patches-3.8/009-mmc_mvsdio_add_pinctrl.patch create mode 100644 target/linux/mvebu/patches-3.8/010-arm_mvebu_add_dt_info_a370.patch create mode 100644 target/linux/mvebu/patches-3.8/011-arm_mvebu_add_pin_mux_options_a370.patch create mode 100644 target/linux/mvebu/patches-3.8/012-arm_mvebu_add_pin_mux_options_axp.patch create mode 100644 target/linux/mvebu/patches-3.8/013-arm_mvebu_enable_sd_cart_slot_axp_db.patch create mode 100644 target/linux/mvebu/patches-3.8/014-arm_mvebu_enable_sd_card_slot_a370_db.patch create mode 100644 target/linux/mvebu/patches-3.8/015-arm_mvebu_enable_sd_card_slot_mirabox.patch create mode 100644 target/linux/mvebu/patches-3.8/016-arm_cache_l2x0_aurora_invalidate.patch create mode 100644 target/linux/mvebu/patches-3.8/017-arm_cache_l2x0_aurora_use_writel_relaxed.patch create mode 100644 target/linux/mvebu/patches-3.8/018-arm_mvebu_dw_apb_uart.patch diff --git a/target/linux/generic/config-3.8 b/target/linux/generic/config-3.8 index f6b01b66d7..f45bb1f4af 100644 --- a/target/linux/generic/config-3.8 +++ b/target/linux/generic/config-3.8 @@ -1025,6 +1025,7 @@ CONFIG_HZ_100=y # CONFIG_I2C_ALI15X3 is not set # CONFIG_I2C_AMD756 is not set # CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_CBUS_GPIO is not set # CONFIG_I2C_CHARDEV is not set # CONFIG_I2C_COMPAT is not set # CONFIG_I2C_DEBUG_ALGO is not set diff --git a/target/linux/mvebu/Makefile b/target/linux/mvebu/Makefile new file mode 100644 index 0000000000..4ff5fe20a1 --- /dev/null +++ b/target/linux/mvebu/Makefile @@ -0,0 +1,24 @@ +# +# Copyright (C) 2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +ARCH:=arm +BOARD:=mvebu +BOARDNAME:=Marvell Armada XP/370 boards +FEATURES:=targz usb jffs2 pci pcie gpio +CFLAGS:=-Os -pipe -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp +MAINTAINER:=Florian Fainelli + +LINUX_VERSION:=3.8-rc2 + +include $(INCLUDE_DIR)/target.mk + +KERNELNAME:="zImage dtbs" + +DEFAULT_PACKAGES += + +$(eval $(call BuildTarget)) diff --git a/target/linux/mvebu/config-default b/target/linux/mvebu/config-default new file mode 100644 index 0000000000..e3b4b3a227 --- /dev/null +++ b/target/linux/mvebu/config-default @@ -0,0 +1,255 @@ +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_AMBA_PL08X is not set +# CONFIG_ARCH_BCM is not set +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_MULTIPLATFORM=y +# CONFIG_ARCH_MULTI_CPU_AUTO is not set +# CONFIG_ARCH_MULTI_V6 is not set +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_MVEBU=y +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_REQUIRE_GPIOLIB=y +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SUNXI is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_VEXPRESS=y +# CONFIG_ARCH_VEXPRESS_CA9X4 is not set +CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA=y +# CONFIG_ARCH_VT8500_SINGLE is not set +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_ARM=y +CONFIG_ARMADA_370_XP_TIMER=y +CONFIG_ARM_AMBA=y +CONFIG_ARM_APPENDED_DTB=y +# CONFIG_ARM_ATAG_DTB_COMPAT is not set +# CONFIG_ARM_CHARLCD is not set +# CONFIG_ARM_CPU_SUSPEND is not set +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +CONFIG_ARM_ERRATA_720789=y +# CONFIG_ARM_ERRATA_743622 is not set +CONFIG_ARM_ERRATA_751472=y +# CONFIG_ARM_ERRATA_754322 is not set +CONFIG_ARM_GIC=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_L1_CACHE_SHIFT_6=y +# CONFIG_ARM_LPAE is not set +CONFIG_ARM_NR_BANKS=8 +CONFIG_ARM_PATCH_PHYS_VIRT=y +# CONFIG_ARM_SP805_WATCHDOG is not set +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +CONFIG_ARM_TIMER_SP804=y +CONFIG_ASYNC_TX_DMA=y +CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y +CONFIG_ATAGS=y +CONFIG_AUTO_ZRELADDR=y +CONFIG_BOUNCE=y +CONFIG_CACHE_L2X0=y +CONFIG_CACHE_PL310=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_VERSATILE=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_HAS_ASID=y +# CONFIG_CPU_ICACHE_DISABLE is not set +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_PJ4B=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_LL_INCLUDE="debug/mvebu.S" +CONFIG_DEBUG_MVEBU_UART=y +# CONFIG_DEBUG_PINCTRL is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_VEXPRESS_UART0_CA9 is not set +# CONFIG_DEBUG_VEXPRESS_UART0_DETECT is not set +# CONFIG_DEBUG_VEXPRESS_UART0_RS1 is not set +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +CONFIG_DTC=y +# CONFIG_DW_DMAC is not set +CONFIG_EARLY_PRINTK=y +CONFIG_EXT2_FS=y +CONFIG_EXT3_FS=y +CONFIG_FAT_FS=y +CONFIG_FRAME_POINTER=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_IO=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_GENERIC=y +CONFIG_GPIO_MVEBU=y +CONFIG_GPIO_SYSFS=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAVE_AOUT=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_BPF_JIT=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DEBUG_KMEMLEAK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_GENERIC_HARDIRQS=y +CONFIG_HAVE_IRQ_WORK=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_NET_DSA=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_PATA_PLATFORM=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_SMP=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_UID16=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +CONFIG_ICST=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_ISO9660_FS=y +CONFIG_JBD=y +CONFIG_JUMP_LABEL=y +CONFIG_KTIME_SCALAR=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_MACH_ARMADA_370=y +CONFIG_MACH_ARMADA_370_XP=y +CONFIG_MACH_ARMADA_XP=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MDIO_BOARDINFO=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_MSDOS_FS=y +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_PHYSMAP_OF is not set +CONFIG_MULTI_IRQ_HANDLER=y +CONFIG_MVEBU_CLK_CORE=y +CONFIG_MVEBU_CLK_CPU=y +CONFIG_MVEBU_CLK_GATING=y +CONFIG_MVMDIO=y +CONFIG_MVNETA=y +CONFIG_MV_XOR=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +# CONFIG_NEON is not set +CONFIG_NET_DMA=y +CONFIG_NLS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +CONFIG_NLS_UTF8=y +CONFIG_NO_IOPORT=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_DEVICE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_MDIO=y +CONFIG_OF_MTD=y +CONFIG_OF_NET=y +CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PCI_SYSCALL is not set +CONFIG_PERCPU_RWSEM=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PHYLIB=y +CONFIG_PINCONF=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_ARMADA_370=y +CONFIG_PINCTRL_ARMADA_XP=y +# CONFIG_PINCTRL_EXYNOS4 is not set +CONFIG_PINCTRL_MVEBU=y +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_PINMUX=y +# CONFIG_PL310_ERRATA_588369 is not set +# CONFIG_PL310_ERRATA_727915 is not set +CONFIG_PL310_ERRATA_753970=y +# CONFIG_PL310_ERRATA_769419 is not set +# CONFIG_PL330_DMA is not set +CONFIG_PLAT_ORION=y +CONFIG_PLAT_VERSATILE=y +CONFIG_PLAT_VERSATILE_CLCD=y +CONFIG_PLAT_VERSATILE_SCHED_CLOCK=y +# CONFIG_PREEMPT_RCU is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_8250_DW=y +CONFIG_SPARSE_IRQ=y +# CONFIG_SWP_EMULATE is not set +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_THUMB2_KERNEL is not set +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_STATS=y +CONFIG_UDF_FS=m +CONFIG_UID16=y +CONFIG_UIDGID_CONVERTED=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_XHCI is not set +CONFIG_USE_OF=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_VEXPRESS_CONFIG=y +CONFIG_VFAT_FS=y +CONFIG_VFP=y +CONFIG_VFPv3=y +# CONFIG_XEN is not set +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/mvebu/image/Makefile b/target/linux/mvebu/image/Makefile new file mode 100644 index 0000000000..44596beee4 --- /dev/null +++ b/target/linux/mvebu/image/Makefile @@ -0,0 +1,51 @@ +# +# Copyright (C) 2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/image.mk + +TARGET_DTBS := armada-xp-db armada-370-db armada-xp-openblocks-ax3-4 armada-370-mirabox + +LOADADDR:=0x00008000 + +JFFS2_BLOCKSIZE = 128k + +UIMAGE:=$(BIN_DIR)/$(IMG_PREFIX)-uImage +ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y) + UIMAGE:=$(BIN_DIR)/$(IMG_PREFIX)-uImage-initramfs +endif + +define Image/Build/MkuImage + mkimage -A arm -O linux -T kernel -a $(LOADADDR) -C none -e $(LOADADDR) \ + -n 'ARM OpenWrt Linux-$(LINUX_VERSION)' -d $(1) $(2); +endef + +define Image/Build/DTB + cp $(KDIR)/zImage $(KDIR)/zImage-$(1); + cat $(LINUX_DIR)/arch/$(ARCH)/boot/dts/$(1).dtb >> $(KDIR)/zImage-$(1); + $(call Image/Build/MkuImage,$(KDIR)/zImage-$(1),$(KDIR)/uImage-$(1)) + cp $(KDIR)/uImage-$(1) $(UIMAGE)-$(1); +endef + +define Image/Prepare + cp $(LINUX_DIR)/arch/$(ARCH)/boot/zImage $(KDIR)/zImage +endef + +define Image/BuildKernel + $(foreach dtb,$(TARGET_DTBS),$(call Image/Build/DTB,$(dtb))) + $(call Image/Build/Initramfs) +endef + +define Image/Build/squashfs + $(STAGING_DIR_HOST)/bin/padjffs2 $(KDIR)/root.squashfs 128 +endef + +define Image/Build + $(call Image/Build/$(1)) + dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-root.$(1) bs=128k conv=sync +endef + +$(eval $(call BuildImage)) diff --git a/target/linux/mvebu/patches-3.8/001-clk_mvebu_remove_inappropriate_init_tagging.patch b/target/linux/mvebu/patches-3.8/001-clk_mvebu_remove_inappropriate_init_tagging.patch new file mode 100644 index 0000000000..33787f266b --- /dev/null +++ b/target/linux/mvebu/patches-3.8/001-clk_mvebu_remove_inappropriate_init_tagging.patch @@ -0,0 +1,28 @@ +From: Joshua Coombs + +If the Orion WDT driver is built as a module, an opps occurs during +clk lookup when calling mvebu_clk_gating_get_src(). Remove the +inappropriate __init tag so the function is available for modules +after kernel init. + +Signed-off-by: Joshua Coombs +Signed-off-by: Andrew Lunn +--- + drivers/clk/mvebu/clk-gating-ctrl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/mvebu/clk-gating-ctrl.c b/drivers/clk/mvebu/clk-gating-ctrl.c +index c6d3c26..8fa5408 100644 +--- a/drivers/clk/mvebu/clk-gating-ctrl.c ++++ b/drivers/clk/mvebu/clk-gating-ctrl.c +@@ -32,7 +32,7 @@ struct mvebu_soc_descr { + + #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) + +-static struct clk __init *mvebu_clk_gating_get_src( ++static struct clk *mvebu_clk_gating_get_src( + struct of_phandle_args *clkspec, void *data) + { + struct mvebu_gating_ctrl *ctrl = (struct mvebu_gating_ctrl *)data; +-- +1.7.10.4 diff --git a/target/linux/mvebu/patches-3.8/002-dma_mv_xor_fix_error_handling.patch b/target/linux/mvebu/patches-3.8/002-dma_mv_xor_fix_error_handling.patch new file mode 100644 index 0000000000..f5940fbb1d --- /dev/null +++ b/target/linux/mvebu/patches-3.8/002-dma_mv_xor_fix_error_handling.patch @@ -0,0 +1,38 @@ +From: Thomas Petazzoni + +When mv_xor_channel_add() fails for one XOR channel, we jump to the +err_channel_add label to clean up all previous channels that had been +initialized correctly. Unfortunately, while handling this error +condition, we were disposing the IRQ mapping before calling +mv_xor_channel_remove() (which does the free_irq()), which is +incorrect. + +Instead, do things properly in the reverse order of the +initialization: first remove the XOR channel (so that free_irq() is +done), and then dispose the IRQ mapping. + +This avoids ugly warnings when for some reason one of the XOR channel +fails to initialize. + +Signed-off-by: Thomas Petazzoni +--- + drivers/dma/mv_xor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c +index ac71f55..cc5d23d 100644 +--- a/drivers/dma/mv_xor.c ++++ b/drivers/dma/mv_xor.c +@@ -1361,9 +1361,9 @@ static int mv_xor_probe(struct platform_device *pdev) + err_channel_add: + for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) + if (xordev->channels[i]) { ++ mv_xor_channel_remove(xordev->channels[i]); + if (pdev->dev.of_node) + irq_dispose_mapping(xordev->channels[i]->irq); +- mv_xor_channel_remove(xordev->channels[i]); + } + + clk_disable_unprepare(xordev->clk); +-- +1.7.10.4 diff --git a/target/linux/mvebu/patches-3.8/003-dma_mv_xor_fix_error_handling_clocks.patch b/target/linux/mvebu/patches-3.8/003-dma_mv_xor_fix_error_handling_clocks.patch new file mode 100644 index 0000000000..9bee8acded --- /dev/null +++ b/target/linux/mvebu/patches-3.8/003-dma_mv_xor_fix_error_handling_clocks.patch @@ -0,0 +1,35 @@ +From: Thomas Petazzoni + +When a channel fails to initialize, we release all ressources, +including clocks. However, a XOR unit is not necessarily associated to +a clock (some variants of Marvell SoCs have a clock for XOR units, +some don't), so we shouldn't unconditionally be releasing the clock. + +Instead, just like we do in the mv_xor_remove() function, we should +check if one clock was found before releasing it. + +Signed-off-by: Thomas Petazzoni +--- + drivers/dma/mv_xor.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c +index cc5d23d..e17fad0 100644 +--- a/drivers/dma/mv_xor.c ++++ b/drivers/dma/mv_xor.c +@@ -1366,8 +1366,11 @@ err_channel_add: + irq_dispose_mapping(xordev->channels[i]->irq); + } + +- clk_disable_unprepare(xordev->clk); +- clk_put(xordev->clk); ++ if (!IS_ERR(xordev->clk)) { ++ clk_disable_unprepare(xordev->clk); ++ clk_put(xordev->clk); ++ } ++ + return ret; + } + +-- +1.7.10.4 diff --git a/target/linux/mvebu/patches-3.8/004-net_mvneta_fix_driver_operations_smp.patch b/target/linux/mvebu/patches-3.8/004-net_mvneta_fix_driver_operations_smp.patch new file mode 100644 index 0000000000..c7e992fc4f --- /dev/null +++ b/target/linux/mvebu/patches-3.8/004-net_mvneta_fix_driver_operations_smp.patch @@ -0,0 +1,75 @@ +From: Dmitri Epshtein + +In order for the driver to behave properly in a SMP context, the same +transmit queue should be used by the kernel in dev_queue_xmit() and in +the driver's mvneta_tx() function. To achieve that, the driver now +implements the ->ndo_select_txq() operation. + +For now, it always returns the same transmit queue, txq_def, until the +driver is expanded to properly take advantage of the multiqueue +capabilities of the hardware. + +Without this patch, the network driver crashes the kernel almost +immediately on Armada XP platforms, if the network load is at least a +little bit parallel (i.e several threads). + +[Thomas Petazzoni: reword commit message] +Signed-off-by: Dmitri Epshtein +Signed-off-by: Thomas Petazzoni +--- +This is 3.8-rc material. +--- + drivers/net/ethernet/marvell/mvneta.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c +index b6025c3..af2c421 100644 +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -1310,6 +1310,17 @@ static u32 mvneta_skb_tx_csum(struct mvneta_port *pp, struct sk_buff *skb) + return MVNETA_TX_L4_CSUM_NOT; + } + ++static u16 mvneta_tx_policy(struct mvneta_port *pp, struct sk_buff *skb) ++{ ++ return (u16)txq_def; ++} ++ ++static u16 mvneta_select_txq(struct net_device *dev, struct sk_buff *skb) ++{ ++ struct mvneta_port *pp = netdev_priv(dev); ++ return mvneta_tx_policy(pp, skb); ++} ++ + /* Returns rx queue pointer (find last set bit) according to causeRxTx + * value + */ +@@ -1476,7 +1487,8 @@ error: + static int mvneta_tx(struct sk_buff *skb, struct net_device *dev) + { + struct mvneta_port *pp = netdev_priv(dev); +- struct mvneta_tx_queue *txq = &pp->txqs[txq_def]; ++ u16 txq_id = mvneta_tx_policy(pp, skb); ++ struct mvneta_tx_queue *txq = &pp->txqs[txq_id]; + struct mvneta_tx_desc *tx_desc; + struct netdev_queue *nq; + int frags = 0; +@@ -1486,7 +1498,7 @@ static int mvneta_tx(struct sk_buff *skb, struct net_device *dev) + goto out; + + frags = skb_shinfo(skb)->nr_frags + 1; +- nq = netdev_get_tx_queue(dev, txq_def); ++ nq = netdev_get_tx_queue(dev, txq_id); + + /* Get a descriptor for the first part of the packet */ + tx_desc = mvneta_txq_next_desc_get(txq); +@@ -2550,6 +2562,7 @@ static const struct net_device_ops mvneta_netdev_ops = { + .ndo_change_mtu = mvneta_change_mtu, + .ndo_tx_timeout = mvneta_tx_timeout, + .ndo_get_stats64 = mvneta_get_stats64, ++ .ndo_select_queue = mvneta_select_txq, + }; + + const struct ethtool_ops mvneta_eth_tool_ops = { +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/005-arm_mvebu_use_global_interrupts_for_gpio.patch b/target/linux/mvebu/patches-3.8/005-arm_mvebu_use_global_interrupts_for_gpio.patch new file mode 100644 index 0000000000..726e2529fc --- /dev/null +++ b/target/linux/mvebu/patches-3.8/005-arm_mvebu_use_global_interrupts_for_gpio.patch @@ -0,0 +1,174 @@ +The Armada XP GPIO controller has two ways of notifying interrupts: +using global interrupts or using per-CPU interrupts. In an attempt to +use the best available features, the 'marvell,armadaxp-gpio' +compatible string selects a variant of the gpio-mvebu driver that +makes use of the per-CPU interrupts. + +Unfortunately, this doesn't work properly in a SMP context, because we +fall into cases where the GPIO interrupt is enabled on CPU X at the +GPIO controller level, but on CPU Y at the interrupt controller +level. It is not yet clear how to fix that easily. + +So for 3.8, our approach is to switch to global interrupts for GPIOs, +so that we do not fall into this per-CPU interrupts problem. + +This patch therefore fixes GPIO interrupts on Armada XP +platforms. Without this patch, GPIO interrupts simply do not work +reliably, because their proper operation depends on which CPU the code +requesting the interrupt is running. + +Signed-off-by: Thomas Petazzoni +--- +This is 3.8-rc material. +--- + arch/arm/boot/dts/armada-xp-mv78230.dtsi | 14 ++++++-------- + arch/arm/boot/dts/armada-xp-mv78260.dtsi | 21 +++++++++------------ + arch/arm/boot/dts/armada-xp-mv78460.dtsi | 21 +++++++++------------ + 3 files changed, 24 insertions(+), 32 deletions(-) + +diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi +index 271855a..e041f42 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi +@@ -50,27 +50,25 @@ + }; + + gpio0: gpio@d0018100 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018100 0x40>, +- <0xd0018800 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018100 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <16>, <17>, <18>, <19>; ++ interrupts = <82>, <83>, <84>, <85>; + }; + + gpio1: gpio@d0018140 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018140 0x40>, +- <0xd0018840 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018140 0x40>; + ngpios = <17>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <20>, <21>, <22>; ++ interrupts = <87>, <88>, <89>; + }; + }; + }; +diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi +index 1c1937d..9e23bd8 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi +@@ -51,39 +51,36 @@ + }; + + gpio0: gpio@d0018100 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018100 0x40>, +- <0xd0018800 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018100 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <16>, <17>, <18>, <19>; ++ interrupts = <82>, <83>, <84>, <85>; + }; + + gpio1: gpio@d0018140 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018140 0x40>, +- <0xd0018840 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018140 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <20>, <21>, <22>, <23>; ++ interrupts = <87>, <88>, <89>, <90>; + }; + + gpio2: gpio@d0018180 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018180 0x40>, +- <0xd0018870 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018180 0x40>; + ngpios = <3>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <24>; ++ interrupts = <91>; + }; + + ethernet@d0034000 { +diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi +index 4905cf3..9659661 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi +@@ -66,39 +66,36 @@ + }; + + gpio0: gpio@d0018100 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018100 0x40>, +- <0xd0018800 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018100 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <16>, <17>, <18>, <19>; ++ interrupts = <82>, <83>, <84>, <85>; + }; + + gpio1: gpio@d0018140 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018140 0x40>, +- <0xd0018840 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018140 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <20>, <21>, <22>, <23>; ++ interrupts = <87>, <88>, <89>, <90>; + }; + + gpio2: gpio@d0018180 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018180 0x40>, +- <0xd0018870 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018180 0x40>; + ngpios = <3>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <24>; ++ interrupts = <91>; + }; + + ethernet@d0034000 { +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/006-mmc_mvsdio_use_slot_gpio.patch b/target/linux/mvebu/patches-3.8/006-mmc_mvsdio_use_slot_gpio.patch new file mode 100644 index 0000000000..8a77de3068 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/006-mmc_mvsdio_use_slot_gpio.patch @@ -0,0 +1,101 @@ +The MMC core subsystem provides in drivers/mmc/core/slot-gpio.c a nice +set of helper functions to simplify the management of the write +protect GPIO in MMC host drivers. This patch migrates the mvsdio +driver to using those helpers, which will make the ->probe() code +simpler, and therefore ease the process of adding a Device Tree +binding for this driver. + +Signed-off-by: Thomas Petazzoni +--- + drivers/mmc/host/mvsdio.c | 34 +++++----------------------------- + 1 file changed, 5 insertions(+), 29 deletions(-) + +diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c +index de4c20b..a24a22f 100644 +--- a/drivers/mmc/host/mvsdio.c ++++ b/drivers/mmc/host/mvsdio.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -54,7 +55,6 @@ struct mvsd_host { + int irq; + struct clk *clk; + int gpio_card_detect; +- int gpio_write_protect; + }; + + #define mvsd_write(offs, val) writel(val, iobase + (offs)) +@@ -566,20 +566,6 @@ static void mvsd_enable_sdio_irq(struct mmc_host *mmc, int enable) + spin_unlock_irqrestore(&host->lock, flags); + } + +-static int mvsd_get_ro(struct mmc_host *mmc) +-{ +- struct mvsd_host *host = mmc_priv(mmc); +- +- if (host->gpio_write_protect) +- return gpio_get_value(host->gpio_write_protect); +- +- /* +- * Board doesn't support read only detection; let the mmc core +- * decide what to do. +- */ +- return -ENOSYS; +-} +- + static void mvsd_power_up(struct mvsd_host *host) + { + void __iomem *iobase = host->base; +@@ -676,7 +662,7 @@ static void mvsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + + static const struct mmc_host_ops mvsd_ops = { + .request = mvsd_request, +- .get_ro = mvsd_get_ro, ++ .get_ro = mmc_gpio_get_ro, + .set_ios = mvsd_set_ios, + .enable_sdio_irq = mvsd_enable_sdio_irq, + }; +@@ -798,15 +784,7 @@ static int __init mvsd_probe(struct platform_device *pdev) + if (!host->gpio_card_detect) + mmc->caps |= MMC_CAP_NEEDS_POLL; + +- if (mvsd_data->gpio_write_protect) { +- ret = gpio_request(mvsd_data->gpio_write_protect, +- DRIVER_NAME " wp"); +- if (ret == 0) { +- gpio_direction_input(mvsd_data->gpio_write_protect); +- host->gpio_write_protect = +- mvsd_data->gpio_write_protect; +- } +- } ++ mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect); + + setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host); + platform_set_drvdata(pdev, mmc); +@@ -831,8 +809,7 @@ out: + free_irq(gpio_to_irq(host->gpio_card_detect), host); + gpio_free(host->gpio_card_detect); + } +- if (host->gpio_write_protect) +- gpio_free(host->gpio_write_protect); ++ mmc_gpio_free_ro(mmc); + if (host->base) + iounmap(host->base); + } +@@ -861,8 +838,7 @@ static int __exit mvsd_remove(struct platform_device *pdev) + } + mmc_remove_host(mmc); + free_irq(host->irq, host); +- if (host->gpio_write_protect) +- gpio_free(host->gpio_write_protect); ++ mmc_gpio_free_ro(mmc); + del_timer_sync(&host->timer); + mvsd_power_down(host); + iounmap(host->base); +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/007-mmc_mvsdio_use_slot_gpio_for_cd.patch b/target/linux/mvebu/patches-3.8/007-mmc_mvsdio_use_slot_gpio_for_cd.patch new file mode 100644 index 0000000000..287dedf1d9 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/007-mmc_mvsdio_use_slot_gpio_for_cd.patch @@ -0,0 +1,105 @@ +The MMC core subsystem provides in drivers/mmc/core/slot-gpio.c a nice +set of helper functions to simplify the management of the card detect +GPIO in MMC host drivers. This patch migrates the mvsdio driver to +using those helpers, which will make the ->probe() code simpler, and +therefore ease the process of adding a Device Tree binding for this +driver. + +Signed-off-by: Thomas Petazzoni +--- + drivers/mmc/host/mvsdio.c | 44 +++++++++----------------------------------- + 1 file changed, 9 insertions(+), 35 deletions(-) + +diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c +index a24a22f..baf19fc 100644 +--- a/drivers/mmc/host/mvsdio.c ++++ b/drivers/mmc/host/mvsdio.c +@@ -54,7 +54,6 @@ struct mvsd_host { + struct resource *res; + int irq; + struct clk *clk; +- int gpio_card_detect; + }; + + #define mvsd_write(offs, val) writel(val, iobase + (offs)) +@@ -540,13 +539,6 @@ static void mvsd_timeout_timer(unsigned long data) + mmc_request_done(host->mmc, mrq); + } + +-static irqreturn_t mvsd_card_detect_irq(int irq, void *dev) +-{ +- struct mvsd_host *host = dev; +- mmc_detect_change(host->mmc, msecs_to_jiffies(100)); +- return IRQ_HANDLED; +-} +- + static void mvsd_enable_sdio_irq(struct mmc_host *mmc, int enable) + { + struct mvsd_host *host = mmc_priv(mmc); +@@ -765,23 +757,11 @@ static int __init mvsd_probe(struct platform_device *pdev) + clk_prepare_enable(host->clk); + } + +- if (mvsd_data->gpio_card_detect) { +- ret = gpio_request(mvsd_data->gpio_card_detect, +- DRIVER_NAME " cd"); +- if (ret == 0) { +- gpio_direction_input(mvsd_data->gpio_card_detect); +- irq = gpio_to_irq(mvsd_data->gpio_card_detect); +- ret = request_irq(irq, mvsd_card_detect_irq, +- IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING, +- DRIVER_NAME " cd", host); +- if (ret == 0) +- host->gpio_card_detect = +- mvsd_data->gpio_card_detect; +- else +- gpio_free(mvsd_data->gpio_card_detect); +- } +- } +- if (!host->gpio_card_detect) ++ if (gpio_is_valid(mvsd_data->gpio_card_detect)) { ++ ret = mmc_gpio_request_cd(mmc, mvsd_data->gpio_card_detect); ++ if (ret) ++ goto out; ++ } else + mmc->caps |= MMC_CAP_NEEDS_POLL; + + mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect); +@@ -794,9 +774,9 @@ static int __init mvsd_probe(struct platform_device *pdev) + + pr_notice("%s: %s driver initialized, ", + mmc_hostname(mmc), DRIVER_NAME); +- if (host->gpio_card_detect) ++ if (!(mmc->caps & MMC_CAP_NEEDS_POLL)) + printk("using GPIO %d for card detection\n", +- host->gpio_card_detect); ++ mvsd_data->gpio_card_detect); + else + printk("lacking card detect (fall back to polling)\n"); + return 0; +@@ -805,10 +785,7 @@ out: + if (host) { + if (host->irq) + free_irq(host->irq, host); +- if (host->gpio_card_detect) { +- free_irq(gpio_to_irq(host->gpio_card_detect), host); +- gpio_free(host->gpio_card_detect); +- } ++ mmc_gpio_free_cd(mmc); + mmc_gpio_free_ro(mmc); + if (host->base) + iounmap(host->base); +@@ -832,10 +809,7 @@ static int __exit mvsd_remove(struct platform_device *pdev) + if (mmc) { + struct mvsd_host *host = mmc_priv(mmc); + +- if (host->gpio_card_detect) { +- free_irq(gpio_to_irq(host->gpio_card_detect), host); +- gpio_free(host->gpio_card_detect); +- } ++ mmc_gpio_free_cd(mmc); + mmc_remove_host(mmc); + free_irq(host->irq, host); + mmc_gpio_free_ro(mmc); +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch b/target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch new file mode 100644 index 0000000000..4f8cc2011f --- /dev/null +++ b/target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch @@ -0,0 +1,169 @@ +This patch adds a simple Device Tree binding for the mvsdio driver, as +well as the necessary documentation for it. Compatibility with non-DT +platforms is preserved, by keeping the platform_data based +initialization. + +We introduce a small difference between non-DT and DT platforms: DT +platforms are required to provide a clocks = <...> property, which the +driver uses to get the frequency of the clock that goes to the SDIO +IP. The behaviour on non-DT platforms is kept unchanged: a clock +reference is not mandatory, but the clock frequency must be passed in +the "clock" field of the mvsdio_platform_data structure. + +Signed-off-by: Thomas Petazzoni +--- + .../devicetree/bindings/mmc/orion-sdio.txt | 17 ++++++ + drivers/mmc/host/mvsdio.c | 60 +++++++++++++++----- + 2 files changed, 62 insertions(+), 15 deletions(-) + create mode 100644 Documentation/devicetree/bindings/mmc/orion-sdio.txt + +diff --git a/Documentation/devicetree/bindings/mmc/orion-sdio.txt b/Documentation/devicetree/bindings/mmc/orion-sdio.txt +new file mode 100644 +index 0000000..84f0ebd +--- /dev/null ++++ b/Documentation/devicetree/bindings/mmc/orion-sdio.txt +@@ -0,0 +1,17 @@ ++* Marvell orion-sdio controller ++ ++This file documents differences between the core properties in mmc.txt ++and the properties used by the orion-sdio driver. ++ ++- compatible: Should be "marvell,orion-sdio" ++- clocks: reference to the clock of the SDIO interface ++ ++Example: ++ ++ mvsdio@d00d4000 { ++ compatible = "marvell,orion-sdio"; ++ reg = <0xd00d4000 0x200>; ++ interrupts = <54>; ++ clocks = <&gateclk 17>; ++ status = "disabled"; ++ }; +diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c +index baf19fc..56954bc 100644 +--- a/drivers/mmc/host/mvsdio.c ++++ b/drivers/mmc/host/mvsdio.c +@@ -21,6 +21,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + +@@ -683,17 +685,17 @@ mv_conf_mbus_windows(struct mvsd_host *host, + + static int __init mvsd_probe(struct platform_device *pdev) + { ++ struct device_node *np = pdev->dev.of_node; + struct mmc_host *mmc = NULL; + struct mvsd_host *host = NULL; +- const struct mvsdio_platform_data *mvsd_data; + const struct mbus_dram_target_info *dram; + struct resource *r; + int ret, irq; ++ int gpio_card_detect, gpio_write_protect; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); +- mvsd_data = pdev->dev.platform_data; +- if (!r || irq < 0 || !mvsd_data) ++ if (!r || irq < 0) + return -ENXIO; + + r = request_mem_region(r->start, SZ_1K, DRIVER_NAME); +@@ -710,7 +712,35 @@ static int __init mvsd_probe(struct platform_device *pdev) + host->mmc = mmc; + host->dev = &pdev->dev; + host->res = r; +- host->base_clock = mvsd_data->clock / 2; ++ ++ /* Some non-DT platforms do not pass a clock, and the clock ++ frequency is passed through platform_data. On DT platforms, ++ a clock must always be passed, even if there is no gatable ++ clock associated to the SDIO interface (it can simply be a ++ fixed rate clock). */ ++ host->clk = clk_get(&pdev->dev, NULL); ++ if (!IS_ERR(host->clk)) ++ clk_prepare_enable(host->clk); ++ ++ if (np) { ++ if (IS_ERR(host->clk)) { ++ dev_err(&pdev->dev, "DT platforms must have a clock associated\n"); ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ host->base_clock = clk_get_rate(host->clk) / 2; ++ gpio_card_detect = of_get_named_gpio(np, "cd-gpios", 0); ++ gpio_write_protect = of_get_named_gpio(np, "wp-gpios", 0); ++ } else { ++ const struct mvsdio_platform_data *mvsd_data; ++ mvsd_data = pdev->dev.platform_data; ++ if (!mvsd_data) ++ return -ENXIO; ++ host->base_clock = mvsd_data->clock / 2; ++ gpio_card_detect = mvsd_data->gpio_card_detect; ++ gpio_write_protect = mvsd_data->gpio_write_protect; ++ } + + mmc->ops = &mvsd_ops; + +@@ -750,21 +780,14 @@ static int __init mvsd_probe(struct platform_device *pdev) + } else + host->irq = irq; + +- /* Not all platforms can gate the clock, so it is not +- an error if the clock does not exists. */ +- host->clk = clk_get(&pdev->dev, NULL); +- if (!IS_ERR(host->clk)) { +- clk_prepare_enable(host->clk); +- } +- +- if (gpio_is_valid(mvsd_data->gpio_card_detect)) { +- ret = mmc_gpio_request_cd(mmc, mvsd_data->gpio_card_detect); ++ if (gpio_is_valid(gpio_card_detect)) { ++ ret = mmc_gpio_request_cd(mmc, gpio_card_detect); + if (ret) + goto out; + } else + mmc->caps |= MMC_CAP_NEEDS_POLL; + +- mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect); ++ mmc_gpio_request_ro(mmc, gpio_write_protect); + + setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host); + platform_set_drvdata(pdev, mmc); +@@ -776,7 +799,7 @@ static int __init mvsd_probe(struct platform_device *pdev) + mmc_hostname(mmc), DRIVER_NAME); + if (!(mmc->caps & MMC_CAP_NEEDS_POLL)) + printk("using GPIO %d for card detection\n", +- mvsd_data->gpio_card_detect); ++ gpio_card_detect); + else + printk("lacking card detect (fall back to polling)\n"); + return 0; +@@ -855,12 +878,19 @@ static int mvsd_resume(struct platform_device *dev) + #define mvsd_resume NULL + #endif + ++static const struct of_device_id mvsdio_dt_ids[] = { ++ { .compatible = "marvell,orion-sdio" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, mvsdio_dt_ids); ++ + static struct platform_driver mvsd_driver = { + .remove = __exit_p(mvsd_remove), + .suspend = mvsd_suspend, + .resume = mvsd_resume, + .driver = { + .name = DRIVER_NAME, ++ .of_match_table = mvsdio_dt_ids, + }, + }; + +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/009-mmc_mvsdio_add_pinctrl.patch b/target/linux/mvebu/patches-3.8/009-mmc_mvsdio_add_pinctrl.patch new file mode 100644 index 0000000000..394fc4ceba --- /dev/null +++ b/target/linux/mvebu/patches-3.8/009-mmc_mvsdio_add_pinctrl.patch @@ -0,0 +1,48 @@ +On many Marvell SoCs, the pins used for the SDIO interface are part of +the MPP pins, that are muxable pins. In order to get the muxing of +those pins correct, this commit integrates the mvsdio driver with the +pinctrl infrastructure by calling devm_pinctrl_get_select_default() +during ->probe(). + +Note that we permit this function to fail because not all Marvell +platforms have yet been fully converted to using the pinctrl +infrastructure. + +Signed-off-by: Thomas Petazzoni +--- + drivers/mmc/host/mvsdio.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c +index 56954bc..feb16bd 100644 +--- a/drivers/mmc/host/mvsdio.c ++++ b/drivers/mmc/host/mvsdio.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -692,6 +693,7 @@ static int __init mvsd_probe(struct platform_device *pdev) + struct resource *r; + int ret, irq; + int gpio_card_detect, gpio_write_protect; ++ struct pinctrl *pinctrl; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); +@@ -713,6 +715,10 @@ static int __init mvsd_probe(struct platform_device *pdev) + host->dev = &pdev->dev; + host->res = r; + ++ pinctrl = devm_pinctrl_get_select_default(&pdev->dev); ++ if (IS_ERR(pinctrl)) ++ dev_warn(&pdev->dev, "no pins associated\n"); ++ + /* Some non-DT platforms do not pass a clock, and the clock + frequency is passed through platform_data. On DT platforms, + a clock must always be passed, even if there is no gatable +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/010-arm_mvebu_add_dt_info_a370.patch b/target/linux/mvebu/patches-3.8/010-arm_mvebu_add_dt_info_a370.patch new file mode 100644 index 0000000000..36e5ea2a22 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/010-arm_mvebu_add_dt_info_a370.patch @@ -0,0 +1,30 @@ +Now that the mvsdio MMC driver has a Device Tree binding, we add the +Device Tree informations to describe the SDIO interface available in +the Armada 370/XP SoCs. + +Signed-off-by: Thomas Petazzoni +--- + arch/arm/boot/dts/armada-370-xp.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi +index cf6c48a..41a5b11 100644 +--- a/arch/arm/boot/dts/armada-370-xp.dtsi ++++ b/arch/arm/boot/dts/armada-370-xp.dtsi +@@ -129,6 +129,14 @@ + clocks = <&coreclk 0>; + status = "disabled"; + }; ++ ++ mvsdio@d00d4000 { ++ compatible = "marvell,orion-sdio"; ++ reg = <0xd00d4000 0x200>; ++ interrupts = <54>; ++ clocks = <&gateclk 17>; ++ status = "disabled"; ++ }; + }; + }; + +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/011-arm_mvebu_add_pin_mux_options_a370.patch b/target/linux/mvebu/patches-3.8/011-arm_mvebu_add_pin_mux_options_a370.patch new file mode 100644 index 0000000000..6b245a0179 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/011-arm_mvebu_add_pin_mux_options_a370.patch @@ -0,0 +1,38 @@ +The SDIO interface is available either on pins MPP9/11/12/13/14/15 or +MPP47/48/49/50/51/52 on the Armada 370. Even though all combinations +are potentially possible, those two muxing options are the most +probable ones, so we provide those at the SoC level .dtsi file. + +In practice, in turns out the Armada 370 DB board uses the former, +while the Armada 370 Mirabox uses the latter. + +Signed-off-by: Thomas Petazzoni +--- + arch/arm/boot/dts/armada-370.dtsi | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi +index 636cf7d..88f9bab 100644 +--- a/arch/arm/boot/dts/armada-370.dtsi ++++ b/arch/arm/boot/dts/armada-370.dtsi +@@ -47,6 +47,18 @@ + pinctrl { + compatible = "marvell,mv88f6710-pinctrl"; + reg = <0xd0018000 0x38>; ++ ++ sdio_pins1: sdio-pins1 { ++ marvell,pins = "mpp9", "mpp11", "mpp12", ++ "mpp13", "mpp14", "mpp15"; ++ marvell,function = "sd0"; ++ }; ++ ++ sdio_pins2: sdio-pins2 { ++ marvell,pins = "mpp47", "mpp48", "mpp49", ++ "mpp50", "mpp51", "mpp52"; ++ marvell,function = "sd0"; ++ }; + }; + + gpio0: gpio@d0018100 { +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/012-arm_mvebu_add_pin_mux_options_axp.patch b/target/linux/mvebu/patches-3.8/012-arm_mvebu_add_pin_mux_options_axp.patch new file mode 100644 index 0000000000..f4d9a96f83 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/012-arm_mvebu_add_pin_mux_options_axp.patch @@ -0,0 +1,69 @@ +The SDIO interface is only available on pins MPP30/31/32/33/34/35 on +the various Armada XP variants, so we provide a pin muxing option for +this in the Armada XP .dtsi files. + +Even though those muxing options are the same for MV78230, MV78260 and +MV78460, we keep them in each .dtsi file, because the number of pins, +and therefore the declaration of the pinctrl node, is different for +each SoC variant. + +Signed-off-by: Thomas Petazzoni +--- + arch/arm/boot/dts/armada-xp-mv78230.dtsi | 6 ++++++ + arch/arm/boot/dts/armada-xp-mv78260.dtsi | 6 ++++++ + arch/arm/boot/dts/armada-xp-mv78460.dtsi | 6 ++++++ + 3 files changed, 18 insertions(+) + +diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi +index c45c7b4..3fa9c84 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi +@@ -40,6 +40,12 @@ + pinctrl { + compatible = "marvell,mv78230-pinctrl"; + reg = <0xd0018000 0x38>; ++ ++ sdio_pins: sdio-pins { ++ marvell,pins = "mpp30", "mpp31", "mpp32", ++ "mpp33", "mpp34", "mpp35"; ++ marvell,function = "sd0"; ++ }; + }; + + gpio0: gpio@d0018100 { +diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi +index a2aee57..5a907b3 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi +@@ -48,6 +48,12 @@ + pinctrl { + compatible = "marvell,mv78260-pinctrl"; + reg = <0xd0018000 0x38>; ++ ++ sdio_pins: sdio-pins { ++ marvell,pins = "mpp30", "mpp31", "mpp32", ++ "mpp33", "mpp34", "mpp35"; ++ marvell,function = "sd0"; ++ }; + }; + + gpio0: gpio@d0018100 { +diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi +index da03a12..6dcdc50d 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi +@@ -63,6 +63,12 @@ + pinctrl { + compatible = "marvell,mv78460-pinctrl"; + reg = <0xd0018000 0x38>; ++ ++ sdio_pins: sdio-pins { ++ marvell,pins = "mpp30", "mpp31", "mpp32", ++ "mpp33", "mpp34", "mpp35"; ++ marvell,function = "sd0"; ++ }; + }; + + gpio0: gpio@d0018100 { +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/013-arm_mvebu_enable_sd_cart_slot_axp_db.patch b/target/linux/mvebu/patches-3.8/013-arm_mvebu_enable_sd_cart_slot_axp_db.patch new file mode 100644 index 0000000000..f013ec0f11 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/013-arm_mvebu_enable_sd_cart_slot_axp_db.patch @@ -0,0 +1,29 @@ +The Armada XP DB evaluation board has one SD card slot, directly +connected to the SDIO IP of the SoC, so we enable this +IP. Unfortunately, there are no GPIOs for card-detect and +write-protect. + +Signed-off-by: Thomas Petazzoni +--- + arch/arm/boot/dts/armada-xp-db.dts | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts +index 8e53b25..c7035c5 100644 +--- a/arch/arm/boot/dts/armada-xp-db.dts ++++ b/arch/arm/boot/dts/armada-xp-db.dts +@@ -90,5 +90,12 @@ + phy = <&phy3>; + phy-mode = "sgmii"; + }; ++ ++ mvsdio@d00d4000 { ++ pinctrl-0 = <&sdio_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ /* No CD or WP GPIOs */ ++ }; + }; + }; +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/014-arm_mvebu_enable_sd_card_slot_a370_db.patch b/target/linux/mvebu/patches-3.8/014-arm_mvebu_enable_sd_card_slot_a370_db.patch new file mode 100644 index 0000000000..3759741dbe --- /dev/null +++ b/target/linux/mvebu/patches-3.8/014-arm_mvebu_enable_sd_card_slot_a370_db.patch @@ -0,0 +1,46 @@ +The Armada XP DB evaluation board has one SD card slot, directly +connected to the SDIO IP of the SoC, so we add a device tree +description for it. + +However, in the default configuration of the board, the SD card slot +is not usable: the connector plugged into CON40 must be changed +against a different one, provided with the board by the +manufacturer. Since such a manual modification of the hardware is +needed, we did not enable the SDIO interface by default, and left it +to the board user to modify the Device Tree if needed. Since this +board is really only an evaluation board for developers and not a +final product, it is not too bad. + +Signed-off-by: Thomas Petazzoni +--- +[florian: changed status to "okay" for RD-A370-A1] + arch/arm/boot/dts/armada-370-db.dts | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts +index 0004402..43ff156 100644 +--- a/arch/arm/boot/dts/armada-370-db.dts ++++ b/arch/arm/boot/dts/armada-370-db.dts +@@ -59,5 +59,20 @@ + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; ++ ++ mvsdio@d00d4000 { ++ pinctrl-0 = <&sdio_pins1>; ++ pinctrl-names = "default"; ++ /* ++ * This device is disabled by default, because ++ * using the SD card connector requires ++ * changing the default CON40 connector ++ * "DB-88F6710_MPP_2xRGMII_DEVICE_Jumper" to a ++ * different connector ++ * "DB-88F6710_MPP_RGMII_SD_Jumper". ++ */ ++ status = "okay"; ++ /* No CD or WP GPIOs */ ++ }; + }; + }; +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/015-arm_mvebu_enable_sd_card_slot_mirabox.patch b/target/linux/mvebu/patches-3.8/015-arm_mvebu_enable_sd_card_slot_mirabox.patch new file mode 100644 index 0000000000..3868d46d8d --- /dev/null +++ b/target/linux/mvebu/patches-3.8/015-arm_mvebu_enable_sd_card_slot_mirabox.patch @@ -0,0 +1,31 @@ +The Globalscale Mirabox uses the SDIO interface of the Armada 370 to +connect to a Wifi/Bluetooth SD8787 chip, so we enable the SDIO +interface of this board in its Device Tree file. + +Signed-off-by: Thomas Petazzoni +--- + arch/arm/boot/dts/armada-370-mirabox.dts | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts +index 3b40713..1864820 100644 +--- a/arch/arm/boot/dts/armada-370-mirabox.dts ++++ b/arch/arm/boot/dts/armada-370-mirabox.dts +@@ -52,5 +52,15 @@ + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; ++ ++ mvsdio@d00d4000 { ++ pinctrl-0 = <&sdio_pins2>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ /* ++ * No CD or WP GPIOs: SDIO interface used for ++ * Wifi/Bluetooth chip ++ */ ++ }; + }; + }; +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/016-arm_cache_l2x0_aurora_invalidate.patch b/target/linux/mvebu/patches-3.8/016-arm_cache_l2x0_aurora_invalidate.patch new file mode 100644 index 0000000000..7e7c5fda8b --- /dev/null +++ b/target/linux/mvebu/patches-3.8/016-arm_cache_l2x0_aurora_invalidate.patch @@ -0,0 +1,52 @@ +From e84ed03e1c5d45305fdd9b872e0b7be97bcfda16 Mon Sep 17 00:00:00 2001 +From: Gregory CLEMENT +Date: Thu, 13 Dec 2012 15:03:27 +0100 +Subject: [PATCH] arm: cache-l2x0: aurora: Invalidate during clean operation + with WT enable + +This patch fixes a bug for Aurora L2 cache controller when the +write-through mode is enable. For the clean operation even if we don't +have to flush the lines we still need to invalidate them. + +Signed-off-by: Gregory CLEMENT +--- + arch/arm/mm/cache-l2x0.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c +index 6911b8b..7ffe943 100644 +--- a/arch/arm/mm/cache-l2x0.c ++++ b/arch/arm/mm/cache-l2x0.c +@@ -505,15 +505,21 @@ static void aurora_clean_range(unsigned long start, unsigned long end) + + static void aurora_flush_range(unsigned long start, unsigned long end) + { +- if (!l2_wt_override) { +- start &= ~(CACHE_LINE_SIZE - 1); +- end = ALIGN(end, CACHE_LINE_SIZE); +- while (start != end) { +- unsigned long range_end = calc_range_end(start, end); ++ start &= ~(CACHE_LINE_SIZE - 1); ++ end = ALIGN(end, CACHE_LINE_SIZE); ++ while (start != end) { ++ unsigned long range_end = calc_range_end(start, end); ++ /* ++ * If L2 is forced to WT, the L2 will always be clean and we ++ * just need to invalidate. ++ */ ++ if (l2_wt_override) + aurora_pa_range(start, range_end - CACHE_LINE_SIZE, +- AURORA_FLUSH_RANGE_REG); +- start = range_end; +- } ++ AURORA_INVAL_RANGE_REG); ++ else ++ aurora_pa_range(start, range_end - CACHE_LINE_SIZE, ++ AURORA_FLUSH_RANGE_REG); ++ start = range_end; + } + } + +-- +1.7.10.4 + diff --git a/target/linux/mvebu/patches-3.8/017-arm_cache_l2x0_aurora_use_writel_relaxed.patch b/target/linux/mvebu/patches-3.8/017-arm_cache_l2x0_aurora_use_writel_relaxed.patch new file mode 100644 index 0000000000..5f5ba11d79 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/017-arm_cache_l2x0_aurora_use_writel_relaxed.patch @@ -0,0 +1,45 @@ +From 6c8928f877a1572f16cfc8a0c055d7e16320c741 Mon Sep 17 00:00:00 2001 +From: Gregory CLEMENT +Date: Thu, 13 Dec 2012 18:33:06 +0100 +Subject: [PATCH] arm: cache-l2x0: aurora: Use writel_relaxed instead of + writel + +The use of writel instead of writel_relaxed lead to deadlock in some +situation (SMP on Armada 370 for instance). The use of writel_relaxed +as it was done in the rest of this driver fixes this bug. + +Signed-off-by: Gregory CLEMENT +--- + arch/arm/mm/cache-l2x0.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c +index 7ffe943..96a1ae4 100644 +--- a/arch/arm/mm/cache-l2x0.c ++++ b/arch/arm/mm/cache-l2x0.c +@@ -459,8 +459,8 @@ static void aurora_pa_range(unsigned long start, unsigned long end, + unsigned long flags; + + raw_spin_lock_irqsave(&l2x0_lock, flags); +- writel(start, l2x0_base + AURORA_RANGE_BASE_ADDR_REG); +- writel(end, l2x0_base + offset); ++ writel_relaxed(start, l2x0_base + AURORA_RANGE_BASE_ADDR_REG); ++ writel_relaxed(end, l2x0_base + offset); + raw_spin_unlock_irqrestore(&l2x0_lock, flags); + + cache_sync(); +@@ -674,8 +674,9 @@ static void pl310_resume(void) + static void aurora_resume(void) + { + if (!(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) { +- writel(l2x0_saved_regs.aux_ctrl, l2x0_base + L2X0_AUX_CTRL); +- writel(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL); ++ writel_relaxed(l2x0_saved_regs.aux_ctrl, ++ l2x0_base + L2X0_AUX_CTRL); ++ writel_relaxed(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL); + } + } + +-- +1.7.10.4 + diff --git a/target/linux/mvebu/patches-3.8/018-arm_mvebu_dw_apb_uart.patch b/target/linux/mvebu/patches-3.8/018-arm_mvebu_dw_apb_uart.patch new file mode 100644 index 0000000000..29c199cad4 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/018-arm_mvebu_dw_apb_uart.patch @@ -0,0 +1,88 @@ +From 3487b074a742bc3300683e91e3ade383b659fbe9 Mon Sep 17 00:00:00 2001 +From: Gregory CLEMENT +Date: Tue, 4 Dec 2012 18:04:59 +0100 +Subject: [PATCH] arm: mvebu: Use dw-apb-uart instead of ns16650 as UART + driver + +The UART controller used in the Armada 370 and Armada XP SoCs is the +Synopsys DesignWare 8250 (aka Synopsys DesignWare ABP UART). The +improper use of the ns16550 can lead to a kernel oops during boot if +a character is sent to the UART before the initialization of the +driver. The DW APB has an extra interrupt that gets raised when +writing to the LCR when busy. This explains why we need to use +dw-apb-uart driver to handle this. + +Signed-off-by: Gregory CLEMENT +--- + arch/arm/boot/dts/armada-370-xp.dtsi | 6 ++++-- + arch/arm/boot/dts/armada-xp.dtsi | 6 ++++-- + arch/arm/configs/mvebu_defconfig | 1 + + 3 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi +index cf6c48a..4c0abe8 100644 +--- a/arch/arm/boot/dts/armada-370-xp.dtsi ++++ b/arch/arm/boot/dts/armada-370-xp.dtsi +@@ -50,17 +50,19 @@ + ranges; + + serial@d0012000 { +- compatible = "ns16550"; ++ compatible = "snps,dw-apb-uart"; + reg = <0xd0012000 0x100>; + reg-shift = <2>; + interrupts = <41>; ++ reg-io-width = <4>; + status = "disabled"; + }; + serial@d0012100 { +- compatible = "ns16550"; ++ compatible = "snps,dw-apb-uart"; + reg = <0xd0012100 0x100>; + reg-shift = <2>; + interrupts = <42>; ++ reg-io-width = <4>; + status = "disabled"; + }; + +diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi +index 367aa3f..8a85ffe 100644 +--- a/arch/arm/boot/dts/armada-xp.dtsi ++++ b/arch/arm/boot/dts/armada-xp.dtsi +@@ -42,17 +42,19 @@ + + soc { + serial@d0012200 { +- compatible = "ns16550"; ++ compatible = "snps,dw-apb-uart"; + reg = <0xd0012200 0x100>; + reg-shift = <2>; + interrupts = <43>; ++ reg-io-width = <4>; + status = "disabled"; + }; + serial@d0012300 { +- compatible = "ns16550"; ++ compatible = "snps,dw-apb-uart"; + reg = <0xd0012300 0x100>; + reg-shift = <2>; + interrupts = <44>; ++ reg-io-width = <4>; + status = "disabled"; + }; + +diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig +index a702fb3..3ba35f1 100644 +--- a/arch/arm/configs/mvebu_defconfig ++++ b/arch/arm/configs/mvebu_defconfig +@@ -34,6 +34,7 @@ CONFIG_MARVELL_PHY=y + CONFIG_SERIAL_8250=y + CONFIG_SERIAL_8250_CONSOLE=y + CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_SERIAL_8250_DW=y + CONFIG_I2C=y + CONFIG_I2C_MV64XXX=y + CONFIG_GPIOLIB=y +-- +1.7.10.4 +