mirror of https://github.com/hak5/openwrt.git
ramips: drop support for kernel 4.14
The target seems to be working on 5.4, so drop 4.14 support in preparation for removing it from master entirely. Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>master
parent
e68c017e93
commit
66ab1fb395
|
@ -1,235 +0,0 @@
|
|||
CONFIG_AR8216_PHY=y
|
||||
CONFIG_ARCH_BINFMT_ELF_STATE=y
|
||||
CONFIG_ARCH_CLOCKSOURCE_DATA=y
|
||||
CONFIG_ARCH_DISCARD_MEMBLOCK=y
|
||||
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
|
||||
# CONFIG_ARCH_HAS_GCOV_PROFILE_ALL is not set
|
||||
CONFIG_ARCH_HAS_RESET_CONTROLLER=y
|
||||
# CONFIG_ARCH_HAS_SG_CHAIN is not set
|
||||
# CONFIG_ARCH_HAS_STRICT_KERNEL_RWX is not set
|
||||
# CONFIG_ARCH_HAS_STRICT_MODULE_RWX is not set
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MAX=15
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
|
||||
# CONFIG_ARCH_OPTIONAL_KERNEL_RWX is not set
|
||||
# CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT is not set
|
||||
CONFIG_ARCH_SUPPORTS_UPROBES=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
|
||||
CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
|
||||
CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
|
||||
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
|
||||
CONFIG_AT803X_PHY=y
|
||||
CONFIG_BLK_MQ_PCI=y
|
||||
CONFIG_CEVT_R4K=y
|
||||
CONFIG_CEVT_SYSTICK_QUIRK=y
|
||||
CONFIG_CLKDEV_LOOKUP=y
|
||||
CONFIG_CLKEVT_RT3352=y
|
||||
CONFIG_CLKSRC_MMIO=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
|
||||
CONFIG_CMDLINE_BOOL=y
|
||||
# CONFIG_CMDLINE_OVERRIDE is not set
|
||||
CONFIG_CPU_GENERIC_DUMP_TLB=y
|
||||
CONFIG_CPU_HAS_PREFETCH=y
|
||||
CONFIG_CPU_HAS_RIXI=y
|
||||
CONFIG_CPU_HAS_SYNC=y
|
||||
CONFIG_CPU_LITTLE_ENDIAN=y
|
||||
CONFIG_CPU_MIPS32=y
|
||||
# CONFIG_CPU_MIPS32_R1 is not set
|
||||
CONFIG_CPU_MIPS32_R2=y
|
||||
CONFIG_CPU_MIPSR2=y
|
||||
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
|
||||
CONFIG_CPU_R4K_CACHE_TLB=y
|
||||
CONFIG_CPU_R4K_FPU=y
|
||||
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
|
||||
CONFIG_CPU_SUPPORTS_HIGHMEM=y
|
||||
CONFIG_CPU_SUPPORTS_MSA=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_WORKQUEUE=y
|
||||
CONFIG_CSRC_R4K=y
|
||||
CONFIG_DEBUG_PINCTRL=y
|
||||
CONFIG_DMA_NONCOHERENT=y
|
||||
# CONFIG_DTB_MT7620A_EVAL is not set
|
||||
# CONFIG_DTB_OMEGA2P is not set
|
||||
CONFIG_DTB_RT_NONE=y
|
||||
# CONFIG_DTB_VOCORE2 is not set
|
||||
CONFIG_DTC=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_ETHERNET_PACKET_MANGLE=y
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_GENERIC_ATOMIC64=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||
CONFIG_GENERIC_CPU_AUTOPROBE=y
|
||||
CONFIG_GENERIC_IO=y
|
||||
CONFIG_GENERIC_IRQ_CHIP=y
|
||||
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_PHY=y
|
||||
CONFIG_GENERIC_SCHED_CLOCK=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
CONFIG_GPIOLIB=y
|
||||
# CONFIG_GPIO_MT7621 is not set
|
||||
CONFIG_GPIO_RALINK=y
|
||||
# CONFIG_GRO_CELLS is not set
|
||||
CONFIG_HANDLE_DOMAIN_IRQ=y
|
||||
CONFIG_HARDWARE_WATCHPOINTS=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
|
||||
# CONFIG_HAVE_ARCH_BITREVERSE is not set
|
||||
CONFIG_HAVE_ARCH_JUMP_LABEL=y
|
||||
CONFIG_HAVE_ARCH_KGDB=y
|
||||
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
|
||||
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
|
||||
CONFIG_HAVE_CBPF_JIT=y
|
||||
CONFIG_HAVE_CC_STACKPROTECTOR=y
|
||||
CONFIG_HAVE_CLK=y
|
||||
CONFIG_HAVE_CONTEXT_TRACKING=y
|
||||
CONFIG_HAVE_COPY_THREAD_TLS=y
|
||||
CONFIG_HAVE_C_RECORDMCOUNT=y
|
||||
CONFIG_HAVE_DEBUG_KMEMLEAK=y
|
||||
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
|
||||
CONFIG_HAVE_DMA_API_DEBUG=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_IDE=y
|
||||
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
|
||||
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
|
||||
CONFIG_HAVE_KVM=y
|
||||
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
|
||||
CONFIG_HAVE_MEMBLOCK=y
|
||||
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
|
||||
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
|
||||
CONFIG_HAVE_NET_DSA=y
|
||||
CONFIG_HAVE_OPROFILE=y
|
||||
CONFIG_HAVE_PERF_EVENTS=y
|
||||
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
|
||||
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
|
||||
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
|
||||
CONFIG_HW_HAS_PCI=y
|
||||
CONFIG_HZ_PERIODIC=y
|
||||
CONFIG_ICPLUS_PHY=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_INTC=y
|
||||
CONFIG_IRQ_MIPS_CPU=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_MARVELL_PHY=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MFD_SYSCON=y
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_MIPS_ASID_BITS=8
|
||||
CONFIG_MIPS_ASID_SHIFT=0
|
||||
CONFIG_MIPS_CLOCK_VSYSCALL=y
|
||||
# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
|
||||
# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
|
||||
# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
|
||||
CONFIG_MIPS_CMDLINE_FROM_DTB=y
|
||||
# CONFIG_MIPS_ELF_APPENDED_DTB is not set
|
||||
# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set
|
||||
CONFIG_MIPS_L1_CACHE_SHIFT=5
|
||||
# CONFIG_MIPS_MACHINE is not set
|
||||
# CONFIG_MIPS_NO_APPENDED_DTB is not set
|
||||
CONFIG_MIPS_RAW_APPENDED_DTB=y
|
||||
CONFIG_MIPS_SPRAM=y
|
||||
CONFIG_MODULES_USE_ELF_REL=y
|
||||
# CONFIG_MT7621_WDT is not set
|
||||
# CONFIG_MTD_CFI_INTELEXT is not set
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
CONFIG_MTD_M25P80=y
|
||||
CONFIG_MTD_PHYSMAP=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
|
||||
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384
|
||||
CONFIG_MTD_SPLIT_JIMAGE_FW=y
|
||||
CONFIG_MTD_SPLIT_SEAMA_FW=y
|
||||
CONFIG_MTD_SPLIT_TPLINK_FW=y
|
||||
CONFIG_MTD_SPLIT_UIMAGE_FW=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_PER_CPU_KM=y
|
||||
CONFIG_NET_RALINK_GSW_MT7620=y
|
||||
CONFIG_NET_RALINK_MDIO=y
|
||||
CONFIG_NET_RALINK_MDIO_MT7620=y
|
||||
CONFIG_NET_RALINK_MT7620=y
|
||||
# CONFIG_NET_RALINK_RT3050 is not set
|
||||
CONFIG_NET_RALINK_SOC=y
|
||||
CONFIG_NET_VENDOR_RALINK=y
|
||||
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
|
||||
# CONFIG_NO_IOPORT_MAP is not set
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_ADDRESS_PCI=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OF_NET=y
|
||||
CONFIG_OF_PCI=y
|
||||
CONFIG_OF_PCI_IRQ=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_DRIVERS_LEGACY=y
|
||||
CONFIG_PERF_USE_VMALLOC=y
|
||||
CONFIG_PGTABLE_LEVELS=2
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHY_RALINK_USB=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_RT2880=y
|
||||
# CONFIG_PINCTRL_SINGLE is not set
|
||||
CONFIG_RALINK=y
|
||||
CONFIG_RALINK_WDT=y
|
||||
# CONFIG_RCU_NEED_SEGCBLIST is not set
|
||||
# CONFIG_RCU_STALL_COMMON is not set
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_REGMAP_MMIO=y
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
# CONFIG_SCHED_INFO is not set
|
||||
# CONFIG_SCSI_DMA is not set
|
||||
# CONFIG_SERIAL_8250_FSL is not set
|
||||
CONFIG_SERIAL_8250_RT288X=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
CONFIG_SOC_MT7620=y
|
||||
# CONFIG_SOC_MT7621 is not set
|
||||
# CONFIG_SOC_RT288X is not set
|
||||
# CONFIG_SOC_RT305X is not set
|
||||
# CONFIG_SOC_RT3883 is not set
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_MASTER=y
|
||||
# CONFIG_SPI_MT7621 is not set
|
||||
CONFIG_SPI_RT2880=y
|
||||
CONFIG_SRCU=y
|
||||
CONFIG_SWCONFIG=y
|
||||
CONFIG_SWCONFIG_LEDS=y
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
|
||||
CONFIG_SYS_HAS_CPU_MIPS32_R2=y
|
||||
CONFIG_SYS_HAS_EARLY_PRINTK=y
|
||||
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
|
||||
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
|
||||
CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
|
||||
CONFIG_SYS_SUPPORTS_MIPS16=y
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TIMER_OF=y
|
||||
CONFIG_TIMER_PROBE=y
|
||||
CONFIG_TINY_SRCU=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_USE_OF=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
|
@ -1,45 +0,0 @@
|
|||
From 35d017947401d9f449a7e55e52506744e0c62577 Mon Sep 17 00:00:00 2001
|
||||
From: Mathias Kresin <dev@kresin.me>
|
||||
Date: Wed, 22 Aug 2018 22:38:06 +0200
|
||||
Subject: [PATCH] MIPS: ralink: Add rt3352 SPI_CS1 pinmux
|
||||
|
||||
The rt3352 has a pin that can be used as second spi chip select,
|
||||
watchdog reset or GPIO. The pinmux setup was missing the definition of
|
||||
said pin.
|
||||
|
||||
The pin is configured via the same bit on rt5350, so reuse the existing
|
||||
macro.
|
||||
|
||||
Signed-off-by: Mathias Kresin <dev@kresin.me>
|
||||
Signed-off-by: Paul Burton <paul.burton@mips.com>
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/20301/
|
||||
Cc: John Crispin <john@phrozen.org>
|
||||
Cc: Ralf Baechle <ralf@linux-mips.org>
|
||||
Cc: James Hogan <jhogan@kernel.org>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Cc: linux-kernel@vger.kernel.org
|
||||
---
|
||||
arch/mips/ralink/rt305x.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
--- a/arch/mips/ralink/rt305x.c
|
||||
+++ b/arch/mips/ralink/rt305x.c
|
||||
@@ -49,6 +49,10 @@ static struct rt2880_pmx_func rgmii_func
|
||||
static struct rt2880_pmx_func rt3352_lna_func[] = { FUNC("lna", 0, 36, 2) };
|
||||
static struct rt2880_pmx_func rt3352_pa_func[] = { FUNC("pa", 0, 38, 2) };
|
||||
static struct rt2880_pmx_func rt3352_led_func[] = { FUNC("led", 0, 40, 5) };
|
||||
+static struct rt2880_pmx_func rt3352_cs1_func[] = {
|
||||
+ FUNC("spi_cs1", 0, 45, 1),
|
||||
+ FUNC("wdg_cs1", 1, 45, 1),
|
||||
+};
|
||||
|
||||
static struct rt2880_pmx_group rt3050_pinmux_data[] = {
|
||||
GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
|
||||
@@ -75,6 +79,7 @@ static struct rt2880_pmx_group rt3352_pi
|
||||
GRP("lna", rt3352_lna_func, 1, RT3352_GPIO_MODE_LNA),
|
||||
GRP("pa", rt3352_pa_func, 1, RT3352_GPIO_MODE_PA),
|
||||
GRP("led", rt3352_led_func, 1, RT5350_GPIO_MODE_PHY_LED),
|
||||
+ GRP("spi_cs1", rt3352_cs1_func, 2, RT5350_GPIO_MODE_SPI_CS1),
|
||||
{ 0 }
|
||||
};
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
From 0eb1cfffd5433d8dce3e4163a5cd9accc6000856 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Wolf <dev-NTEO@vplace.de>
|
||||
Date: Wed, 5 Sep 2018 08:51:26 +0200
|
||||
Subject: [PATCH] MIPS: pci-rt2880: set pci controller of_node
|
||||
|
||||
Set the PCI controller of_node such that PCI devices can be
|
||||
instantiated via device tree.
|
||||
|
||||
Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de>
|
||||
Signed-off-by: Mathias Kresin <dev@kresin.me>
|
||||
Acked-by: John Crispin <john@phrozen.org>
|
||||
Signed-off-by: Paul Burton <paul.burton@mips.com>
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/20423/
|
||||
Cc: Ralf Baechle <ralf@linux-mips.org>
|
||||
Cc: James Hogan <jhogan@kernel.org>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Cc: linux-kernel@vger.kernel.org
|
||||
---
|
||||
arch/mips/pci/pci-rt2880.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/arch/mips/pci/pci-rt2880.c
|
||||
+++ b/arch/mips/pci/pci-rt2880.c
|
||||
@@ -246,6 +246,8 @@ static int rt288x_pci_probe(struct platf
|
||||
rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
|
||||
(void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);
|
||||
|
||||
+ rt2880_pci_controller.of_node = pdev->dev.of_node;
|
||||
+
|
||||
register_pci_controller(&rt2880_pci_controller);
|
||||
return 0;
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
From: Tobias Wolf <dev-NTEO@vplace.de>
|
||||
Subject: [v2] MIPS: Fix memory reservation in bootmem_init for certain non-usermem setups
|
||||
|
||||
Commit 67a3ba25aa95 ("MIPS: Fix incorrect mem=X@Y handling") introduced a new
|
||||
issue for rt288x where "PHYS_OFFSET" is 0x0 but the calculated "ramstart" is
|
||||
not. As the prerequisite of custom memory map has been removed, this results
|
||||
in the full memory range of 0x0 - 0x8000000 to be marked as reserved for this
|
||||
platform.
|
||||
|
||||
v2: Correctly compare that usermem is not null.
|
||||
|
||||
This patch adds the originally intended prerequisite again.
|
||||
|
||||
Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de>
|
||||
---
|
||||
|
||||
--- a/arch/mips/kernel/setup.c
|
||||
+++ b/arch/mips/kernel/setup.c
|
||||
@@ -369,6 +369,8 @@ static unsigned long __init bootmap_byte
|
||||
return ALIGN(bytes, sizeof(long));
|
||||
}
|
||||
|
||||
+static int usermem __initdata;
|
||||
+
|
||||
static void __init bootmem_init(void)
|
||||
{
|
||||
unsigned long reserved_end;
|
||||
@@ -442,7 +444,7 @@ static void __init bootmem_init(void)
|
||||
/*
|
||||
* Reserve any memory between the start of RAM and PHYS_OFFSET
|
||||
*/
|
||||
- if (ramstart > PHYS_OFFSET)
|
||||
+ if (usermem && ramstart > PHYS_OFFSET)
|
||||
add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET,
|
||||
BOOT_MEM_RESERVED);
|
||||
|
||||
@@ -652,8 +654,6 @@ static void __init bootmem_init(void)
|
||||
* initialization hook for anything else was introduced.
|
||||
*/
|
||||
|
||||
-static int usermem __initdata;
|
||||
-
|
||||
static int __init early_parse_mem(char *p)
|
||||
{
|
||||
phys_addr_t start, size;
|
|
@ -1,861 +0,0 @@
|
|||
From fec11d4e8dc5cc79bcd7c8fd55038ac21ac39965 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 16 Mar 2014 05:22:39 +0000
|
||||
Subject: [PATCH 04/53] MIPS: ralink: add MT7621 pcie driver
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/pci/Makefile | 1 +
|
||||
arch/mips/pci/pci-mt7621.c | 813 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 814 insertions(+)
|
||||
create mode 100644 arch/mips/pci/pci-mt7621.c
|
||||
|
||||
--- a/arch/mips/pci/Makefile
|
||||
+++ b/arch/mips/pci/Makefile
|
||||
@@ -47,6 +47,7 @@ obj-$(CONFIG_SNI_RM) += fixup-sni.o ops
|
||||
obj-$(CONFIG_LANTIQ) += fixup-lantiq.o
|
||||
obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o
|
||||
obj-$(CONFIG_SOC_MT7620) += pci-mt7620.o
|
||||
+obj-$(CONFIG_SOC_MT7621) += pci-mt7621.o
|
||||
obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o
|
||||
obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o
|
||||
obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/pci/pci-mt7621.c
|
||||
@@ -0,0 +1,836 @@
|
||||
+/**************************************************************************
|
||||
+ *
|
||||
+ * BRIEF MODULE DESCRIPTION
|
||||
+ * PCI init for Ralink RT2880 solution
|
||||
+ *
|
||||
+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw)
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License as published by the
|
||||
+ * Free Software Foundation; either version 2 of the License, or (at your
|
||||
+ * option) any later version.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License along
|
||||
+ * with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
+ *
|
||||
+ *
|
||||
+ **************************************************************************
|
||||
+ * May 2007 Bruce Chang
|
||||
+ * Initial Release
|
||||
+ *
|
||||
+ * May 2009 Bruce Chang
|
||||
+ * support RT2880/RT3883 PCIe
|
||||
+ *
|
||||
+ * May 2011 Bruce Chang
|
||||
+ * support RT6855/MT7620 PCIe
|
||||
+ *
|
||||
+ **************************************************************************
|
||||
+ */
|
||||
+
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/pci.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/version.h>
|
||||
+#include <asm/pci.h>
|
||||
+#include <asm/io.h>
|
||||
+#include <asm/mips-cm.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_pci.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include <ralink_regs.h>
|
||||
+
|
||||
+extern void pcie_phy_init(void);
|
||||
+extern void chk_phy_pll(void);
|
||||
+
|
||||
+/*
|
||||
+ * These functions and structures provide the BIOS scan and mapping of the PCI
|
||||
+ * devices.
|
||||
+ */
|
||||
+
|
||||
+#define CONFIG_PCIE_PORT0
|
||||
+#define CONFIG_PCIE_PORT1
|
||||
+#define CONFIG_PCIE_PORT2
|
||||
+#define RALINK_PCIE0_CLK_EN (1<<24)
|
||||
+#define RALINK_PCIE1_CLK_EN (1<<25)
|
||||
+#define RALINK_PCIE2_CLK_EN (1<<26)
|
||||
+
|
||||
+#define RALINK_PCI_CONFIG_ADDR 0x20
|
||||
+#define RALINK_PCI_CONFIG_DATA_VIRTUAL_REG 0x24
|
||||
+#define RALINK_INT_PCIE0 pcie_irq[0]
|
||||
+#define RALINK_INT_PCIE1 pcie_irq[1]
|
||||
+#define RALINK_INT_PCIE2 pcie_irq[2]
|
||||
+#define RALINK_PCI_MEMBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x0028)
|
||||
+#define RALINK_PCI_IOBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x002C)
|
||||
+#define RALINK_PCIE0_RST (1<<24)
|
||||
+#define RALINK_PCIE1_RST (1<<25)
|
||||
+#define RALINK_PCIE2_RST (1<<26)
|
||||
+#define RALINK_SYSCTL_BASE 0xBE000000
|
||||
+
|
||||
+#define RALINK_PCI_PCICFG_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x0000)
|
||||
+#define RALINK_PCI_PCIMSK_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x000C)
|
||||
+#define RALINK_PCI_BASE 0xBE140000
|
||||
+
|
||||
+#define RALINK_PCIEPHY_P0P1_CTL_OFFSET (RALINK_PCI_BASE + 0x9000)
|
||||
+#define RT6855_PCIE0_OFFSET 0x2000
|
||||
+#define RT6855_PCIE1_OFFSET 0x3000
|
||||
+#define RT6855_PCIE2_OFFSET 0x4000
|
||||
+
|
||||
+#define RALINK_PCI0_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0010)
|
||||
+#define RALINK_PCI0_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0018)
|
||||
+#define RALINK_PCI0_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0030)
|
||||
+#define RALINK_PCI0_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0034)
|
||||
+#define RALINK_PCI0_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0038)
|
||||
+#define RALINK_PCI0_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0050)
|
||||
+#define RALINK_PCI0_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0060)
|
||||
+#define RALINK_PCI0_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0064)
|
||||
+
|
||||
+#define RALINK_PCI1_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0010)
|
||||
+#define RALINK_PCI1_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0018)
|
||||
+#define RALINK_PCI1_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0030)
|
||||
+#define RALINK_PCI1_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0034)
|
||||
+#define RALINK_PCI1_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0038)
|
||||
+#define RALINK_PCI1_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0050)
|
||||
+#define RALINK_PCI1_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0060)
|
||||
+#define RALINK_PCI1_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0064)
|
||||
+
|
||||
+#define RALINK_PCI2_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0010)
|
||||
+#define RALINK_PCI2_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0018)
|
||||
+#define RALINK_PCI2_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0030)
|
||||
+#define RALINK_PCI2_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0034)
|
||||
+#define RALINK_PCI2_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0038)
|
||||
+#define RALINK_PCI2_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0050)
|
||||
+#define RALINK_PCI2_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0060)
|
||||
+#define RALINK_PCI2_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0064)
|
||||
+
|
||||
+#define RALINK_PCIEPHY_P0P1_CTL_OFFSET (RALINK_PCI_BASE + 0x9000)
|
||||
+#define RALINK_PCIEPHY_P2_CTL_OFFSET (RALINK_PCI_BASE + 0xA000)
|
||||
+
|
||||
+
|
||||
+#define MV_WRITE(ofs, data) \
|
||||
+ *(volatile u32 *)(RALINK_PCI_BASE+(ofs)) = cpu_to_le32(data)
|
||||
+#define MV_READ(ofs, data) \
|
||||
+ *(data) = le32_to_cpu(*(volatile u32 *)(RALINK_PCI_BASE+(ofs)))
|
||||
+#define MV_READ_DATA(ofs) \
|
||||
+ le32_to_cpu(*(volatile u32 *)(RALINK_PCI_BASE+(ofs)))
|
||||
+
|
||||
+#define MV_WRITE_16(ofs, data) \
|
||||
+ *(volatile u16 *)(RALINK_PCI_BASE+(ofs)) = cpu_to_le16(data)
|
||||
+#define MV_READ_16(ofs, data) \
|
||||
+ *(data) = le16_to_cpu(*(volatile u16 *)(RALINK_PCI_BASE+(ofs)))
|
||||
+
|
||||
+#define MV_WRITE_8(ofs, data) \
|
||||
+ *(volatile u8 *)(RALINK_PCI_BASE+(ofs)) = data
|
||||
+#define MV_READ_8(ofs, data) \
|
||||
+ *(data) = *(volatile u8 *)(RALINK_PCI_BASE+(ofs))
|
||||
+
|
||||
+
|
||||
+
|
||||
+#define RALINK_PCI_MM_MAP_BASE 0x60000000
|
||||
+#define RALINK_PCI_IO_MAP_BASE 0x1e160000
|
||||
+
|
||||
+#define RALINK_SYSTEM_CONTROL_BASE 0xbe000000
|
||||
+#define GPIO_PERST
|
||||
+#define ASSERT_SYSRST_PCIE(val) do { \
|
||||
+ if (*(unsigned int *)(0xbe00000c) == 0x00030101) \
|
||||
+ RALINK_RSTCTRL |= val; \
|
||||
+ else \
|
||||
+ RALINK_RSTCTRL &= ~val; \
|
||||
+ } while(0)
|
||||
+#define DEASSERT_SYSRST_PCIE(val) do { \
|
||||
+ if (*(unsigned int *)(0xbe00000c) == 0x00030101) \
|
||||
+ RALINK_RSTCTRL &= ~val; \
|
||||
+ else \
|
||||
+ RALINK_RSTCTRL |= val; \
|
||||
+ } while(0)
|
||||
+#define RALINK_SYSCFG1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x14)
|
||||
+#define RALINK_CLKCFG1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x30)
|
||||
+#define RALINK_RSTCTRL *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x34)
|
||||
+#define RALINK_GPIOMODE *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x60)
|
||||
+#define RALINK_PCIE_CLK_GEN *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x7c)
|
||||
+#define RALINK_PCIE_CLK_GEN1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x80)
|
||||
+#define PPLL_CFG1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x9c)
|
||||
+#define PPLL_DRV *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0xa0)
|
||||
+//RALINK_SYSCFG1 bit
|
||||
+#define RALINK_PCI_HOST_MODE_EN (1<<7)
|
||||
+#define RALINK_PCIE_RC_MODE_EN (1<<8)
|
||||
+//RALINK_RSTCTRL bit
|
||||
+#define RALINK_PCIE_RST (1<<23)
|
||||
+#define RALINK_PCI_RST (1<<24)
|
||||
+//RALINK_CLKCFG1 bit
|
||||
+#define RALINK_PCI_CLK_EN (1<<19)
|
||||
+#define RALINK_PCIE_CLK_EN (1<<21)
|
||||
+//RALINK_GPIOMODE bit
|
||||
+#define PCI_SLOTx2 (1<<11)
|
||||
+#define PCI_SLOTx1 (2<<11)
|
||||
+//MTK PCIE PLL bit
|
||||
+#define PDRV_SW_SET (1<<31)
|
||||
+#define LC_CKDRVPD_ (1<<19)
|
||||
+
|
||||
+#define MEMORY_BASE 0x0
|
||||
+static int pcie_link_status = 0;
|
||||
+
|
||||
+#define PCI_ACCESS_READ_1 0
|
||||
+#define PCI_ACCESS_READ_2 1
|
||||
+#define PCI_ACCESS_READ_4 2
|
||||
+#define PCI_ACCESS_WRITE_1 3
|
||||
+#define PCI_ACCESS_WRITE_2 4
|
||||
+#define PCI_ACCESS_WRITE_4 5
|
||||
+
|
||||
+static int pcie_irq[3];
|
||||
+
|
||||
+static int config_access(unsigned char access_type, struct pci_bus *bus,
|
||||
+ unsigned int devfn, unsigned int where, u32 * data)
|
||||
+{
|
||||
+ unsigned int slot = PCI_SLOT(devfn);
|
||||
+ u8 func = PCI_FUNC(devfn);
|
||||
+ uint32_t address_reg, data_reg;
|
||||
+ unsigned int address;
|
||||
+
|
||||
+ address_reg = RALINK_PCI_CONFIG_ADDR;
|
||||
+ data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG;
|
||||
+
|
||||
+ address = (((where&0xF00)>>8)<<24) |(bus->number << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | 0x80000000;
|
||||
+ MV_WRITE(address_reg, address);
|
||||
+
|
||||
+ switch(access_type) {
|
||||
+ case PCI_ACCESS_WRITE_1:
|
||||
+ MV_WRITE_8(data_reg+(where&0x3), *data);
|
||||
+ break;
|
||||
+ case PCI_ACCESS_WRITE_2:
|
||||
+ MV_WRITE_16(data_reg+(where&0x3), *data);
|
||||
+ break;
|
||||
+ case PCI_ACCESS_WRITE_4:
|
||||
+ MV_WRITE(data_reg, *data);
|
||||
+ break;
|
||||
+ case PCI_ACCESS_READ_1:
|
||||
+ MV_READ_8( data_reg+(where&0x3), data);
|
||||
+ break;
|
||||
+ case PCI_ACCESS_READ_2:
|
||||
+ MV_READ_16(data_reg+(where&0x3), data);
|
||||
+ break;
|
||||
+ case PCI_ACCESS_READ_4:
|
||||
+ MV_READ(data_reg, data);
|
||||
+ break;
|
||||
+ default:
|
||||
+ printk("no specify access type\n");
|
||||
+ break;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 * val)
|
||||
+{
|
||||
+ return config_access(PCI_ACCESS_READ_1, bus, devfn, (unsigned int)where, (u32 *)val);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 * val)
|
||||
+{
|
||||
+ return config_access(PCI_ACCESS_READ_2, bus, devfn, (unsigned int)where, (u32 *)val);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
|
||||
+{
|
||||
+ return config_access(PCI_ACCESS_READ_4, bus, devfn, (unsigned int)where, (u32 *)val);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val)
|
||||
+{
|
||||
+ if (config_access(PCI_ACCESS_WRITE_1, bus, devfn, (unsigned int)where, (u32 *)&val))
|
||||
+ return -1;
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val)
|
||||
+{
|
||||
+ if (config_access(PCI_ACCESS_WRITE_2, bus, devfn, where, (u32 *)&val))
|
||||
+ return -1;
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val)
|
||||
+{
|
||||
+ if (config_access(PCI_ACCESS_WRITE_4, bus, devfn, where, &val))
|
||||
+ return -1;
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int
|
||||
+pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
|
||||
+{
|
||||
+ switch (size) {
|
||||
+ case 1:
|
||||
+ return read_config_byte(bus, devfn, where, (u8 *) val);
|
||||
+ case 2:
|
||||
+ return read_config_word(bus, devfn, where, (u16 *) val);
|
||||
+ default:
|
||||
+ return read_config_dword(bus, devfn, where, val);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
|
||||
+{
|
||||
+ switch (size) {
|
||||
+ case 1:
|
||||
+ return write_config_byte(bus, devfn, where, (u8) val);
|
||||
+ case 2:
|
||||
+ return write_config_word(bus, devfn, where, (u16) val);
|
||||
+ default:
|
||||
+ return write_config_dword(bus, devfn, where, val);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+struct pci_ops mt7621_pci_ops= {
|
||||
+ .read = pci_config_read,
|
||||
+ .write = pci_config_write,
|
||||
+};
|
||||
+
|
||||
+static struct resource mt7621_res_pci_mem1 = {
|
||||
+ .name = "PCI MEM1",
|
||||
+ .start = RALINK_PCI_MM_MAP_BASE,
|
||||
+ .end = (u32)((RALINK_PCI_MM_MAP_BASE + (unsigned char *)0x0fffffff)),
|
||||
+ .flags = IORESOURCE_MEM,
|
||||
+};
|
||||
+static struct resource mt7621_res_pci_io1 = {
|
||||
+ .name = "PCI I/O1",
|
||||
+ .start = RALINK_PCI_IO_MAP_BASE,
|
||||
+ .end = (u32)((RALINK_PCI_IO_MAP_BASE + (unsigned char *)0x0ffff)),
|
||||
+ .flags = IORESOURCE_IO,
|
||||
+};
|
||||
+
|
||||
+static struct pci_controller mt7621_controller = {
|
||||
+ .pci_ops = &mt7621_pci_ops,
|
||||
+ .mem_resource = &mt7621_res_pci_mem1,
|
||||
+ .io_resource = &mt7621_res_pci_io1,
|
||||
+ .mem_offset = 0x00000000UL,
|
||||
+ .io_offset = 0x00000000UL,
|
||||
+ .io_map_base = 0xa0000000,
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+read_config(unsigned long bus, unsigned long dev, unsigned long func, unsigned long reg, unsigned long *val)
|
||||
+{
|
||||
+ unsigned int address_reg, data_reg, address;
|
||||
+
|
||||
+ address_reg = RALINK_PCI_CONFIG_ADDR;
|
||||
+ data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG;
|
||||
+ address = (((reg & 0xF00)>>8)<<24) | (bus << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 0x80000000 ;
|
||||
+ MV_WRITE(address_reg, address);
|
||||
+ MV_READ(data_reg, val);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+write_config(unsigned long bus, unsigned long dev, unsigned long func, unsigned long reg, unsigned long val)
|
||||
+{
|
||||
+ unsigned int address_reg, data_reg, address;
|
||||
+
|
||||
+ address_reg = RALINK_PCI_CONFIG_ADDR;
|
||||
+ data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG;
|
||||
+ address = (((reg & 0xF00)>>8)<<24) | (bus << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 0x80000000 ;
|
||||
+ MV_WRITE(address_reg, address);
|
||||
+ MV_WRITE(data_reg, val);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+int
|
||||
+pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
+{
|
||||
+ u16 cmd;
|
||||
+ u32 val;
|
||||
+ int irq = 0;
|
||||
+
|
||||
+ if ((dev->bus->number == 0) && (slot == 0)) {
|
||||
+ write_config(0, 0, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE);
|
||||
+ read_config(0, 0, 0, PCI_BASE_ADDRESS_0, (unsigned long *)&val);
|
||||
+ printk("BAR0 at slot 0 = %x\n", val);
|
||||
+ printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot);
|
||||
+ } else if((dev->bus->number == 0) && (slot == 0x1)) {
|
||||
+ write_config(0, 1, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE);
|
||||
+ read_config(0, 1, 0, PCI_BASE_ADDRESS_0, (unsigned long *)&val);
|
||||
+ printk("BAR0 at slot 1 = %x\n", val);
|
||||
+ printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot);
|
||||
+ } else if((dev->bus->number == 0) && (slot == 0x2)) {
|
||||
+ write_config(0, 2, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE);
|
||||
+ read_config(0, 2, 0, PCI_BASE_ADDRESS_0, (unsigned long *)&val);
|
||||
+ printk("BAR0 at slot 2 = %x\n", val);
|
||||
+ printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot);
|
||||
+ } else if ((dev->bus->number == 1) && (slot == 0x0)) {
|
||||
+ switch (pcie_link_status) {
|
||||
+ case 2:
|
||||
+ case 6:
|
||||
+ irq = RALINK_INT_PCIE1;
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ irq = RALINK_INT_PCIE2;
|
||||
+ break;
|
||||
+ default:
|
||||
+ irq = RALINK_INT_PCIE0;
|
||||
+ }
|
||||
+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
|
||||
+ } else if ((dev->bus->number == 2) && (slot == 0x0)) {
|
||||
+ switch (pcie_link_status) {
|
||||
+ case 5:
|
||||
+ case 6:
|
||||
+ irq = RALINK_INT_PCIE2;
|
||||
+ break;
|
||||
+ default:
|
||||
+ irq = RALINK_INT_PCIE1;
|
||||
+ }
|
||||
+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
|
||||
+ } else if ((dev->bus->number == 2) && (slot == 0x1)) {
|
||||
+ switch (pcie_link_status) {
|
||||
+ case 5:
|
||||
+ case 6:
|
||||
+ irq = RALINK_INT_PCIE2;
|
||||
+ break;
|
||||
+ default:
|
||||
+ irq = RALINK_INT_PCIE1;
|
||||
+ }
|
||||
+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
|
||||
+ } else if ((dev->bus->number ==3) && (slot == 0x0)) {
|
||||
+ irq = RALINK_INT_PCIE2;
|
||||
+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
|
||||
+ } else if ((dev->bus->number ==3) && (slot == 0x1)) {
|
||||
+ irq = RALINK_INT_PCIE2;
|
||||
+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
|
||||
+ } else if ((dev->bus->number ==3) && (slot == 0x2)) {
|
||||
+ irq = RALINK_INT_PCIE2;
|
||||
+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
|
||||
+ } else {
|
||||
+ printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x14); //configure cache line size 0x14
|
||||
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xFF); //configure latency timer 0x10
|
||||
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
||||
+ cmd = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
|
||||
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
|
||||
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
+ return irq;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+set_pcie_phy(u32 *addr, int start_b, int bits, int val)
|
||||
+{
|
||||
+// printk("0x%p:", addr);
|
||||
+// printk(" %x", *addr);
|
||||
+ *(unsigned int *)(addr) &= ~(((1<<bits) - 1)<<start_b);
|
||||
+ *(unsigned int *)(addr) |= val << start_b;
|
||||
+// printk(" -> %x\n", *addr);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+bypass_pipe_rst(void)
|
||||
+{
|
||||
+#if defined (CONFIG_PCIE_PORT0)
|
||||
+ /* PCIe Port 0 */
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x02c), 12, 1, 0x01); // rg_pe1_pipe_rst_b
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x02c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4]
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT1)
|
||||
+ /* PCIe Port 1 */
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x12c), 12, 1, 0x01); // rg_pe1_pipe_rst_b
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x12c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4]
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ /* PCIe Port 2 */
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c), 12, 1, 0x01); // rg_pe1_pipe_rst_b
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4]
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+set_phy_for_ssc(void)
|
||||
+{
|
||||
+ unsigned long reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x10));
|
||||
+
|
||||
+ reg = (reg >> 6) & 0x7;
|
||||
+#if defined (CONFIG_PCIE_PORT0) || defined (CONFIG_PCIE_PORT1)
|
||||
+ /* Set PCIe Port0 & Port1 PHY to disable SSC */
|
||||
+ /* Debug Xtal Type */
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x400), 8, 1, 0x01); // rg_pe1_frc_h_xtal_type
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x400), 9, 2, 0x00); // rg_pe1_h_xtal_type
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 0 enable control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 1 enable control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 5, 1, 0x00); // rg_pe1_phy_en //Port 0 disable
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 5, 1, 0x00); // rg_pe1_phy_en //Port 1 disable
|
||||
+ if(reg <= 5 && reg >= 3) { // 40MHz Xtal
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 6, 2, 0x01); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode)
|
||||
+ printk("***** Xtal 40MHz *****\n");
|
||||
+ } else { // 25MHz | 20MHz Xtal
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 6, 2, 0x00); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode)
|
||||
+ if (reg >= 6) {
|
||||
+ printk("***** Xtal 25MHz *****\n");
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4bc), 4, 2, 0x01); // RG_PE1_H_PLL_FBKSEL //Feedback clock select
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x49c), 0,31, 0x18000000); // RG_PE1_H_LCDDS_PCW_NCPO //DDS NCPO PCW (for host mode)
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a4), 0,16, 0x18d); // RG_PE1_H_LCDDS_SSC_PRD //DDS SSC dither period control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 0,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA //DDS SSC dither amplitude control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 16,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA1 //DDS SSC dither amplitude control for initial
|
||||
+ } else {
|
||||
+ printk("***** Xtal 20MHz *****\n");
|
||||
+ }
|
||||
+ }
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a0), 5, 1, 0x01); // RG_PE1_LCDDS_CLK_PH_INV //DDS clock inversion
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 22, 2, 0x02); // RG_PE1_H_PLL_BC
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 18, 4, 0x06); // RG_PE1_H_PLL_BP
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 12, 4, 0x02); // RG_PE1_H_PLL_IR
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 8, 4, 0x01); // RG_PE1_H_PLL_IC
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4ac), 16, 3, 0x00); // RG_PE1_H_PLL_BR
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 1, 3, 0x02); // RG_PE1_PLL_DIVEN
|
||||
+ if(reg <= 5 && reg >= 3) { // 40MHz Xtal
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x414), 6, 2, 0x01); // rg_pe1_mstckdiv //value of da_pe1_mstckdiv when force mode enable
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x414), 5, 1, 0x01); // rg_pe1_frc_mstckdiv //force mode enable of da_pe1_mstckdiv
|
||||
+ }
|
||||
+ /* Enable PHY and disable force mode */
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 5, 1, 0x01); // rg_pe1_phy_en //Port 0 enable
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 5, 1, 0x01); // rg_pe1_phy_en //Port 1 enable
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 0 disable control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 1 disable control
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ /* Set PCIe Port2 PHY to disable SSC */
|
||||
+ /* Debug Xtal Type */
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x400), 8, 1, 0x01); // rg_pe1_frc_h_xtal_type
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x400), 9, 2, 0x00); // rg_pe1_h_xtal_type
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 0 enable control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 5, 1, 0x00); // rg_pe1_phy_en //Port 0 disable
|
||||
+ if(reg <= 5 && reg >= 3) { // 40MHz Xtal
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 6, 2, 0x01); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode)
|
||||
+ } else { // 25MHz | 20MHz Xtal
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 6, 2, 0x00); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode)
|
||||
+ if (reg >= 6) { // 25MHz Xtal
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4bc), 4, 2, 0x01); // RG_PE1_H_PLL_FBKSEL //Feedback clock select
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x49c), 0,31, 0x18000000); // RG_PE1_H_LCDDS_PCW_NCPO //DDS NCPO PCW (for host mode)
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a4), 0,16, 0x18d); // RG_PE1_H_LCDDS_SSC_PRD //DDS SSC dither period control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 0,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA //DDS SSC dither amplitude control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 16,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA1 //DDS SSC dither amplitude control for initial
|
||||
+ }
|
||||
+ }
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a0), 5, 1, 0x01); // RG_PE1_LCDDS_CLK_PH_INV //DDS clock inversion
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 22, 2, 0x02); // RG_PE1_H_PLL_BC
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 18, 4, 0x06); // RG_PE1_H_PLL_BP
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 12, 4, 0x02); // RG_PE1_H_PLL_IR
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 8, 4, 0x01); // RG_PE1_H_PLL_IC
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4ac), 16, 3, 0x00); // RG_PE1_H_PLL_BR
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 1, 3, 0x02); // RG_PE1_PLL_DIVEN
|
||||
+ if(reg <= 5 && reg >= 3) { // 40MHz Xtal
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x414), 6, 2, 0x01); // rg_pe1_mstckdiv //value of da_pe1_mstckdiv when force mode enable
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x414), 5, 1, 0x01); // rg_pe1_frc_mstckdiv //force mode enable of da_pe1_mstckdiv
|
||||
+ }
|
||||
+ /* Enable PHY and disable force mode */
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 5, 1, 0x01); // rg_pe1_phy_en //Port 0 enable
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 0 disable control
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+void setup_cm_memory_region(struct resource *mem_resource)
|
||||
+{
|
||||
+ resource_size_t mask;
|
||||
+ if (mips_cps_numiocu(0)) {
|
||||
+ /* FIXME: hardware doesn't accept mask values with 1s after
|
||||
+ 0s (e.g. 0xffef), so it would be great to warn if that's
|
||||
+ about to happen */
|
||||
+ mask = ~(mem_resource->end - mem_resource->start);
|
||||
+
|
||||
+ write_gcr_reg1_base(mem_resource->start);
|
||||
+ write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0);
|
||||
+ printk("PCI coherence region base: 0x%08lx, mask/settings: 0x%08lx\n",
|
||||
+ read_gcr_reg1_base(),
|
||||
+ read_gcr_reg1_mask());
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int mt7621_pci_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ unsigned long val = 0;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < 3; i++)
|
||||
+ pcie_irq[i] = irq_of_parse_and_map(pdev->dev.of_node, i);
|
||||
+
|
||||
+ iomem_resource.start = 0;
|
||||
+ iomem_resource.end= ~0;
|
||||
+ ioport_resource.start= 0;
|
||||
+ ioport_resource.end = ~0;
|
||||
+
|
||||
+#if defined (CONFIG_PCIE_PORT0)
|
||||
+ val = RALINK_PCIE0_RST;
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT1)
|
||||
+ val |= RALINK_PCIE1_RST;
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ val |= RALINK_PCIE2_RST;
|
||||
+#endif
|
||||
+ ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST | RALINK_PCIE1_RST | RALINK_PCIE2_RST);
|
||||
+ printk("pull PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL);
|
||||
+#if defined GPIO_PERST /* add GPIO control instead of PERST_N */ /*chhung*/
|
||||
+ *(unsigned int *)(0xbe000060) &= ~(0x3<<10 | 0x3<<3);
|
||||
+ *(unsigned int *)(0xbe000060) |= 0x1<<10 | 0x1<<3;
|
||||
+ mdelay(100);
|
||||
+ *(unsigned int *)(0xbe000600) |= 0x1<<19 | 0x1<<8 | 0x1<<7; // use GPIO19/GPIO8/GPIO7 (PERST_N/UART_RXD3/UART_TXD3)
|
||||
+ mdelay(100);
|
||||
+ *(unsigned int *)(0xbe000620) &= ~(0x1<<19 | 0x1<<8 | 0x1<<7); // clear DATA
|
||||
+
|
||||
+ mdelay(100);
|
||||
+#else
|
||||
+ *(unsigned int *)(0xbe000060) &= ~0x00000c00;
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT0)
|
||||
+ val = RALINK_PCIE0_RST;
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT1)
|
||||
+ val |= RALINK_PCIE1_RST;
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ val |= RALINK_PCIE2_RST;
|
||||
+#endif
|
||||
+ DEASSERT_SYSRST_PCIE(val);
|
||||
+ printk("release PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL);
|
||||
+
|
||||
+ if ((*(unsigned int *)(0xbe00000c)&0xFFFF) == 0x0101) // MT7621 E2
|
||||
+ bypass_pipe_rst();
|
||||
+ set_phy_for_ssc();
|
||||
+ printk("release PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL);
|
||||
+
|
||||
+#if defined (CONFIG_PCIE_PORT0)
|
||||
+ read_config(0, 0, 0, 0x70c, &val);
|
||||
+ printk("Port 0 N_FTS = %x\n", (unsigned int)val);
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT1)
|
||||
+ read_config(0, 1, 0, 0x70c, &val);
|
||||
+ printk("Port 1 N_FTS = %x\n", (unsigned int)val);
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ read_config(0, 2, 0, 0x70c, &val);
|
||||
+ printk("Port 2 N_FTS = %x\n", (unsigned int)val);
|
||||
+#endif
|
||||
+
|
||||
+ RALINK_RSTCTRL = (RALINK_RSTCTRL | RALINK_PCIE_RST);
|
||||
+ RALINK_SYSCFG1 &= ~(0x30);
|
||||
+ RALINK_SYSCFG1 |= (2<<4);
|
||||
+ RALINK_PCIE_CLK_GEN &= 0x7fffffff;
|
||||
+ RALINK_PCIE_CLK_GEN1 &= 0x80ffffff;
|
||||
+ RALINK_PCIE_CLK_GEN1 |= 0xa << 24;
|
||||
+ RALINK_PCIE_CLK_GEN |= 0x80000000;
|
||||
+ mdelay(50);
|
||||
+ RALINK_RSTCTRL = (RALINK_RSTCTRL & ~RALINK_PCIE_RST);
|
||||
+
|
||||
+
|
||||
+#if defined GPIO_PERST /* add GPIO control instead of PERST_N */ /*chhung*/
|
||||
+ *(unsigned int *)(0xbe000620) |= 0x1<<19 | 0x1<<8 | 0x1<<7; // set DATA
|
||||
+ mdelay(100);
|
||||
+#else
|
||||
+ RALINK_PCI_PCICFG_ADDR &= ~(1<<1); //de-assert PERST
|
||||
+#endif
|
||||
+ mdelay(500);
|
||||
+
|
||||
+
|
||||
+ mdelay(500);
|
||||
+#if defined (CONFIG_PCIE_PORT0)
|
||||
+ if(( RALINK_PCI0_STATUS & 0x1) == 0)
|
||||
+ {
|
||||
+ printk("PCIE0 no card, disable it(RST&CLK)\n");
|
||||
+ ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST);
|
||||
+ RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE0_CLK_EN);
|
||||
+ pcie_link_status &= ~(1<<0);
|
||||
+ } else {
|
||||
+ pcie_link_status |= 1<<0;
|
||||
+ RALINK_PCI_PCIMSK_ADDR |= (1<<20); // enable pcie1 interrupt
|
||||
+ }
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT1)
|
||||
+ if(( RALINK_PCI1_STATUS & 0x1) == 0)
|
||||
+ {
|
||||
+ printk("PCIE1 no card, disable it(RST&CLK)\n");
|
||||
+ ASSERT_SYSRST_PCIE(RALINK_PCIE1_RST);
|
||||
+ RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE1_CLK_EN);
|
||||
+ pcie_link_status &= ~(1<<1);
|
||||
+ } else {
|
||||
+ pcie_link_status |= 1<<1;
|
||||
+ RALINK_PCI_PCIMSK_ADDR |= (1<<21); // enable pcie1 interrupt
|
||||
+ }
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ if (( RALINK_PCI2_STATUS & 0x1) == 0) {
|
||||
+ printk("PCIE2 no card, disable it(RST&CLK)\n");
|
||||
+ ASSERT_SYSRST_PCIE(RALINK_PCIE2_RST);
|
||||
+ RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE2_CLK_EN);
|
||||
+ pcie_link_status &= ~(1<<2);
|
||||
+ } else {
|
||||
+ pcie_link_status |= 1<<2;
|
||||
+ RALINK_PCI_PCIMSK_ADDR |= (1<<22); // enable pcie2 interrupt
|
||||
+ }
|
||||
+#endif
|
||||
+ if (pcie_link_status == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+/*
|
||||
+pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num
|
||||
+3'b000 x x x
|
||||
+3'b001 x x 0
|
||||
+3'b010 x 0 x
|
||||
+3'b011 x 1 0
|
||||
+3'b100 0 x x
|
||||
+3'b101 1 x 0
|
||||
+3'b110 1 0 x
|
||||
+3'b111 2 1 0
|
||||
+*/
|
||||
+ switch(pcie_link_status) {
|
||||
+ case 2:
|
||||
+ RALINK_PCI_PCICFG_ADDR &= ~0x00ff0000;
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x1 << 16; //port0
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x0 << 20; //port1
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000;
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x1 << 16; //port0
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x2 << 20; //port1
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x0 << 24; //port2
|
||||
+ break;
|
||||
+ case 5:
|
||||
+ RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000;
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x0 << 16; //port0
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x2 << 20; //port1
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x1 << 24; //port2
|
||||
+ break;
|
||||
+ case 6:
|
||||
+ RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000;
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x2 << 16; //port0
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x0 << 20; //port1
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x1 << 24; //port2
|
||||
+ break;
|
||||
+ }
|
||||
+ printk(" -> %x\n", RALINK_PCI_PCICFG_ADDR);
|
||||
+ //printk(" RALINK_PCI_ARBCTL = %x\n", RALINK_PCI_ARBCTL);
|
||||
+
|
||||
+/*
|
||||
+ ioport_resource.start = mt7621_res_pci_io1.start;
|
||||
+ ioport_resource.end = mt7621_res_pci_io1.end;
|
||||
+*/
|
||||
+
|
||||
+ RALINK_PCI_MEMBASE = 0xffffffff; //RALINK_PCI_MM_MAP_BASE;
|
||||
+ RALINK_PCI_IOBASE = RALINK_PCI_IO_MAP_BASE;
|
||||
+
|
||||
+#if defined (CONFIG_PCIE_PORT0)
|
||||
+ //PCIe0
|
||||
+ if((pcie_link_status & 0x1) != 0) {
|
||||
+ RALINK_PCI0_BAR0SETUP_ADDR = 0x7FFF0001; //open 7FFF:2G; ENABLE
|
||||
+ RALINK_PCI0_IMBASEBAR0_ADDR = MEMORY_BASE;
|
||||
+ RALINK_PCI0_CLASS = 0x06040001;
|
||||
+ printk("PCIE0 enabled\n");
|
||||
+ }
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT1)
|
||||
+ //PCIe1
|
||||
+ if ((pcie_link_status & 0x2) != 0) {
|
||||
+ RALINK_PCI1_BAR0SETUP_ADDR = 0x7FFF0001; //open 7FFF:2G; ENABLE
|
||||
+ RALINK_PCI1_IMBASEBAR0_ADDR = MEMORY_BASE;
|
||||
+ RALINK_PCI1_CLASS = 0x06040001;
|
||||
+ printk("PCIE1 enabled\n");
|
||||
+ }
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ //PCIe2
|
||||
+ if ((pcie_link_status & 0x4) != 0) {
|
||||
+ RALINK_PCI2_BAR0SETUP_ADDR = 0x7FFF0001; //open 7FFF:2G; ENABLE
|
||||
+ RALINK_PCI2_IMBASEBAR0_ADDR = MEMORY_BASE;
|
||||
+ RALINK_PCI2_CLASS = 0x06040001;
|
||||
+ printk("PCIE2 enabled\n");
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+ switch(pcie_link_status) {
|
||||
+ case 7:
|
||||
+ read_config(0, 2, 0, 0x4, &val);
|
||||
+ write_config(0, 2, 0, 0x4, val|0x4);
|
||||
+ // write_config(0, 1, 0, 0x4, val|0x7);
|
||||
+ read_config(0, 2, 0, 0x70c, &val);
|
||||
+ val &= ~(0xff)<<8;
|
||||
+ val |= 0x50<<8;
|
||||
+ write_config(0, 2, 0, 0x70c, val);
|
||||
+ case 3:
|
||||
+ case 5:
|
||||
+ case 6:
|
||||
+ read_config(0, 1, 0, 0x4, &val);
|
||||
+ write_config(0, 1, 0, 0x4, val|0x4);
|
||||
+ // write_config(0, 1, 0, 0x4, val|0x7);
|
||||
+ read_config(0, 1, 0, 0x70c, &val);
|
||||
+ val &= ~(0xff)<<8;
|
||||
+ val |= 0x50<<8;
|
||||
+ write_config(0, 1, 0, 0x70c, val);
|
||||
+ default:
|
||||
+ read_config(0, 0, 0, 0x4, &val);
|
||||
+ write_config(0, 0, 0, 0x4, val|0x4); //bus master enable
|
||||
+ // write_config(0, 0, 0, 0x4, val|0x7); //bus master enable
|
||||
+ read_config(0, 0, 0, 0x70c, &val);
|
||||
+ val &= ~(0xff)<<8;
|
||||
+ val |= 0x50<<8;
|
||||
+ write_config(0, 0, 0, 0x70c, val);
|
||||
+ }
|
||||
+
|
||||
+ pci_load_of_ranges(&mt7621_controller, pdev->dev.of_node);
|
||||
+ setup_cm_memory_region(mt7621_controller.mem_resource);
|
||||
+ register_pci_controller(&mt7621_controller);
|
||||
+ return 0;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+int pcibios_plat_dev_init(struct pci_dev *dev)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mt7621_pci_ids[] = {
|
||||
+ { .compatible = "mediatek,mt7621-pci" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mt7621_pci_ids);
|
||||
+
|
||||
+static struct platform_driver mt7621_pci_driver = {
|
||||
+ .probe = mt7621_pci_probe,
|
||||
+ .driver = {
|
||||
+ .name = "mt7621-pci",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = of_match_ptr(mt7621_pci_ids),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init mt7621_pci_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&mt7621_pci_driver);
|
||||
+}
|
||||
+
|
||||
+arch_initcall(mt7621_pci_init);
|
|
@ -1,82 +0,0 @@
|
|||
From ce3d4a4111a5f7e6b4e74bceae5faa6ce388e8ec Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 14 Jul 2013 23:08:11 +0200
|
||||
Subject: [PATCH 05/53] MIPS: use set_mode() to enable/disable the cevt-r4k
|
||||
irq
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/ralink/Kconfig | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
--- a/arch/mips/ralink/Kconfig
|
||||
+++ b/arch/mips/ralink/Kconfig
|
||||
@@ -1,12 +1,17 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
if RALINK
|
||||
|
||||
+config CEVT_SYSTICK_QUIRK
|
||||
+ bool
|
||||
+ default n
|
||||
+
|
||||
config CLKEVT_RT3352
|
||||
bool
|
||||
depends on SOC_RT305X || SOC_MT7620
|
||||
default y
|
||||
select TIMER_OF
|
||||
select CLKSRC_MMIO
|
||||
+ select CEVT_SYSTICK_QUIRK
|
||||
|
||||
config RALINK_ILL_ACC
|
||||
bool
|
||||
--- a/arch/mips/kernel/cevt-r4k.c
|
||||
+++ b/arch/mips/kernel/cevt-r4k.c
|
||||
@@ -15,6 +15,26 @@
|
||||
#include <asm/time.h>
|
||||
#include <asm/cevt-r4k.h>
|
||||
|
||||
+static int mips_state_oneshot(struct clock_event_device *evt)
|
||||
+{
|
||||
+ if (!cp0_timer_irq_installed) {
|
||||
+ cp0_timer_irq_installed = 1;
|
||||
+ setup_irq(evt->irq, &c0_compare_irqaction);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mips_state_shutdown(struct clock_event_device *evt)
|
||||
+{
|
||||
+ if (cp0_timer_irq_installed) {
|
||||
+ cp0_timer_irq_installed = 0;
|
||||
+ remove_irq(evt->irq, &c0_compare_irqaction);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int mips_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
@@ -281,17 +301,21 @@ int r4k_clockevent_init(void)
|
||||
cd->rating = 300;
|
||||
cd->irq = irq;
|
||||
cd->cpumask = cpumask_of(cpu);
|
||||
+ cd->set_state_shutdown = mips_state_shutdown;
|
||||
+ cd->set_state_oneshot = mips_state_oneshot;
|
||||
cd->set_next_event = mips_next_event;
|
||||
cd->event_handler = mips_event_handler;
|
||||
|
||||
clockevents_config_and_register(cd, mips_hpt_frequency, min_delta, 0x7fffffff);
|
||||
|
||||
+#ifndef CONFIG_CEVT_SYSTICK_QUIRK
|
||||
if (cp0_timer_irq_installed)
|
||||
return 0;
|
||||
|
||||
cp0_timer_irq_installed = 1;
|
||||
|
||||
setup_irq(irq, &c0_compare_irqaction);
|
||||
+#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,200 +0,0 @@
|
|||
From bd30f19a006fb52bac80c6463c49dd2f4159f4ac Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 28 Jul 2013 16:26:41 +0200
|
||||
Subject: [PATCH 06/53] MIPS: ralink: add cpu frequency scaling
|
||||
|
||||
This feature will break udelay() and cause the delay loop to have longer delays
|
||||
when the frequency is scaled causing a performance hit.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/ralink/cevt-rt3352.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 38 insertions(+)
|
||||
|
||||
--- a/arch/mips/ralink/cevt-rt3352.c
|
||||
+++ b/arch/mips/ralink/cevt-rt3352.c
|
||||
@@ -29,6 +29,10 @@
|
||||
/* enable the counter */
|
||||
#define CFG_CNT_EN 0x1
|
||||
|
||||
+/* mt7620 frequency scaling defines */
|
||||
+#define CLK_LUT_CFG 0x40
|
||||
+#define SLEEP_EN BIT(31)
|
||||
+
|
||||
struct systick_device {
|
||||
void __iomem *membase;
|
||||
struct clock_event_device dev;
|
||||
@@ -36,21 +40,53 @@ struct systick_device {
|
||||
int freq_scale;
|
||||
};
|
||||
|
||||
+static void (*systick_freq_scaling)(struct systick_device *sdev, int status);
|
||||
+
|
||||
static int systick_set_oneshot(struct clock_event_device *evt);
|
||||
static int systick_shutdown(struct clock_event_device *evt);
|
||||
|
||||
+static inline void mt7620_freq_scaling(struct systick_device *sdev, int status)
|
||||
+{
|
||||
+ if (sdev->freq_scale == status)
|
||||
+ return;
|
||||
+
|
||||
+ sdev->freq_scale = status;
|
||||
+
|
||||
+ pr_info("%s: %s autosleep mode\n", sdev->dev.name,
|
||||
+ (status) ? ("enable") : ("disable"));
|
||||
+ if (status)
|
||||
+ rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) | SLEEP_EN, CLK_LUT_CFG);
|
||||
+ else
|
||||
+ rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) & ~SLEEP_EN, CLK_LUT_CFG);
|
||||
+}
|
||||
+
|
||||
+static inline unsigned int read_count(struct systick_device *sdev)
|
||||
+{
|
||||
+ return ioread32(sdev->membase + SYSTICK_COUNT);
|
||||
+}
|
||||
+
|
||||
+static inline unsigned int read_compare(struct systick_device *sdev)
|
||||
+{
|
||||
+ return ioread32(sdev->membase + SYSTICK_COMPARE);
|
||||
+}
|
||||
+
|
||||
+static inline void write_compare(struct systick_device *sdev, unsigned int val)
|
||||
+{
|
||||
+ iowrite32(val, sdev->membase + SYSTICK_COMPARE);
|
||||
+}
|
||||
+
|
||||
static int systick_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
struct systick_device *sdev;
|
||||
- u32 count;
|
||||
+ int res;
|
||||
|
||||
sdev = container_of(evt, struct systick_device, dev);
|
||||
- count = ioread32(sdev->membase + SYSTICK_COUNT);
|
||||
- count = (count + delta) % SYSTICK_FREQ;
|
||||
- iowrite32(count, sdev->membase + SYSTICK_COMPARE);
|
||||
+ delta += read_count(sdev);
|
||||
+ write_compare(sdev, delta);
|
||||
+ res = ((int)(read_count(sdev) - delta) >= 0) ? -ETIME : 0;
|
||||
|
||||
- return 0;
|
||||
+ return res;
|
||||
}
|
||||
|
||||
static void systick_event_handler(struct clock_event_device *dev)
|
||||
@@ -60,20 +96,25 @@ static void systick_event_handler(struct
|
||||
|
||||
static irqreturn_t systick_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
- struct clock_event_device *dev = (struct clock_event_device *) dev_id;
|
||||
+ int ret = 0;
|
||||
+ struct clock_event_device *cdev;
|
||||
+ struct systick_device *sdev;
|
||||
|
||||
- dev->event_handler(dev);
|
||||
+ if (read_c0_cause() & STATUSF_IP7) {
|
||||
+ cdev = (struct clock_event_device *) dev_id;
|
||||
+ sdev = container_of(cdev, struct systick_device, dev);
|
||||
+
|
||||
+ /* Clear Count/Compare Interrupt */
|
||||
+ write_compare(sdev, read_compare(sdev));
|
||||
+ cdev->event_handler(cdev);
|
||||
+ ret = 1;
|
||||
+ }
|
||||
|
||||
- return IRQ_HANDLED;
|
||||
+ return IRQ_RETVAL(ret);
|
||||
}
|
||||
|
||||
static struct systick_device systick = {
|
||||
.dev = {
|
||||
- /*
|
||||
- * cevt-r4k uses 300, make sure systick
|
||||
- * gets used if available
|
||||
- */
|
||||
- .rating = 310,
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_next_event = systick_next_event,
|
||||
.set_state_shutdown = systick_shutdown,
|
||||
@@ -95,9 +136,15 @@ static int systick_shutdown(struct clock
|
||||
sdev = container_of(evt, struct systick_device, dev);
|
||||
|
||||
if (sdev->irq_requested)
|
||||
- free_irq(systick.dev.irq, &systick_irqaction);
|
||||
+ remove_irq(systick.dev.irq, &systick_irqaction);
|
||||
sdev->irq_requested = 0;
|
||||
- iowrite32(0, systick.membase + SYSTICK_CONFIG);
|
||||
+ iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG);
|
||||
+
|
||||
+ if (systick_freq_scaling)
|
||||
+ systick_freq_scaling(sdev, 0);
|
||||
+
|
||||
+ if (systick_freq_scaling)
|
||||
+ systick_freq_scaling(sdev, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -117,34 +164,48 @@ static int systick_set_oneshot(struct cl
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const struct of_device_id systick_match[] = {
|
||||
+ { .compatible = "ralink,mt7620a-systick", .data = mt7620_freq_scaling},
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
static int __init ralink_systick_init(struct device_node *np)
|
||||
{
|
||||
+ const struct of_device_id *match;
|
||||
+ int rating = 200;
|
||||
int ret;
|
||||
|
||||
systick.membase = of_iomap(np, 0);
|
||||
if (!systick.membase)
|
||||
return -ENXIO;
|
||||
|
||||
- systick_irqaction.name = np->name;
|
||||
- systick.dev.name = np->name;
|
||||
- clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60);
|
||||
- systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev);
|
||||
- systick.dev.max_delta_ticks = 0x7fff;
|
||||
- systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev);
|
||||
- systick.dev.min_delta_ticks = 0x3;
|
||||
+ match = of_match_node(systick_match, np);
|
||||
+ if (match) {
|
||||
+ systick_freq_scaling = match->data;
|
||||
+ /*
|
||||
+ * cevt-r4k uses 300, make sure systick
|
||||
+ * gets used if available
|
||||
+ */
|
||||
+ rating = 310;
|
||||
+ }
|
||||
+
|
||||
+ /* enable counter than register clock source */
|
||||
+ iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG);
|
||||
+ clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
|
||||
+ SYSTICK_FREQ, rating, 16, clocksource_mmio_readl_up);
|
||||
+
|
||||
+ /* register clock event */
|
||||
systick.dev.irq = irq_of_parse_and_map(np, 0);
|
||||
if (!systick.dev.irq) {
|
||||
pr_err("%s: request_irq failed", np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
|
||||
- SYSTICK_FREQ, 301, 16,
|
||||
- clocksource_mmio_readl_up);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- clockevents_register_device(&systick.dev);
|
||||
+ systick_irqaction.name = np->name;
|
||||
+ systick.dev.name = np->name;
|
||||
+ systick.dev.rating = rating;
|
||||
+ systick.dev.cpumask = cpumask_of(0);
|
||||
+ clockevents_config_and_register(&systick.dev, SYSTICK_FREQ, 0x3, 0x7fff);
|
||||
|
||||
pr_info("%s: running - mult: %d, shift: %d\n",
|
||||
np->name, systick.dev.mult, systick.dev.shift);
|
|
@ -1,21 +0,0 @@
|
|||
From 67b7bff0fd364c194e653f69baa623ba2141bd4c Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 4 Aug 2014 18:46:02 +0200
|
||||
Subject: [PATCH 07/53] MIPS: ralink: copy the commandline from the devicetree
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/ralink/of.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/arch/mips/ralink/of.c
|
||||
+++ b/arch/mips/ralink/of.c
|
||||
@@ -82,6 +82,8 @@ void __init plat_mem_setup(void)
|
||||
|
||||
__dt_setup_arch(dtb);
|
||||
|
||||
+ strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
|
||||
+
|
||||
of_scan_flat_dt(early_init_dt_find_memory, NULL);
|
||||
if (memory_dtb)
|
||||
of_scan_flat_dt(early_init_dt_scan_memory, NULL);
|
|
@ -1,28 +0,0 @@
|
|||
From 7768798964eb0e4f95eaecffb93b5d0ca28a38af Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sat, 3 Jun 2017 20:00:03 +0200
|
||||
Subject: [PATCH] MIPS: pci-mt7620: enabled PCIe on MT7688
|
||||
To: linux-mips@linux-mips.org,
|
||||
John Crispin <john@phrozen.org>
|
||||
Cc: Wei Yongjun <yongjun_wei@trendmicro.com.cn>,
|
||||
Ralf Baechle <ralf@linux-mips.org>,
|
||||
linux-mediatek@lists.infradead.org
|
||||
|
||||
Use PCIe support for MT7628AN also on MT7688.
|
||||
Tested on WRTNODE2R.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
arch/mips/pci/pci-mt7620.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/arch/mips/pci/pci-mt7620.c
|
||||
+++ b/arch/mips/pci/pci-mt7620.c
|
||||
@@ -316,6 +316,7 @@ static int mt7620_pci_probe(struct platf
|
||||
break;
|
||||
|
||||
case MT762X_SOC_MT7628AN:
|
||||
+ case MT762X_SOC_MT7688:
|
||||
if (mt7628_pci_hw_init(pdev))
|
||||
return -1;
|
||||
break;
|
|
@ -1,28 +0,0 @@
|
|||
From 5ede027f6c4a57ed25da872420508b7f1168b36b Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 7 Dec 2015 17:15:32 +0100
|
||||
Subject: [PATCH 13/53] owrt: hack: fix mt7688 cache issue
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/kernel/setup.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/mips/kernel/setup.c
|
||||
+++ b/arch/mips/kernel/setup.c
|
||||
@@ -910,7 +910,6 @@ static void __init arch_mem_init(char **
|
||||
crashk_res.end - crashk_res.start + 1,
|
||||
BOOTMEM_DEFAULT);
|
||||
#endif
|
||||
- device_tree_init();
|
||||
|
||||
/*
|
||||
* In order to reduce the possibility of kernel panic when failed to
|
||||
@@ -1036,6 +1035,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
cpu_cache_init();
|
||||
paging_init();
|
||||
+ device_tree_init();
|
||||
}
|
||||
|
||||
unsigned long kernelsp[NR_CPUS];
|
|
@ -1,25 +0,0 @@
|
|||
From 9e6ce539092a1dd605a20bf73c655a9de58d8641 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 7 Dec 2015 17:18:05 +0100
|
||||
Subject: [PATCH 15/53] arch: mips: do not select illegal access driver by
|
||||
default
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/ralink/Kconfig | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/arch/mips/ralink/Kconfig
|
||||
+++ b/arch/mips/ralink/Kconfig
|
||||
@@ -14,9 +14,9 @@ config CLKEVT_RT3352
|
||||
select CEVT_SYSTICK_QUIRK
|
||||
|
||||
config RALINK_ILL_ACC
|
||||
- bool
|
||||
+ bool "illegal access irq"
|
||||
depends on SOC_RT305X
|
||||
- default y
|
||||
+ default n
|
||||
|
||||
config IRQ_INTC
|
||||
bool
|
|
@ -1,165 +0,0 @@
|
|||
From 4267880319bc1a2270d352e0ded6d6386242a7ef Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Tue, 12 Aug 2014 20:49:27 +0200
|
||||
Subject: [PATCH 24/53] GPIO: add named gpio exports
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/gpio/gpiolib-of.c | 68 +++++++++++++++++++++++++++++++++++++++++
|
||||
drivers/gpio/gpiolib-sysfs.c | 10 +++++-
|
||||
include/asm-generic/gpio.h | 6 ++++
|
||||
include/linux/gpio/consumer.h | 8 +++++
|
||||
4 files changed, 91 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/gpio/gpiolib-of.c
|
||||
+++ b/drivers/gpio/gpiolib-of.c
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/platform_device.h>
|
||||
|
||||
#include "gpiolib.h"
|
||||
|
||||
@@ -513,3 +515,68 @@ void of_gpiochip_remove(struct gpio_chip
|
||||
gpiochip_remove_pin_ranges(chip);
|
||||
of_node_put(chip->of_node);
|
||||
}
|
||||
+
|
||||
+static struct of_device_id gpio_export_ids[] = {
|
||||
+ { .compatible = "gpio-export" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+
|
||||
+static int of_gpio_export_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device_node *np = pdev->dev.of_node;
|
||||
+ struct device_node *cnp;
|
||||
+ u32 val;
|
||||
+ int nb = 0;
|
||||
+
|
||||
+ for_each_child_of_node(np, cnp) {
|
||||
+ const char *name = NULL;
|
||||
+ int gpio;
|
||||
+ bool dmc;
|
||||
+ int max_gpio = 1;
|
||||
+ int i;
|
||||
+
|
||||
+ of_property_read_string(cnp, "gpio-export,name", &name);
|
||||
+
|
||||
+ if (!name)
|
||||
+ max_gpio = of_gpio_count(cnp);
|
||||
+
|
||||
+ for (i = 0; i < max_gpio; i++) {
|
||||
+ unsigned flags = 0;
|
||||
+ enum of_gpio_flags of_flags;
|
||||
+
|
||||
+ gpio = of_get_gpio_flags(cnp, i, &of_flags);
|
||||
+ if (!gpio_is_valid(gpio))
|
||||
+ return gpio;
|
||||
+
|
||||
+ if (of_flags == OF_GPIO_ACTIVE_LOW)
|
||||
+ flags |= GPIOF_ACTIVE_LOW;
|
||||
+
|
||||
+ if (!of_property_read_u32(cnp, "gpio-export,output", &val))
|
||||
+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
|
||||
+ else
|
||||
+ flags |= GPIOF_IN;
|
||||
+
|
||||
+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
|
||||
+ continue;
|
||||
+
|
||||
+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
|
||||
+ gpio_export_with_name(gpio, dmc, name);
|
||||
+ nb++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver gpio_export_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "gpio-export",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = of_match_ptr(gpio_export_ids),
|
||||
+ },
|
||||
+ .probe = of_gpio_export_probe,
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(gpio_export_driver);
|
||||
--- a/drivers/gpio/gpiolib-sysfs.c
|
||||
+++ b/drivers/gpio/gpiolib-sysfs.c
|
||||
@@ -553,7 +553,7 @@ static struct class gpio_class = {
|
||||
*
|
||||
* Returns zero on success, else an error.
|
||||
*/
|
||||
-int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
|
||||
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
|
||||
{
|
||||
struct gpio_chip *chip;
|
||||
struct gpio_device *gdev;
|
||||
@@ -615,6 +615,8 @@ int gpiod_export(struct gpio_desc *desc,
|
||||
offset = gpio_chip_hwgpio(desc);
|
||||
if (chip->names && chip->names[offset])
|
||||
ioname = chip->names[offset];
|
||||
+ if (name)
|
||||
+ ioname = name;
|
||||
|
||||
dev = device_create_with_groups(&gpio_class, &gdev->dev,
|
||||
MKDEV(0, 0), data, gpio_groups,
|
||||
@@ -636,6 +638,12 @@ err_unlock:
|
||||
gpiod_dbg(desc, "%s: status %d\n", __func__, status);
|
||||
return status;
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(__gpiod_export);
|
||||
+
|
||||
+int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
|
||||
+{
|
||||
+ return __gpiod_export(desc, direction_may_change, NULL);
|
||||
+}
|
||||
EXPORT_SYMBOL_GPL(gpiod_export);
|
||||
|
||||
static int match_export(struct device *dev, const void *desc)
|
||||
--- a/include/asm-generic/gpio.h
|
||||
+++ b/include/asm-generic/gpio.h
|
||||
@@ -127,6 +127,12 @@ static inline int gpio_export(unsigned g
|
||||
return gpiod_export(gpio_to_desc(gpio), direction_may_change);
|
||||
}
|
||||
|
||||
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
|
||||
+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
|
||||
+{
|
||||
+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name);
|
||||
+}
|
||||
+
|
||||
static inline int gpio_export_link(struct device *dev, const char *name,
|
||||
unsigned gpio)
|
||||
{
|
||||
--- a/include/linux/gpio/consumer.h
|
||||
+++ b/include/linux/gpio/consumer.h
|
||||
@@ -451,6 +451,7 @@ struct gpio_desc *devm_fwnode_get_gpiod_
|
||||
|
||||
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
|
||||
|
||||
+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
|
||||
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
|
||||
int gpiod_export_link(struct device *dev, const char *name,
|
||||
struct gpio_desc *desc);
|
||||
@@ -458,6 +459,13 @@ void gpiod_unexport(struct gpio_desc *de
|
||||
|
||||
#else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
|
||||
|
||||
+static inline int _gpiod_export(struct gpio_desc *desc,
|
||||
+ bool direction_may_change,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ return -ENOSYS;
|
||||
+}
|
||||
+
|
||||
static inline int gpiod_export(struct gpio_desc *desc,
|
||||
bool direction_may_change)
|
||||
{
|
|
@ -1,524 +0,0 @@
|
|||
From 7adbe9a88c33c6e362a10b109d963b5500a21f00 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 27 Jul 2014 09:34:05 +0100
|
||||
Subject: [PATCH 25/53] pinctrl: ralink: add pinctrl driver
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/Kconfig | 2 +
|
||||
drivers/pinctrl/Kconfig | 5 +
|
||||
drivers/pinctrl/Makefile | 1 +
|
||||
drivers/pinctrl/pinctrl-rt2880.c | 474 ++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 482 insertions(+)
|
||||
create mode 100644 drivers/pinctrl/pinctrl-rt2880.c
|
||||
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -629,6 +629,8 @@ config RALINK
|
||||
select CLKDEV_LOOKUP
|
||||
select ARCH_HAS_RESET_CONTROLLER
|
||||
select RESET_CONTROLLER
|
||||
+ select PINCTRL
|
||||
+ select PINCTRL_RT2880
|
||||
|
||||
config SGI_IP22
|
||||
bool "SGI IP22 (Indy/Indigo2)"
|
||||
--- a/drivers/pinctrl/Kconfig
|
||||
+++ b/drivers/pinctrl/Kconfig
|
||||
@@ -143,6 +143,11 @@ config PINCTRL_LPC18XX
|
||||
help
|
||||
Pinctrl driver for NXP LPC18xx/43xx System Control Unit (SCU).
|
||||
|
||||
+config PINCTRL_RT2880
|
||||
+ bool
|
||||
+ depends on RALINK
|
||||
+ select PINMUX
|
||||
+
|
||||
config PINCTRL_FALCON
|
||||
bool
|
||||
depends on SOC_FALCON
|
||||
--- a/drivers/pinctrl/Makefile
|
||||
+++ b/drivers/pinctrl/Makefile
|
||||
@@ -28,6 +28,7 @@ obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-
|
||||
obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o
|
||||
obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
|
||||
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
|
||||
+obj-$(CONFIG_PINCTRL_RT2880) += pinctrl-rt2880.o
|
||||
obj-$(CONFIG_PINCTRL_RZA1) += pinctrl-rza1.o
|
||||
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
|
||||
obj-$(CONFIG_PINCTRL_SIRF) += sirf/
|
||||
--- /dev/null
|
||||
+++ b/drivers/pinctrl/pinctrl-rt2880.c
|
||||
@@ -0,0 +1,472 @@
|
||||
+/*
|
||||
+ * linux/drivers/pinctrl/pinctrl-rt2880.c
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * publishhed by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/pinctrl/pinctrl.h>
|
||||
+#include <linux/pinctrl/pinconf.h>
|
||||
+#include <linux/pinctrl/pinmux.h>
|
||||
+#include <linux/pinctrl/consumer.h>
|
||||
+#include <linux/pinctrl/machine.h>
|
||||
+
|
||||
+#include <asm/mach-ralink/ralink_regs.h>
|
||||
+#include <asm/mach-ralink/pinmux.h>
|
||||
+#include <asm/mach-ralink/mt7620.h>
|
||||
+
|
||||
+#include "core.h"
|
||||
+
|
||||
+#define SYSC_REG_GPIO_MODE 0x60
|
||||
+#define SYSC_REG_GPIO_MODE2 0x64
|
||||
+
|
||||
+struct rt2880_priv {
|
||||
+ struct device *dev;
|
||||
+
|
||||
+ struct pinctrl_pin_desc *pads;
|
||||
+ struct pinctrl_desc *desc;
|
||||
+
|
||||
+ struct rt2880_pmx_func **func;
|
||||
+ int func_count;
|
||||
+
|
||||
+ struct rt2880_pmx_group *groups;
|
||||
+ const char **group_names;
|
||||
+ int group_count;
|
||||
+
|
||||
+ uint8_t *gpio;
|
||||
+ int max_pins;
|
||||
+};
|
||||
+
|
||||
+static int rt2880_get_group_count(struct pinctrl_dev *pctrldev)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+
|
||||
+ return p->group_count;
|
||||
+}
|
||||
+
|
||||
+static const char *rt2880_get_group_name(struct pinctrl_dev *pctrldev,
|
||||
+ unsigned group)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+
|
||||
+ if (group >= p->group_count)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return p->group_names[group];
|
||||
+}
|
||||
+
|
||||
+static int rt2880_get_group_pins(struct pinctrl_dev *pctrldev,
|
||||
+ unsigned group,
|
||||
+ const unsigned **pins,
|
||||
+ unsigned *num_pins)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+
|
||||
+ if (group >= p->group_count)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ *pins = p->groups[group].func[0].pins;
|
||||
+ *num_pins = p->groups[group].func[0].pin_count;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void rt2880_pinctrl_dt_free_map(struct pinctrl_dev *pctrldev,
|
||||
+ struct pinctrl_map *map, unsigned num_maps)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < num_maps; i++)
|
||||
+ if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN ||
|
||||
+ map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
|
||||
+ kfree(map[i].data.configs.configs);
|
||||
+ kfree(map);
|
||||
+}
|
||||
+
|
||||
+static void rt2880_pinctrl_pin_dbg_show(struct pinctrl_dev *pctrldev,
|
||||
+ struct seq_file *s,
|
||||
+ unsigned offset)
|
||||
+{
|
||||
+ seq_printf(s, "ralink pio");
|
||||
+}
|
||||
+
|
||||
+static void rt2880_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctrldev,
|
||||
+ struct device_node *np,
|
||||
+ struct pinctrl_map **map)
|
||||
+{
|
||||
+ const char *function;
|
||||
+ int func = of_property_read_string(np, "function", &function);
|
||||
+ int grps = of_property_count_strings(np, "groups");
|
||||
+ int i;
|
||||
+
|
||||
+ if (func || !grps)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < grps; i++) {
|
||||
+ const char *group;
|
||||
+
|
||||
+ of_property_read_string_index(np, "groups", i, &group);
|
||||
+
|
||||
+ (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
|
||||
+ (*map)->name = function;
|
||||
+ (*map)->data.mux.group = group;
|
||||
+ (*map)->data.mux.function = function;
|
||||
+ (*map)++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int rt2880_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrldev,
|
||||
+ struct device_node *np_config,
|
||||
+ struct pinctrl_map **map,
|
||||
+ unsigned *num_maps)
|
||||
+{
|
||||
+ int max_maps = 0;
|
||||
+ struct pinctrl_map *tmp;
|
||||
+ struct device_node *np;
|
||||
+
|
||||
+ for_each_child_of_node(np_config, np) {
|
||||
+ int ret = of_property_count_strings(np, "groups");
|
||||
+
|
||||
+ if (ret >= 0)
|
||||
+ max_maps += ret;
|
||||
+ }
|
||||
+
|
||||
+ if (!max_maps)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ *map = kzalloc(max_maps * sizeof(struct pinctrl_map), GFP_KERNEL);
|
||||
+ if (!*map)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ tmp = *map;
|
||||
+
|
||||
+ for_each_child_of_node(np_config, np)
|
||||
+ rt2880_pinctrl_dt_subnode_to_map(pctrldev, np, &tmp);
|
||||
+ *num_maps = max_maps;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct pinctrl_ops rt2880_pctrl_ops = {
|
||||
+ .get_groups_count = rt2880_get_group_count,
|
||||
+ .get_group_name = rt2880_get_group_name,
|
||||
+ .get_group_pins = rt2880_get_group_pins,
|
||||
+ .pin_dbg_show = rt2880_pinctrl_pin_dbg_show,
|
||||
+ .dt_node_to_map = rt2880_pinctrl_dt_node_to_map,
|
||||
+ .dt_free_map = rt2880_pinctrl_dt_free_map,
|
||||
+};
|
||||
+
|
||||
+static int rt2880_pmx_func_count(struct pinctrl_dev *pctrldev)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+
|
||||
+ return p->func_count;
|
||||
+}
|
||||
+
|
||||
+static const char *rt2880_pmx_func_name(struct pinctrl_dev *pctrldev,
|
||||
+ unsigned func)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+
|
||||
+ return p->func[func]->name;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_pmx_group_get_groups(struct pinctrl_dev *pctrldev,
|
||||
+ unsigned func,
|
||||
+ const char * const **groups,
|
||||
+ unsigned * const num_groups)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+
|
||||
+ if (p->func[func]->group_count == 1)
|
||||
+ *groups = &p->group_names[p->func[func]->groups[0]];
|
||||
+ else
|
||||
+ *groups = p->group_names;
|
||||
+
|
||||
+ *num_groups = p->func[func]->group_count;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_pmx_group_enable(struct pinctrl_dev *pctrldev,
|
||||
+ unsigned func,
|
||||
+ unsigned group)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+ u32 mode = 0;
|
||||
+ u32 reg = SYSC_REG_GPIO_MODE;
|
||||
+ int i;
|
||||
+ int shift;
|
||||
+
|
||||
+ /* dont allow double use */
|
||||
+ if (p->groups[group].enabled) {
|
||||
+ dev_err(p->dev, "%s is already enabled\n", p->groups[group].name);
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+
|
||||
+ p->groups[group].enabled = 1;
|
||||
+ p->func[func]->enabled = 1;
|
||||
+
|
||||
+ shift = p->groups[group].shift;
|
||||
+ if (shift >= 32) {
|
||||
+ shift -= 32;
|
||||
+ reg = SYSC_REG_GPIO_MODE2;
|
||||
+ }
|
||||
+ mode = rt_sysc_r32(reg);
|
||||
+ mode &= ~(p->groups[group].mask << shift);
|
||||
+
|
||||
+ /* mark the pins as gpio */
|
||||
+ for (i = 0; i < p->groups[group].func[0].pin_count; i++)
|
||||
+ p->gpio[p->groups[group].func[0].pins[i]] = 1;
|
||||
+
|
||||
+ /* function 0 is gpio and needs special handling */
|
||||
+ if (func == 0) {
|
||||
+ mode |= p->groups[group].gpio << shift;
|
||||
+ } else {
|
||||
+ for (i = 0; i < p->func[func]->pin_count; i++)
|
||||
+ p->gpio[p->func[func]->pins[i]] = 0;
|
||||
+ mode |= p->func[func]->value << shift;
|
||||
+ }
|
||||
+ rt_sysc_w32(mode, reg);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_pmx_group_gpio_request_enable(struct pinctrl_dev *pctrldev,
|
||||
+ struct pinctrl_gpio_range *range,
|
||||
+ unsigned pin)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+
|
||||
+ if (!p->gpio[pin]) {
|
||||
+ dev_err(p->dev, "pin %d is not set to gpio mux\n", pin);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct pinmux_ops rt2880_pmx_group_ops = {
|
||||
+ .get_functions_count = rt2880_pmx_func_count,
|
||||
+ .get_function_name = rt2880_pmx_func_name,
|
||||
+ .get_function_groups = rt2880_pmx_group_get_groups,
|
||||
+ .set_mux = rt2880_pmx_group_enable,
|
||||
+ .gpio_request_enable = rt2880_pmx_group_gpio_request_enable,
|
||||
+};
|
||||
+
|
||||
+static struct pinctrl_desc rt2880_pctrl_desc = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .name = "rt2880-pinmux",
|
||||
+ .pctlops = &rt2880_pctrl_ops,
|
||||
+ .pmxops = &rt2880_pmx_group_ops,
|
||||
+};
|
||||
+
|
||||
+static struct rt2880_pmx_func gpio_func = {
|
||||
+ .name = "gpio",
|
||||
+};
|
||||
+
|
||||
+static int rt2880_pinmux_index(struct rt2880_priv *p)
|
||||
+{
|
||||
+ struct rt2880_pmx_func **f;
|
||||
+ struct rt2880_pmx_group *mux = p->groups;
|
||||
+ int i, j, c = 0;
|
||||
+
|
||||
+ /* count the mux functions */
|
||||
+ while (mux->name) {
|
||||
+ p->group_count++;
|
||||
+ mux++;
|
||||
+ }
|
||||
+
|
||||
+ /* allocate the group names array needed by the gpio function */
|
||||
+ p->group_names = devm_kzalloc(p->dev, sizeof(char *) * p->group_count, GFP_KERNEL);
|
||||
+ if (!p->group_names)
|
||||
+ return -1;
|
||||
+
|
||||
+ for (i = 0; i < p->group_count; i++) {
|
||||
+ p->group_names[i] = p->groups[i].name;
|
||||
+ p->func_count += p->groups[i].func_count;
|
||||
+ }
|
||||
+
|
||||
+ /* we have a dummy function[0] for gpio */
|
||||
+ p->func_count++;
|
||||
+
|
||||
+ /* allocate our function and group mapping index buffers */
|
||||
+ f = p->func = devm_kzalloc(p->dev, sizeof(struct rt2880_pmx_func) * p->func_count, GFP_KERNEL);
|
||||
+ gpio_func.groups = devm_kzalloc(p->dev, sizeof(int) * p->group_count, GFP_KERNEL);
|
||||
+ if (!f || !gpio_func.groups)
|
||||
+ return -1;
|
||||
+
|
||||
+ /* add a backpointer to the function so it knows its group */
|
||||
+ gpio_func.group_count = p->group_count;
|
||||
+ for (i = 0; i < gpio_func.group_count; i++)
|
||||
+ gpio_func.groups[i] = i;
|
||||
+
|
||||
+ f[c] = &gpio_func;
|
||||
+ c++;
|
||||
+
|
||||
+ /* add remaining functions */
|
||||
+ for (i = 0; i < p->group_count; i++) {
|
||||
+ for (j = 0; j < p->groups[i].func_count; j++) {
|
||||
+ f[c] = &p->groups[i].func[j];
|
||||
+ f[c]->groups = devm_kzalloc(p->dev, sizeof(int), GFP_KERNEL);
|
||||
+ f[c]->groups[0] = i;
|
||||
+ f[c]->group_count = 1;
|
||||
+ c++;
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_pinmux_pins(struct rt2880_priv *p)
|
||||
+{
|
||||
+ int i, j;
|
||||
+
|
||||
+ /* loop over the functions and initialize the pins array. also work out the highest pin used */
|
||||
+ for (i = 0; i < p->func_count; i++) {
|
||||
+ int pin;
|
||||
+
|
||||
+ if (!p->func[i]->pin_count)
|
||||
+ continue;
|
||||
+
|
||||
+ p->func[i]->pins = devm_kzalloc(p->dev, sizeof(int) * p->func[i]->pin_count, GFP_KERNEL);
|
||||
+ for (j = 0; j < p->func[i]->pin_count; j++)
|
||||
+ p->func[i]->pins[j] = p->func[i]->pin_first + j;
|
||||
+
|
||||
+ pin = p->func[i]->pin_first + p->func[i]->pin_count;
|
||||
+ if (pin > p->max_pins)
|
||||
+ p->max_pins = pin;
|
||||
+ }
|
||||
+
|
||||
+ /* the buffer that tells us which pins are gpio */
|
||||
+ p->gpio = devm_kzalloc(p->dev,sizeof(uint8_t) * p->max_pins,
|
||||
+ GFP_KERNEL);
|
||||
+ /* the pads needed to tell pinctrl about our pins */
|
||||
+ p->pads = devm_kzalloc(p->dev,
|
||||
+ sizeof(struct pinctrl_pin_desc) * p->max_pins,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!p->pads || !p->gpio ) {
|
||||
+ dev_err(p->dev, "Failed to allocate gpio data\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ memset(p->gpio, 1, sizeof(uint8_t) * p->max_pins);
|
||||
+ for (i = 0; i < p->func_count; i++) {
|
||||
+ if (!p->func[i]->pin_count)
|
||||
+ continue;
|
||||
+
|
||||
+ for (j = 0; j < p->func[i]->pin_count; j++)
|
||||
+ p->gpio[p->func[i]->pins[j]] = 0;
|
||||
+ }
|
||||
+
|
||||
+ /* pin 0 is always a gpio */
|
||||
+ p->gpio[0] = 1;
|
||||
+
|
||||
+ /* set the pads */
|
||||
+ for (i = 0; i < p->max_pins; i++) {
|
||||
+ /* strlen("ioXY") + 1 = 5 */
|
||||
+ char *name = devm_kzalloc(p->dev, 5, GFP_KERNEL);
|
||||
+
|
||||
+ if (!name) {
|
||||
+ dev_err(p->dev, "Failed to allocate pad name\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ snprintf(name, 5, "io%d", i);
|
||||
+ p->pads[i].number = i;
|
||||
+ p->pads[i].name = name;
|
||||
+ }
|
||||
+ p->desc->pins = p->pads;
|
||||
+ p->desc->npins = p->max_pins;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_pinmux_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct rt2880_priv *p;
|
||||
+ struct pinctrl_dev *dev;
|
||||
+ struct device_node *np;
|
||||
+
|
||||
+ if (!rt2880_pinmux_data)
|
||||
+ return -ENOSYS;
|
||||
+
|
||||
+ /* setup the private data */
|
||||
+ p = devm_kzalloc(&pdev->dev, sizeof(struct rt2880_priv), GFP_KERNEL);
|
||||
+ if (!p)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ p->dev = &pdev->dev;
|
||||
+ p->desc = &rt2880_pctrl_desc;
|
||||
+ p->groups = rt2880_pinmux_data;
|
||||
+ platform_set_drvdata(pdev, p);
|
||||
+
|
||||
+ /* init the device */
|
||||
+ if (rt2880_pinmux_index(p)) {
|
||||
+ dev_err(&pdev->dev, "failed to load index\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (rt2880_pinmux_pins(p)) {
|
||||
+ dev_err(&pdev->dev, "failed to load pins\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ dev = pinctrl_register(p->desc, &pdev->dev, p);
|
||||
+ if (IS_ERR(dev))
|
||||
+ return PTR_ERR(dev);
|
||||
+
|
||||
+ /* finalize by adding gpio ranges for enables gpio controllers */
|
||||
+ for_each_compatible_node(np, NULL, "ralink,rt2880-gpio") {
|
||||
+ const __be32 *ngpio, *gpiobase;
|
||||
+ struct pinctrl_gpio_range *range;
|
||||
+ char *name;
|
||||
+
|
||||
+ if (!of_device_is_available(np))
|
||||
+ continue;
|
||||
+
|
||||
+ ngpio = of_get_property(np, "ralink,num-gpios", NULL);
|
||||
+ gpiobase = of_get_property(np, "ralink,gpio-base", NULL);
|
||||
+ if (!ngpio || !gpiobase) {
|
||||
+ dev_err(&pdev->dev, "failed to load chip info\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ range = devm_kzalloc(p->dev, sizeof(struct pinctrl_gpio_range) + 4, GFP_KERNEL);
|
||||
+ range->name = name = (char *) &range[1];
|
||||
+ sprintf(name, "pio");
|
||||
+ range->npins = __be32_to_cpu(*ngpio);
|
||||
+ range->base = __be32_to_cpu(*gpiobase);
|
||||
+ range->pin_base = range->base;
|
||||
+ pinctrl_add_gpio_range(dev, range);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id rt2880_pinmux_match[] = {
|
||||
+ { .compatible = "ralink,rt2880-pinmux" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, rt2880_pinmux_match);
|
||||
+
|
||||
+static struct platform_driver rt2880_pinmux_driver = {
|
||||
+ .probe = rt2880_pinmux_probe,
|
||||
+ .driver = {
|
||||
+ .name = "rt2880-pinmux",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = rt2880_pinmux_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+int __init rt2880_pinmux_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&rt2880_pinmux_driver);
|
||||
+}
|
||||
+
|
||||
+core_initcall_sync(rt2880_pinmux_init);
|
|
@ -1,59 +0,0 @@
|
|||
From d410e5478c622c01fcf31427533df5f433df9146 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 28 Jul 2013 19:45:30 +0200
|
||||
Subject: [PATCH 26/53] DT: Add documentation for gpio-ralink
|
||||
|
||||
Describe gpio-ralink binding.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Cc: devicetree@vger.kernel.org
|
||||
Cc: linux-gpio@vger.kernel.org
|
||||
---
|
||||
.../devicetree/bindings/gpio/gpio-ralink.txt | 40 ++++++++++++++++++++
|
||||
1 file changed, 40 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/gpio/gpio-ralink.txt
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
|
||||
@@ -0,0 +1,40 @@
|
||||
+Ralink SoC GPIO controller bindings
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible:
|
||||
+ - "ralink,rt2880-gpio" for Ralink controllers
|
||||
+- #gpio-cells : Should be two.
|
||||
+ - first cell is the pin number
|
||||
+ - second cell is used to specify optional parameters (unused)
|
||||
+- gpio-controller : Marks the device node as a GPIO controller
|
||||
+- reg : Physical base address and length of the controller's registers
|
||||
+- interrupt-parent: phandle to the INTC device node
|
||||
+- interrupts : Specify the INTC interrupt number
|
||||
+- ralink,num-gpios : Specify the number of GPIOs
|
||||
+- ralink,register-map : The register layout depends on the GPIO bank and actual
|
||||
+ SoC type. Register offsets need to be in this order.
|
||||
+ [ INT, EDGE, RENA, FENA, DATA, DIR, POL, SET, RESET, TOGGLE ]
|
||||
+
|
||||
+Optional properties:
|
||||
+- ralink,gpio-base : Specify the GPIO chips base number
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+ gpio0: gpio@600 {
|
||||
+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
|
||||
+
|
||||
+ #gpio-cells = <2>;
|
||||
+ gpio-controller;
|
||||
+
|
||||
+ reg = <0x600 0x34>;
|
||||
+
|
||||
+ interrupt-parent = <&intc>;
|
||||
+ interrupts = <6>;
|
||||
+
|
||||
+ ralink,gpio-base = <0>;
|
||||
+ ralink,num-gpios = <24>;
|
||||
+ ralink,register-map = [ 00 04 08 0c
|
||||
+ 20 24 28 2c
|
||||
+ 30 34 ];
|
||||
+
|
||||
+ };
|
|
@ -1,430 +0,0 @@
|
|||
From 69fdd2c4f937796b934e89c33acde9d082e27bfd Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 4 Aug 2014 20:36:29 +0200
|
||||
Subject: [PATCH 27/53] GPIO: MIPS: ralink: add gpio driver for ralink SoC
|
||||
|
||||
Add gpio driver for Ralink SoC. This driver makes the gpio core on
|
||||
RT2880, RT305x, rt3352, rt3662, rt3883, rt5350 and mt7620 work.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Cc: linux-gpio@vger.kernel.org
|
||||
---
|
||||
arch/mips/include/asm/mach-ralink/gpio.h | 24 ++
|
||||
drivers/gpio/Kconfig | 6 +
|
||||
drivers/gpio/Makefile | 1 +
|
||||
drivers/gpio/gpio-ralink.c | 355 ++++++++++++++++++++++++++++++
|
||||
4 files changed, 386 insertions(+)
|
||||
create mode 100644 arch/mips/include/asm/mach-ralink/gpio.h
|
||||
create mode 100644 drivers/gpio/gpio-ralink.c
|
||||
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-ralink/gpio.h
|
||||
@@ -0,0 +1,24 @@
|
||||
+/*
|
||||
+ * Ralink SoC GPIO API support
|
||||
+ *
|
||||
+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef __ASM_MACH_RALINK_GPIO_H
|
||||
+#define __ASM_MACH_RALINK_GPIO_H
|
||||
+
|
||||
+#define ARCH_NR_GPIOS 128
|
||||
+#include <asm-generic/gpio.h>
|
||||
+
|
||||
+#define gpio_get_value __gpio_get_value
|
||||
+#define gpio_set_value __gpio_set_value
|
||||
+#define gpio_cansleep __gpio_cansleep
|
||||
+#define gpio_to_irq __gpio_to_irq
|
||||
+
|
||||
+#endif /* __ASM_MACH_RALINK_GPIO_H */
|
||||
--- a/drivers/gpio/Kconfig
|
||||
+++ b/drivers/gpio/Kconfig
|
||||
@@ -398,6 +398,12 @@ config GPIO_REG
|
||||
A 32-bit single register GPIO fixed in/out implementation. This
|
||||
can be used to represent any register as a set of GPIO signals.
|
||||
|
||||
+config GPIO_RALINK
|
||||
+ bool "Ralink GPIO Support"
|
||||
+ depends on RALINK
|
||||
+ help
|
||||
+ Say yes here to support the Ralink SoC GPIO device
|
||||
+
|
||||
config GPIO_SPEAR_SPICS
|
||||
bool "ST SPEAr13xx SPI Chip Select as GPIO support"
|
||||
depends on PLAT_SPEAR
|
||||
--- a/drivers/gpio/Makefile
|
||||
+++ b/drivers/gpio/Makefile
|
||||
@@ -98,6 +98,7 @@ obj-$(CONFIG_GPIO_PCI_IDIO_16) += gpio-p
|
||||
obj-$(CONFIG_GPIO_PISOSR) += gpio-pisosr.o
|
||||
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
|
||||
obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
|
||||
+obj-$(CONFIG_GPIO_RALINK) += gpio-ralink.o
|
||||
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
|
||||
obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
|
||||
obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/gpio/gpio-ralink.c
|
||||
@@ -0,0 +1,355 @@
|
||||
+/*
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/irqdomain.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+
|
||||
+enum ralink_gpio_reg {
|
||||
+ GPIO_REG_INT = 0,
|
||||
+ GPIO_REG_EDGE,
|
||||
+ GPIO_REG_RENA,
|
||||
+ GPIO_REG_FENA,
|
||||
+ GPIO_REG_DATA,
|
||||
+ GPIO_REG_DIR,
|
||||
+ GPIO_REG_POL,
|
||||
+ GPIO_REG_SET,
|
||||
+ GPIO_REG_RESET,
|
||||
+ GPIO_REG_TOGGLE,
|
||||
+ GPIO_REG_MAX
|
||||
+};
|
||||
+
|
||||
+struct ralink_gpio_chip {
|
||||
+ struct gpio_chip chip;
|
||||
+ u8 regs[GPIO_REG_MAX];
|
||||
+
|
||||
+ spinlock_t lock;
|
||||
+ void __iomem *membase;
|
||||
+ struct irq_domain *domain;
|
||||
+ int irq;
|
||||
+
|
||||
+ u32 rising;
|
||||
+ u32 falling;
|
||||
+};
|
||||
+
|
||||
+#define MAP_MAX 4
|
||||
+static struct irq_domain *irq_map[MAP_MAX];
|
||||
+static int irq_map_count;
|
||||
+static atomic_t irq_refcount = ATOMIC_INIT(0);
|
||||
+
|
||||
+static inline struct ralink_gpio_chip *to_ralink_gpio(struct gpio_chip *chip)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+
|
||||
+ rg = container_of(chip, struct ralink_gpio_chip, chip);
|
||||
+
|
||||
+ return rg;
|
||||
+}
|
||||
+
|
||||
+static inline void rt_gpio_w32(struct ralink_gpio_chip *rg, u8 reg, u32 val)
|
||||
+{
|
||||
+ iowrite32(val, rg->membase + rg->regs[reg]);
|
||||
+}
|
||||
+
|
||||
+static inline u32 rt_gpio_r32(struct ralink_gpio_chip *rg, u8 reg)
|
||||
+{
|
||||
+ return ioread32(rg->membase + rg->regs[reg]);
|
||||
+}
|
||||
+
|
||||
+static void ralink_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+
|
||||
+ rt_gpio_w32(rg, (value) ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset));
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+
|
||||
+ return !!(rt_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset));
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+ unsigned long flags;
|
||||
+ u32 t;
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ t = rt_gpio_r32(rg, GPIO_REG_DIR);
|
||||
+ t &= ~BIT(offset);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_DIR, t);
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_direction_output(struct gpio_chip *chip,
|
||||
+ unsigned offset, int value)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+ unsigned long flags;
|
||||
+ u32 t;
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ ralink_gpio_set(chip, offset, value);
|
||||
+ t = rt_gpio_r32(rg, GPIO_REG_DIR);
|
||||
+ t |= BIT(offset);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_DIR, t);
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+
|
||||
+ if (rg->irq < 1)
|
||||
+ return -1;
|
||||
+
|
||||
+ return irq_create_mapping(rg->domain, pin);
|
||||
+}
|
||||
+
|
||||
+static void ralink_gpio_irq_handler(struct irq_desc *desc)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < irq_map_count; i++) {
|
||||
+ struct irq_domain *domain = irq_map[i];
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ unsigned long pending;
|
||||
+ int bit;
|
||||
+
|
||||
+ rg = (struct ralink_gpio_chip *) domain->host_data;
|
||||
+ pending = rt_gpio_r32(rg, GPIO_REG_INT);
|
||||
+
|
||||
+ for_each_set_bit(bit, &pending, rg->chip.ngpio) {
|
||||
+ u32 map = irq_find_mapping(domain, bit);
|
||||
+ generic_handle_irq(map);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_INT, BIT(bit));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void ralink_gpio_irq_unmask(struct irq_data *d)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ unsigned long flags;
|
||||
+ u32 rise, fall;
|
||||
+
|
||||
+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
|
||||
+ rise = rt_gpio_r32(rg, GPIO_REG_RENA);
|
||||
+ fall = rt_gpio_r32(rg, GPIO_REG_FENA);
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_RENA, rise | (BIT(d->hwirq) & rg->rising));
|
||||
+ rt_gpio_w32(rg, GPIO_REG_FENA, fall | (BIT(d->hwirq) & rg->falling));
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static void ralink_gpio_irq_mask(struct irq_data *d)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ unsigned long flags;
|
||||
+ u32 rise, fall;
|
||||
+
|
||||
+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
|
||||
+ rise = rt_gpio_r32(rg, GPIO_REG_RENA);
|
||||
+ fall = rt_gpio_r32(rg, GPIO_REG_FENA);
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_FENA, fall & ~BIT(d->hwirq));
|
||||
+ rt_gpio_w32(rg, GPIO_REG_RENA, rise & ~BIT(d->hwirq));
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_irq_type(struct irq_data *d, unsigned int type)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ u32 mask = BIT(d->hwirq);
|
||||
+
|
||||
+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
|
||||
+
|
||||
+ if (type == IRQ_TYPE_PROBE) {
|
||||
+ if ((rg->rising | rg->falling) & mask)
|
||||
+ return 0;
|
||||
+
|
||||
+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
|
||||
+ }
|
||||
+
|
||||
+ if (type & IRQ_TYPE_EDGE_RISING)
|
||||
+ rg->rising |= mask;
|
||||
+ else
|
||||
+ rg->rising &= ~mask;
|
||||
+
|
||||
+ if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
+ rg->falling |= mask;
|
||||
+ else
|
||||
+ rg->falling &= ~mask;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip ralink_gpio_irq_chip = {
|
||||
+ .name = "GPIO",
|
||||
+ .irq_unmask = ralink_gpio_irq_unmask,
|
||||
+ .irq_mask = ralink_gpio_irq_mask,
|
||||
+ .irq_mask_ack = ralink_gpio_irq_mask,
|
||||
+ .irq_set_type = ralink_gpio_irq_type,
|
||||
+};
|
||||
+
|
||||
+static int gpio_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
|
||||
+{
|
||||
+ irq_set_chip_and_handler(irq, &ralink_gpio_irq_chip, handle_level_irq);
|
||||
+ irq_set_handler_data(irq, d);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct irq_domain_ops irq_domain_ops = {
|
||||
+ .xlate = irq_domain_xlate_onecell,
|
||||
+ .map = gpio_map,
|
||||
+};
|
||||
+
|
||||
+static void ralink_gpio_irq_init(struct device_node *np,
|
||||
+ struct ralink_gpio_chip *rg)
|
||||
+{
|
||||
+ if (irq_map_count >= MAP_MAX)
|
||||
+ return;
|
||||
+
|
||||
+ rg->irq = irq_of_parse_and_map(np, 0);
|
||||
+ if (!rg->irq)
|
||||
+ return;
|
||||
+
|
||||
+ rg->domain = irq_domain_add_linear(np, rg->chip.ngpio,
|
||||
+ &irq_domain_ops, rg);
|
||||
+ if (!rg->domain) {
|
||||
+ dev_err(rg->chip.parent, "irq_domain_add_linear failed\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ irq_map[irq_map_count++] = rg->domain;
|
||||
+
|
||||
+ rt_gpio_w32(rg, GPIO_REG_RENA, 0x0);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_FENA, 0x0);
|
||||
+
|
||||
+ if (!atomic_read(&irq_refcount))
|
||||
+ irq_set_chained_handler(rg->irq, ralink_gpio_irq_handler);
|
||||
+ atomic_inc(&irq_refcount);
|
||||
+
|
||||
+ dev_info(rg->chip.parent, "registering %d irq handlers\n", rg->chip.ngpio);
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_request(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ int gpio = chip->base + offset;
|
||||
+
|
||||
+ return pinctrl_request_gpio(gpio);
|
||||
+}
|
||||
+
|
||||
+static void ralink_gpio_free(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ int gpio = chip->base + offset;
|
||||
+
|
||||
+ pinctrl_free_gpio(gpio);
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device_node *np = pdev->dev.of_node;
|
||||
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ const __be32 *ngpio, *gpiobase;
|
||||
+
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "failed to find resource\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ rg = devm_kzalloc(&pdev->dev,
|
||||
+ sizeof(struct ralink_gpio_chip), GFP_KERNEL);
|
||||
+ if (!rg)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ rg->membase = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (!rg->membase) {
|
||||
+ dev_err(&pdev->dev, "cannot remap I/O memory region\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ if (of_property_read_u8_array(np, "ralink,register-map",
|
||||
+ rg->regs, GPIO_REG_MAX)) {
|
||||
+ dev_err(&pdev->dev, "failed to read register definition\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ngpio = of_get_property(np, "ralink,num-gpios", NULL);
|
||||
+ if (!ngpio) {
|
||||
+ dev_err(&pdev->dev, "failed to read number of pins\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ gpiobase = of_get_property(np, "ralink,gpio-base", NULL);
|
||||
+ if (gpiobase)
|
||||
+ rg->chip.base = be32_to_cpu(*gpiobase);
|
||||
+ else
|
||||
+ rg->chip.base = -1;
|
||||
+
|
||||
+ spin_lock_init(&rg->lock);
|
||||
+
|
||||
+ rg->chip.parent = &pdev->dev;
|
||||
+ rg->chip.label = dev_name(&pdev->dev);
|
||||
+ rg->chip.of_node = np;
|
||||
+ rg->chip.ngpio = be32_to_cpu(*ngpio);
|
||||
+ rg->chip.direction_input = ralink_gpio_direction_input;
|
||||
+ rg->chip.direction_output = ralink_gpio_direction_output;
|
||||
+ rg->chip.get = ralink_gpio_get;
|
||||
+ rg->chip.set = ralink_gpio_set;
|
||||
+ rg->chip.request = ralink_gpio_request;
|
||||
+ rg->chip.to_irq = ralink_gpio_to_irq;
|
||||
+ rg->chip.free = ralink_gpio_free;
|
||||
+
|
||||
+ /* set polarity to low for all lines */
|
||||
+ rt_gpio_w32(rg, GPIO_REG_POL, 0);
|
||||
+
|
||||
+ dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
|
||||
+
|
||||
+ ralink_gpio_irq_init(np, rg);
|
||||
+
|
||||
+ return gpiochip_add(&rg->chip);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id ralink_gpio_match[] = {
|
||||
+ { .compatible = "ralink,rt2880-gpio" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ralink_gpio_match);
|
||||
+
|
||||
+static struct platform_driver ralink_gpio_driver = {
|
||||
+ .probe = ralink_gpio_probe,
|
||||
+ .driver = {
|
||||
+ .name = "rt2880_gpio",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = ralink_gpio_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init ralink_gpio_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&ralink_gpio_driver);
|
||||
+}
|
||||
+
|
||||
+subsys_initcall(ralink_gpio_init);
|
|
@ -1,405 +0,0 @@
|
|||
From 61ac7d9b4228de8c332900902c2b93189b042eab Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 27 Jul 2014 11:00:32 +0100
|
||||
Subject: [PATCH 28/53] GPIO: ralink: add mt7621 gpio controller
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/Kconfig | 3 +
|
||||
drivers/gpio/Kconfig | 6 +
|
||||
drivers/gpio/Makefile | 1 +
|
||||
drivers/gpio/gpio-mt7621.c | 354 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 364 insertions(+)
|
||||
create mode 100644 drivers/gpio/gpio-mt7621.c
|
||||
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -631,6 +631,9 @@ config RALINK
|
||||
select RESET_CONTROLLER
|
||||
select PINCTRL
|
||||
select PINCTRL_RT2880
|
||||
+ select ARCH_HAS_RESET_CONTROLLER
|
||||
+ select RESET_CONTROLLER
|
||||
+ select ARCH_REQUIRE_GPIOLIB
|
||||
|
||||
config SGI_IP22
|
||||
bool "SGI IP22 (Indy/Indigo2)"
|
||||
--- a/drivers/gpio/Kconfig
|
||||
+++ b/drivers/gpio/Kconfig
|
||||
@@ -298,6 +298,12 @@ config GPIO_MENZ127
|
||||
help
|
||||
Say yes here to support the MEN 16Z127 GPIO Controller
|
||||
|
||||
+config GPIO_MT7621
|
||||
+ bool "Mediatek GPIO Support"
|
||||
+ depends on SOC_MT7620 || SOC_MT7621
|
||||
+ help
|
||||
+ Say yes here to support the Mediatek SoC GPIO device
|
||||
+
|
||||
config GPIO_MM_LANTIQ
|
||||
bool "Lantiq Memory mapped GPIOs"
|
||||
depends on LANTIQ && SOC_XWAY
|
||||
--- a/drivers/gpio/Makefile
|
||||
+++ b/drivers/gpio/Makefile
|
||||
@@ -152,3 +152,4 @@ obj-$(CONFIG_GPIO_ZEVIO) += gpio-zevio.o
|
||||
obj-$(CONFIG_GPIO_ZYNQ) += gpio-zynq.o
|
||||
obj-$(CONFIG_GPIO_ZX) += gpio-zx.o
|
||||
obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o
|
||||
+obj-$(CONFIG_GPIO_MT7621) += gpio-mt7621.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/gpio/gpio-mt7621.c
|
||||
@@ -0,0 +1,354 @@
|
||||
+/*
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/irqdomain.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#define MTK_MAX_BANK 3
|
||||
+#define MTK_BANK_WIDTH 32
|
||||
+
|
||||
+enum mediatek_gpio_reg {
|
||||
+ GPIO_REG_CTRL = 0,
|
||||
+ GPIO_REG_POL,
|
||||
+ GPIO_REG_DATA,
|
||||
+ GPIO_REG_DSET,
|
||||
+ GPIO_REG_DCLR,
|
||||
+ GPIO_REG_REDGE,
|
||||
+ GPIO_REG_FEDGE,
|
||||
+ GPIO_REG_HLVL,
|
||||
+ GPIO_REG_LLVL,
|
||||
+ GPIO_REG_STAT,
|
||||
+ GPIO_REG_EDGE,
|
||||
+};
|
||||
+
|
||||
+static void __iomem *mediatek_gpio_membase;
|
||||
+static int mediatek_gpio_irq;
|
||||
+static struct irq_domain *mediatek_gpio_irq_domain;
|
||||
+static atomic_t irq_refcount = ATOMIC_INIT(0);
|
||||
+
|
||||
+struct mtk_gc {
|
||||
+ struct gpio_chip chip;
|
||||
+ spinlock_t lock;
|
||||
+ int bank;
|
||||
+ u32 rising;
|
||||
+ u32 falling;
|
||||
+} *gc_map[MTK_MAX_BANK];
|
||||
+
|
||||
+static inline struct mtk_gc
|
||||
+*to_mediatek_gpio(struct gpio_chip *chip)
|
||||
+{
|
||||
+ struct mtk_gc *mgc;
|
||||
+
|
||||
+ mgc = container_of(chip, struct mtk_gc, chip);
|
||||
+
|
||||
+ return mgc;
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+mtk_gpio_w32(struct mtk_gc *rg, u8 reg, u32 val)
|
||||
+{
|
||||
+ iowrite32(val, mediatek_gpio_membase + (reg * 0x10) + (rg->bank * 0x4));
|
||||
+}
|
||||
+
|
||||
+static inline u32
|
||||
+mtk_gpio_r32(struct mtk_gc *rg, u8 reg)
|
||||
+{
|
||||
+ return ioread32(mediatek_gpio_membase + (reg * 0x10) + (rg->bank * 0x4));
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mediatek_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
+{
|
||||
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
|
||||
+
|
||||
+ mtk_gpio_w32(rg, (value) ? GPIO_REG_DSET : GPIO_REG_DCLR, BIT(offset));
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
|
||||
+
|
||||
+ return !!(mtk_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset));
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
|
||||
+ unsigned long flags;
|
||||
+ u32 t;
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ t = mtk_gpio_r32(rg, GPIO_REG_CTRL);
|
||||
+ t &= ~BIT(offset);
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_CTRL, t);
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_direction_output(struct gpio_chip *chip,
|
||||
+ unsigned offset, int value)
|
||||
+{
|
||||
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
|
||||
+ unsigned long flags;
|
||||
+ u32 t;
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ t = mtk_gpio_r32(rg, GPIO_REG_CTRL);
|
||||
+ t |= BIT(offset);
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_CTRL, t);
|
||||
+ mediatek_gpio_set(chip, offset, value);
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
|
||||
+ unsigned long flags;
|
||||
+ u32 t;
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ t = mtk_gpio_r32(rg, GPIO_REG_CTRL);
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+
|
||||
+ if (t & BIT(offset))
|
||||
+ return 0;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
|
||||
+{
|
||||
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
|
||||
+
|
||||
+ return irq_create_mapping(mediatek_gpio_irq_domain, pin + (rg->bank * MTK_BANK_WIDTH));
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_bank_probe(struct platform_device *pdev, struct device_node *bank)
|
||||
+{
|
||||
+ const __be32 *id = of_get_property(bank, "reg", NULL);
|
||||
+ struct mtk_gc *rg = devm_kzalloc(&pdev->dev,
|
||||
+ sizeof(struct mtk_gc), GFP_KERNEL);
|
||||
+
|
||||
+ if (!rg || !id || be32_to_cpu(*id) > MTK_MAX_BANK)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ gc_map[be32_to_cpu(*id)] = rg;
|
||||
+
|
||||
+ memset(rg, 0, sizeof(struct mtk_gc));
|
||||
+
|
||||
+ spin_lock_init(&rg->lock);
|
||||
+
|
||||
+ rg->chip.parent = &pdev->dev;
|
||||
+ rg->chip.label = dev_name(&pdev->dev);
|
||||
+ rg->chip.of_node = bank;
|
||||
+ rg->chip.base = MTK_BANK_WIDTH * be32_to_cpu(*id);
|
||||
+ rg->chip.ngpio = MTK_BANK_WIDTH;
|
||||
+ rg->chip.direction_input = mediatek_gpio_direction_input;
|
||||
+ rg->chip.direction_output = mediatek_gpio_direction_output;
|
||||
+ rg->chip.get_direction = mediatek_gpio_get_direction;
|
||||
+ rg->chip.get = mediatek_gpio_get;
|
||||
+ rg->chip.set = mediatek_gpio_set;
|
||||
+ if (mediatek_gpio_irq_domain)
|
||||
+ rg->chip.to_irq = mediatek_gpio_to_irq;
|
||||
+ rg->bank = be32_to_cpu(*id);
|
||||
+
|
||||
+ /* set polarity to low for all gpios */
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_POL, 0);
|
||||
+
|
||||
+ dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
|
||||
+
|
||||
+ return gpiochip_add(&rg->chip);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mediatek_gpio_irq_handler(struct irq_desc *desc)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < MTK_MAX_BANK; i++) {
|
||||
+ struct mtk_gc *rg = gc_map[i];
|
||||
+ unsigned long pending;
|
||||
+ int bit;
|
||||
+
|
||||
+ if (!rg)
|
||||
+ continue;
|
||||
+
|
||||
+ pending = mtk_gpio_r32(rg, GPIO_REG_STAT);
|
||||
+
|
||||
+ for_each_set_bit(bit, &pending, MTK_BANK_WIDTH) {
|
||||
+ u32 map = irq_find_mapping(mediatek_gpio_irq_domain, (MTK_BANK_WIDTH * i) + bit);
|
||||
+
|
||||
+ generic_handle_irq(map);
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_STAT, BIT(bit));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mediatek_gpio_irq_unmask(struct irq_data *d)
|
||||
+{
|
||||
+ int pin = d->hwirq;
|
||||
+ int bank = pin / 32;
|
||||
+ struct mtk_gc *rg = gc_map[bank];
|
||||
+ unsigned long flags;
|
||||
+ u32 rise, fall;
|
||||
+
|
||||
+ if (!rg)
|
||||
+ return;
|
||||
+
|
||||
+ rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
|
||||
+ fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_REDGE, rise | (BIT(d->hwirq) & rg->rising));
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall | (BIT(d->hwirq) & rg->falling));
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mediatek_gpio_irq_mask(struct irq_data *d)
|
||||
+{
|
||||
+ int pin = d->hwirq;
|
||||
+ int bank = pin / 32;
|
||||
+ struct mtk_gc *rg = gc_map[bank];
|
||||
+ unsigned long flags;
|
||||
+ u32 rise, fall;
|
||||
+
|
||||
+ if (!rg)
|
||||
+ return;
|
||||
+
|
||||
+ rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
|
||||
+ fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall & ~BIT(d->hwirq));
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_REDGE, rise & ~BIT(d->hwirq));
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_irq_type(struct irq_data *d, unsigned int type)
|
||||
+{
|
||||
+ int pin = d->hwirq;
|
||||
+ int bank = pin / 32;
|
||||
+ struct mtk_gc *rg = gc_map[bank];
|
||||
+ u32 mask = BIT(d->hwirq);
|
||||
+
|
||||
+ if (!rg)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (type == IRQ_TYPE_PROBE) {
|
||||
+ if ((rg->rising | rg->falling) & mask)
|
||||
+ return 0;
|
||||
+
|
||||
+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
|
||||
+ }
|
||||
+
|
||||
+ if (type & IRQ_TYPE_EDGE_RISING)
|
||||
+ rg->rising |= mask;
|
||||
+ else
|
||||
+ rg->rising &= ~mask;
|
||||
+
|
||||
+ if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
+ rg->falling |= mask;
|
||||
+ else
|
||||
+ rg->falling &= ~mask;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip mediatek_gpio_irq_chip = {
|
||||
+ .name = "GPIO",
|
||||
+ .irq_unmask = mediatek_gpio_irq_unmask,
|
||||
+ .irq_mask = mediatek_gpio_irq_mask,
|
||||
+ .irq_mask_ack = mediatek_gpio_irq_mask,
|
||||
+ .irq_set_type = mediatek_gpio_irq_type,
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_gpio_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
|
||||
+{
|
||||
+ irq_set_chip_and_handler(irq, &mediatek_gpio_irq_chip, handle_level_irq);
|
||||
+ irq_set_handler_data(irq, d);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct irq_domain_ops irq_domain_ops = {
|
||||
+ .xlate = irq_domain_xlate_onecell,
|
||||
+ .map = mediatek_gpio_gpio_map,
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device_node *bank, *np = pdev->dev.of_node;
|
||||
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+
|
||||
+ mediatek_gpio_membase = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(mediatek_gpio_membase))
|
||||
+ return PTR_ERR(mediatek_gpio_membase);
|
||||
+
|
||||
+ mediatek_gpio_irq = irq_of_parse_and_map(np, 0);
|
||||
+ if (mediatek_gpio_irq) {
|
||||
+ mediatek_gpio_irq_domain = irq_domain_add_linear(np,
|
||||
+ MTK_MAX_BANK * MTK_BANK_WIDTH,
|
||||
+ &irq_domain_ops, NULL);
|
||||
+ if (!mediatek_gpio_irq_domain)
|
||||
+ dev_err(&pdev->dev, "irq_domain_add_linear failed\n");
|
||||
+ }
|
||||
+
|
||||
+ for_each_child_of_node(np, bank)
|
||||
+ if (of_device_is_compatible(bank, "mtk,mt7621-gpio-bank"))
|
||||
+ mediatek_gpio_bank_probe(pdev, bank);
|
||||
+
|
||||
+ if (mediatek_gpio_irq_domain)
|
||||
+ irq_set_chained_handler(mediatek_gpio_irq, mediatek_gpio_irq_handler);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mediatek_gpio_match[] = {
|
||||
+ { .compatible = "mtk,mt7621-gpio" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mediatek_gpio_match);
|
||||
+
|
||||
+static struct platform_driver mediatek_gpio_driver = {
|
||||
+ .probe = mediatek_gpio_probe,
|
||||
+ .driver = {
|
||||
+ .name = "mt7621_gpio",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = mediatek_gpio_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init
|
||||
+mediatek_gpio_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&mediatek_gpio_driver);
|
||||
+}
|
||||
+
|
||||
+subsys_initcall(mediatek_gpio_init);
|
|
@ -1,44 +0,0 @@
|
|||
From 57fa7f2f4ef6f78ce1d30509c0d111aa3791b524 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Santos <daniel.santos@pobox.com>
|
||||
Date: Sun, 4 Nov 2018 20:24:32 -0600
|
||||
Subject: gpio-ralink: Add support for GPIO as interrupt-controller
|
||||
|
||||
Signed-off-by: Daniel Santos <daniel.santos@pobox.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/gpio/gpio-ralink.txt | 6 ++++++
|
||||
drivers/gpio/gpio-ralink.c | 2 +-
|
||||
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
|
||||
+++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
|
||||
@@ -17,6 +17,9 @@ Required properties:
|
||||
|
||||
Optional properties:
|
||||
- ralink,gpio-base : Specify the GPIO chips base number
|
||||
+- interrupt-controller : marks this as an interrupt controller
|
||||
+- #interrupt-cells : a standard two-cell interrupt flag, see
|
||||
+ interrupt-controller/interrupts.txt
|
||||
|
||||
Example:
|
||||
|
||||
@@ -28,6 +31,9 @@ Example:
|
||||
|
||||
reg = <0x600 0x34>;
|
||||
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <2>;
|
||||
+
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <6>;
|
||||
|
||||
--- a/drivers/gpio/gpio-ralink.c
|
||||
+++ b/drivers/gpio/gpio-ralink.c
|
||||
@@ -220,7 +220,7 @@ static int gpio_map(struct irq_domain *d
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops irq_domain_ops = {
|
||||
- .xlate = irq_domain_xlate_onecell,
|
||||
+ .xlate = irq_domain_xlate_twocell,
|
||||
.map = gpio_map,
|
||||
};
|
||||
|
|
@ -1,246 +0,0 @@
|
|||
From 975e76214cd2516eb6cfff4c3eec581872645e88 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 19 Sep 2013 01:50:59 +0200
|
||||
Subject: [PATCH 31/53] uvc: add iPassion iP2970 support
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/media/usb/uvc/uvc_driver.c | 12 +++
|
||||
drivers/media/usb/uvc/uvc_status.c | 2 +
|
||||
drivers/media/usb/uvc/uvc_video.c | 147 ++++++++++++++++++++++++++++++++++++
|
||||
drivers/media/usb/uvc/uvcvideo.h | 5 +-
|
||||
4 files changed, 165 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/media/usb/uvc/uvc_driver.c
|
||||
+++ b/drivers/media/usb/uvc/uvc_driver.c
|
||||
@@ -2749,6 +2749,18 @@ static const struct usb_device_id uvc_id
|
||||
.bInterfaceSubClass = 1,
|
||||
.bInterfaceProtocol = 0,
|
||||
.driver_info = UVC_QUIRK_FORCE_Y8 },
|
||||
+ /* iPassion iP2970 */
|
||||
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
|
||||
+ | USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
+ .idVendor = 0x1B3B,
|
||||
+ .idProduct = 0x2970,
|
||||
+ .bInterfaceClass = USB_CLASS_VIDEO,
|
||||
+ .bInterfaceSubClass = 1,
|
||||
+ .bInterfaceProtocol = 0,
|
||||
+ .driver_info = UVC_QUIRK_PROBE_MINMAX
|
||||
+ | UVC_QUIRK_STREAM_NO_FID
|
||||
+ | UVC_QUIRK_MOTION
|
||||
+ | UVC_QUIRK_SINGLE_ISO },
|
||||
/* Generic USB Video Class */
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) },
|
||||
--- a/drivers/media/usb/uvc/uvc_status.c
|
||||
+++ b/drivers/media/usb/uvc/uvc_status.c
|
||||
@@ -139,6 +139,7 @@ static void uvc_status_complete(struct u
|
||||
switch (dev->status[0] & 0x0f) {
|
||||
case UVC_STATUS_TYPE_CONTROL:
|
||||
uvc_event_control(dev, dev->status, len);
|
||||
+ dev->motion = 1;
|
||||
break;
|
||||
|
||||
case UVC_STATUS_TYPE_STREAMING:
|
||||
@@ -182,6 +183,7 @@ int uvc_status_init(struct uvc_device *d
|
||||
}
|
||||
|
||||
pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress);
|
||||
+ dev->motion = 0;
|
||||
|
||||
/* For high-speed interrupt endpoints, the bInterval value is used as
|
||||
* an exponent of two. Some developers forgot about it.
|
||||
--- a/drivers/media/usb/uvc/uvc_video.c
|
||||
+++ b/drivers/media/usb/uvc/uvc_video.c
|
||||
@@ -21,6 +21,11 @@
|
||||
#include <linux/wait.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/unaligned.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/kobject.h>
|
||||
+#include <linux/netlink.h>
|
||||
+#include <linux/kobject.h>
|
||||
+#include <linux/workqueue.h>
|
||||
|
||||
#include <media/v4l2-common.h>
|
||||
|
||||
@@ -1101,9 +1106,149 @@ static void uvc_video_decode_data(struct
|
||||
}
|
||||
}
|
||||
|
||||
+struct bh_priv {
|
||||
+ unsigned long seen;
|
||||
+};
|
||||
+
|
||||
+struct bh_event {
|
||||
+ const char *name;
|
||||
+ struct sk_buff *skb;
|
||||
+ struct work_struct work;
|
||||
+};
|
||||
+
|
||||
+#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, "webcam", ##args )
|
||||
+#define BH_DBG(fmt, args...) do {} while (0)
|
||||
+#define BH_SKB_SIZE 2048
|
||||
+
|
||||
+extern u64 uevent_next_seqnum(void);
|
||||
+static int seen = 0;
|
||||
+
|
||||
+static int bh_event_add_var(struct bh_event *event, int argv,
|
||||
+ const char *format, ...)
|
||||
+{
|
||||
+ static char buf[128];
|
||||
+ char *s;
|
||||
+ va_list args;
|
||||
+ int len;
|
||||
+
|
||||
+ if (argv)
|
||||
+ return 0;
|
||||
+
|
||||
+ va_start(args, format);
|
||||
+ len = vsnprintf(buf, sizeof(buf), format, args);
|
||||
+ va_end(args);
|
||||
+
|
||||
+ if (len >= sizeof(buf)) {
|
||||
+ BH_ERR("buffer size too small\n");
|
||||
+ WARN_ON(1);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ s = skb_put(event->skb, len + 1);
|
||||
+ strcpy(s, buf);
|
||||
+
|
||||
+ BH_DBG("added variable '%s'\n", s);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int motion_hotplug_fill_event(struct bh_event *event)
|
||||
+{
|
||||
+ int s = jiffies;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!seen)
|
||||
+ seen = jiffies;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "HOME=%s", "/");
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "PATH=%s",
|
||||
+ "/sbin:/bin:/usr/sbin:/usr/bin");
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "SUBSYSTEM=usb");
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "ACTION=motion");
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "SEEN=%d", s - seen);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ seen = s;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum());
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void motion_hotplug_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct bh_event *event = container_of(work, struct bh_event, work);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL);
|
||||
+ if (!event->skb)
|
||||
+ goto out_free_event;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "%s@", "add");
|
||||
+ if (ret)
|
||||
+ goto out_free_skb;
|
||||
+
|
||||
+ ret = motion_hotplug_fill_event(event);
|
||||
+ if (ret)
|
||||
+ goto out_free_skb;
|
||||
+
|
||||
+ NETLINK_CB(event->skb).dst_group = 1;
|
||||
+ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
|
||||
+
|
||||
+out_free_skb:
|
||||
+ if (ret) {
|
||||
+ BH_ERR("work error %d\n", ret);
|
||||
+ kfree_skb(event->skb);
|
||||
+ }
|
||||
+out_free_event:
|
||||
+ kfree(event);
|
||||
+}
|
||||
+
|
||||
+static int motion_hotplug_create_event(void)
|
||||
+{
|
||||
+ struct bh_event *event;
|
||||
+
|
||||
+ event = kzalloc(sizeof(*event), GFP_KERNEL);
|
||||
+ if (!event)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ event->name = "motion";
|
||||
+
|
||||
+ INIT_WORK(&event->work, (void *)(void *)motion_hotplug_work);
|
||||
+ schedule_work(&event->work);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define MOTION_FLAG_OFFSET 4
|
||||
static void uvc_video_decode_end(struct uvc_streaming *stream,
|
||||
struct uvc_buffer *buf, const __u8 *data, int len)
|
||||
{
|
||||
+ if ((stream->dev->quirks & UVC_QUIRK_MOTION) &&
|
||||
+ (data[len - 2] == 0xff) && (data[len - 1] == 0xd9)) {
|
||||
+ u8 *mem;
|
||||
+ buf->state = UVC_BUF_STATE_READY;
|
||||
+ mem = (u8 *) (buf->mem + MOTION_FLAG_OFFSET);
|
||||
+ if ( stream->dev->motion ) {
|
||||
+ stream->dev->motion = 0;
|
||||
+ motion_hotplug_create_event();
|
||||
+ } else {
|
||||
+ *mem &= 0x7f;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Mark the buffer as done if the EOF marker is set. */
|
||||
if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) {
|
||||
uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n");
|
||||
@@ -1518,6 +1663,8 @@ static int uvc_init_video_isoc(struct uv
|
||||
if (npackets == 0)
|
||||
return -ENOMEM;
|
||||
|
||||
+ if (stream->dev->quirks & UVC_QUIRK_SINGLE_ISO)
|
||||
+ npackets = 1;
|
||||
size = npackets * psize;
|
||||
|
||||
for (i = 0; i < UVC_URBS; ++i) {
|
||||
--- a/drivers/media/usb/uvc/uvcvideo.h
|
||||
+++ b/drivers/media/usb/uvc/uvcvideo.h
|
||||
@@ -186,7 +186,9 @@
|
||||
#define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200
|
||||
#define UVC_QUIRK_RESTORE_CTRLS_ON_INIT 0x00000400
|
||||
#define UVC_QUIRK_FORCE_Y8 0x00000800
|
||||
-
|
||||
+#define UVC_QUIRK_MOTION 0x00001000
|
||||
+#define UVC_QUIRK_SINGLE_ISO 0x00002000
|
||||
+
|
||||
/* Format flags */
|
||||
#define UVC_FMT_FLAG_COMPRESSED 0x00000001
|
||||
#define UVC_FMT_FLAG_STREAM 0x00000002
|
||||
@@ -584,6 +586,7 @@ struct uvc_device {
|
||||
__u8 *status;
|
||||
struct input_dev *input;
|
||||
char input_phys[64];
|
||||
+ int motion;
|
||||
};
|
||||
|
||||
enum uvc_handle_state {
|
|
@ -1,59 +0,0 @@
|
|||
From 0b6eb1e68290243d439ee330ea8d0b239a5aec69 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 27 Jul 2014 09:38:50 +0100
|
||||
Subject: [PATCH 34/53] NET: multi phy support
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/net/phy/phy.c | 9 ++++++---
|
||||
include/linux/phy.h | 1 +
|
||||
2 files changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/phy.c
|
||||
+++ b/drivers/net/phy/phy.c
|
||||
@@ -913,7 +913,10 @@ void phy_state_machine(struct work_struc
|
||||
/* If the link is down, give up on negotiation for now */
|
||||
if (!phydev->link) {
|
||||
phydev->state = PHY_NOLINK;
|
||||
- phy_link_down(phydev, true);
|
||||
+ if (!phydev->no_auto_carrier_off)
|
||||
+ phy_link_down(phydev, true);
|
||||
+ else
|
||||
+ phy_link_down(phydev, false);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1000,7 +1003,10 @@ void phy_state_machine(struct work_struc
|
||||
phy_link_up(phydev);
|
||||
} else {
|
||||
phydev->state = PHY_NOLINK;
|
||||
- phy_link_down(phydev, true);
|
||||
+ if (!phydev->no_auto_carrier_off)
|
||||
+ phy_link_down(phydev, true);
|
||||
+ else
|
||||
+ phy_link_down(phydev, false);
|
||||
}
|
||||
|
||||
if (phy_interrupt_is_valid(phydev))
|
||||
@@ -1010,7 +1016,10 @@ void phy_state_machine(struct work_struc
|
||||
case PHY_HALTED:
|
||||
if (phydev->link) {
|
||||
phydev->link = 0;
|
||||
- phy_link_down(phydev, true);
|
||||
+ if (!phydev->no_auto_carrier_off)
|
||||
+ phy_link_down(phydev, true);
|
||||
+ else
|
||||
+ phy_link_down(phydev, false);
|
||||
do_suspend = true;
|
||||
}
|
||||
break;
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -414,6 +414,7 @@ struct phy_device {
|
||||
bool suspended_by_mdio_bus;
|
||||
bool sysfs_links;
|
||||
bool loopback_enabled;
|
||||
+ bool no_auto_carrier_off;
|
||||
|
||||
enum phy_state state;
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
From ee9081b2726a5ca8cde5497afdc5425e21ff8f8b Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 15 Jul 2013 00:39:21 +0200
|
||||
Subject: [PATCH 37/53] mtd: cfi cmdset 0002 force word write
|
||||
|
||||
---
|
||||
drivers/mtd/chips/cfi_cmdset_0002.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
@@ -40,7 +40,7 @@
|
||||
#include <linux/mtd/xip.h>
|
||||
|
||||
#define AMD_BOOTLOC_BUG
|
||||
-#define FORCE_WORD_WRITE 0
|
||||
+#define FORCE_WORD_WRITE 1
|
||||
|
||||
#define MAX_RETRIES 3
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
|
||||
static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
|
||||
static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
|
||||
+#if !FORCE_WORD_WRITE
|
||||
static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
|
||||
+#endif
|
||||
static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *);
|
||||
static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
|
||||
static void cfi_amdstd_sync (struct mtd_info *);
|
||||
@@ -202,6 +204,7 @@ static void fixup_amd_bootblock(struct m
|
||||
}
|
||||
#endif
|
||||
|
||||
+#if !FORCE_WORD_WRITE
|
||||
static void fixup_use_write_buffers(struct mtd_info *mtd)
|
||||
{
|
||||
struct map_info *map = mtd->priv;
|
||||
@@ -211,6 +214,7 @@ static void fixup_use_write_buffers(stru
|
||||
mtd->_write = cfi_amdstd_write_buffers;
|
||||
}
|
||||
}
|
||||
+#endif /* !FORCE_WORD_WRITE */
|
||||
|
||||
/* Atmel chips don't use the same PRI format as AMD chips */
|
||||
static void fixup_convert_atmel_pri(struct mtd_info *mtd)
|
||||
@@ -1798,6 +1802,7 @@ static int cfi_amdstd_write_words(struct
|
||||
/*
|
||||
* FIXME: interleaved mode not tested, and probably not supported!
|
||||
*/
|
||||
+#if !FORCE_WORD_WRITE
|
||||
static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
|
||||
unsigned long adr, const u_char *buf,
|
||||
int len)
|
||||
@@ -1930,7 +1935,6 @@ static int __xipram do_write_buffer(stru
|
||||
return ret;
|
||||
}
|
||||
|
||||
-
|
||||
static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
size_t *retlen, const u_char *buf)
|
||||
{
|
||||
@@ -2005,6 +2009,7 @@ static int cfi_amdstd_write_buffers(stru
|
||||
|
||||
return 0;
|
||||
}
|
||||
+#endif /* !FORCE_WORD_WRITE */
|
||||
|
||||
/*
|
||||
* Wait for the flash chip to become ready to write data
|
|
@ -1,67 +0,0 @@
|
|||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Subject: [PATCH] Revert "mtd: nand: Remove unused chip->write_page() hook"
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This reverts commit f107d7a43923a83d837b3ea3c7b7de58cd014bbd.
|
||||
|
||||
OpenWrt's downstream driver mtk_nand2 still uses that callback.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
---
|
||||
|
||||
--- a/drivers/mtd/nand/nand_base.c
|
||||
+++ b/drivers/mtd/nand/nand_base.c
|
||||
@@ -2577,7 +2577,7 @@ static int nand_write_page_syndrome(stru
|
||||
}
|
||||
|
||||
/**
|
||||
- * nand_write_page - write one page
|
||||
+ * nand_write_page - [REPLACEABLE] write one page
|
||||
* @mtd: MTD device structure
|
||||
* @chip: NAND chip descriptor
|
||||
* @offset: address offset within the page
|
||||
@@ -2761,9 +2761,9 @@ static int nand_do_write_ops(struct mtd_
|
||||
memset(chip->oob_poi, 0xff, mtd->oobsize);
|
||||
}
|
||||
|
||||
- ret = nand_write_page(mtd, chip, column, bytes, wbuf,
|
||||
- oob_required, page,
|
||||
- (ops->mode == MTD_OPS_RAW));
|
||||
+ ret = chip->write_page(mtd, chip, column, bytes, wbuf,
|
||||
+ oob_required, page,
|
||||
+ (ops->mode == MTD_OPS_RAW));
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
@@ -4719,6 +4719,9 @@ int nand_scan_tail(struct mtd_info *mtd)
|
||||
}
|
||||
}
|
||||
|
||||
+ if (!chip->write_page)
|
||||
+ chip->write_page = nand_write_page;
|
||||
+
|
||||
/*
|
||||
* Check ECC mode, default to software if 3byte/512byte hardware ECC is
|
||||
* selected and we have 256 byte pagesize fallback to software ECC
|
||||
--- a/include/linux/mtd/rawnand.h
|
||||
+++ b/include/linux/mtd/rawnand.h
|
||||
@@ -860,6 +860,7 @@ struct nand_manufacturer_ops {
|
||||
* structure which is shared among multiple independent
|
||||
* devices.
|
||||
* @priv: [OPTIONAL] pointer to private chip data
|
||||
+ * @write_page: [REPLACEABLE] High-level page write function
|
||||
* @manufacturer: [INTERN] Contains manufacturer information
|
||||
*/
|
||||
|
||||
@@ -883,6 +884,9 @@ struct nand_chip {
|
||||
int(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
|
||||
int (*erase)(struct mtd_info *mtd, int page);
|
||||
int (*scan_bbt)(struct mtd_info *mtd);
|
||||
+ int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
+ uint32_t offset, int data_len, const uint8_t *buf,
|
||||
+ int oob_required, int page, int raw);
|
||||
int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
int feature_addr, uint8_t *subfeature_para);
|
||||
int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip,
|
File diff suppressed because it is too large
Load Diff
|
@ -1,32 +0,0 @@
|
|||
--- a/drivers/mtd/nand/nand_base.c
|
||||
+++ b/drivers/mtd/nand/nand_base.c
|
||||
@@ -1908,6 +1908,9 @@ static int nand_do_read_ops(struct mtd_i
|
||||
__func__, buf);
|
||||
|
||||
read_retry:
|
||||
+#ifdef CONFIG_MTK_MTD_NAND
|
||||
+ ret = chip->read_page(mtd, chip, bufpoi, page);
|
||||
+#else
|
||||
if (nand_standard_page_accessors(&chip->ecc))
|
||||
chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
|
||||
|
||||
@@ -1927,6 +1930,7 @@ read_retry:
|
||||
else
|
||||
ret = chip->ecc.read_page(mtd, chip, bufpoi,
|
||||
oob_required, page);
|
||||
+#endif
|
||||
if (ret < 0) {
|
||||
if (use_bufpoi)
|
||||
/* Invalidate page cache */
|
||||
--- a/include/linux/mtd/rawnand.h
|
||||
+++ b/include/linux/mtd/rawnand.h
|
||||
@@ -895,6 +895,9 @@ struct nand_chip {
|
||||
int (*setup_data_interface)(struct mtd_info *mtd, int chipnr,
|
||||
const struct nand_data_interface *conf);
|
||||
|
||||
+#ifdef CONFIG_MTK_MTD_NAND
|
||||
+ int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip, u8 *buf, int page);
|
||||
+#endif /* CONFIG_MTK_MTD_NAND */
|
||||
|
||||
int chip_delay;
|
||||
unsigned int options;
|
|
@ -1,44 +0,0 @@
|
|||
From da6015e7f19d749f135f7ac55c4ec47b06faa868 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 9 Aug 2013 20:12:59 +0200
|
||||
Subject: [PATCH 41/53] DT: Add documentation for spi-rt2880
|
||||
|
||||
Describe the SPI master found on the MIPS based Ralink RT2880 SoC.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
.../devicetree/bindings/spi/spi-rt2880.txt | 28 ++++++++++++++++++++
|
||||
1 file changed, 28 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/spi/spi-rt2880.txt
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/spi/spi-rt2880.txt
|
||||
@@ -0,0 +1,28 @@
|
||||
+Ralink SoC RT2880 SPI master controller.
|
||||
+
|
||||
+This SPI controller is found on most wireless SoCs made by ralink.
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible : "ralink,rt2880-spi"
|
||||
+- reg : The register base for the controller.
|
||||
+- #address-cells : <1>, as required by generic SPI binding.
|
||||
+- #size-cells : <0>, also as required by generic SPI binding.
|
||||
+
|
||||
+Child nodes as per the generic SPI binding.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+ spi@b00 {
|
||||
+ compatible = "ralink,rt2880-spi";
|
||||
+ reg = <0xb00 0x100>;
|
||||
+
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ m25p80@0 {
|
||||
+ compatible = "m25p80";
|
||||
+ reg = <0>;
|
||||
+ spi-max-frequency = <10000000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
|
@ -1,574 +0,0 @@
|
|||
From 683af4ebb91a1600df1946ac4769d916b8a1be65 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 27 Jul 2014 11:15:12 +0100
|
||||
Subject: [PATCH 42/53] SPI: ralink: add Ralink SoC spi driver
|
||||
|
||||
Add the driver needed to make SPI work on Ralink SoC.
|
||||
|
||||
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||
Acked-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/spi/Kconfig | 6 +
|
||||
drivers/spi/Makefile | 1 +
|
||||
drivers/spi/spi-rt2880.c | 530 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 537 insertions(+)
|
||||
create mode 100644 drivers/spi/spi-rt2880.c
|
||||
|
||||
--- a/drivers/spi/Kconfig
|
||||
+++ b/drivers/spi/Kconfig
|
||||
@@ -563,6 +563,12 @@ config SPI_QUP
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called spi_qup.
|
||||
|
||||
+config SPI_RT2880
|
||||
+ tristate "Ralink RT288x SPI Controller"
|
||||
+ depends on RALINK
|
||||
+ help
|
||||
+ This selects a driver for the Ralink RT288x/RT305x SPI Controller.
|
||||
+
|
||||
config SPI_S3C24XX
|
||||
tristate "Samsung S3C24XX series SPI"
|
||||
depends on ARCH_S3C24XX
|
||||
--- a/drivers/spi/Makefile
|
||||
+++ b/drivers/spi/Makefile
|
||||
@@ -81,6 +81,7 @@ obj-$(CONFIG_SPI_QUP) += spi-qup.o
|
||||
obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o
|
||||
obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o
|
||||
obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
|
||||
+obj-$(CONFIG_SPI_RT2880) += spi-rt2880.o
|
||||
obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o
|
||||
spi-s3c24xx-hw-y := spi-s3c24xx.o
|
||||
spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/spi/spi-rt2880.c
|
||||
@@ -0,0 +1,530 @@
|
||||
+/*
|
||||
+ * spi-rt2880.c -- Ralink RT288x/RT305x SPI controller driver
|
||||
+ *
|
||||
+ * Copyright (C) 2011 Sergiy <piratfm@gmail.com>
|
||||
+ * Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ *
|
||||
+ * Some parts are based on spi-orion.c:
|
||||
+ * Author: Shadi Ammouri <shadi@marvell.com>
|
||||
+ * Copyright (C) 2007-2008 Marvell Ltd.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/spi/spi.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/gpio.h>
|
||||
+
|
||||
+#define DRIVER_NAME "spi-rt2880"
|
||||
+
|
||||
+#define RAMIPS_SPI_STAT 0x00
|
||||
+#define RAMIPS_SPI_CFG 0x10
|
||||
+#define RAMIPS_SPI_CTL 0x14
|
||||
+#define RAMIPS_SPI_DATA 0x20
|
||||
+#define RAMIPS_SPI_ADDR 0x24
|
||||
+#define RAMIPS_SPI_BS 0x28
|
||||
+#define RAMIPS_SPI_USER 0x2C
|
||||
+#define RAMIPS_SPI_TXFIFO 0x30
|
||||
+#define RAMIPS_SPI_RXFIFO 0x34
|
||||
+#define RAMIPS_SPI_FIFO_STAT 0x38
|
||||
+#define RAMIPS_SPI_MODE 0x3C
|
||||
+#define RAMIPS_SPI_DEV_OFFSET 0x40
|
||||
+#define RAMIPS_SPI_DMA 0x80
|
||||
+#define RAMIPS_SPI_DMASTAT 0x84
|
||||
+#define RAMIPS_SPI_ARBITER 0xF0
|
||||
+
|
||||
+/* SPISTAT register bit field */
|
||||
+#define SPISTAT_BUSY BIT(0)
|
||||
+
|
||||
+/* SPICFG register bit field */
|
||||
+#define SPICFG_ADDRMODE BIT(12)
|
||||
+#define SPICFG_RXENVDIS BIT(11)
|
||||
+#define SPICFG_RXCAP BIT(10)
|
||||
+#define SPICFG_SPIENMODE BIT(9)
|
||||
+#define SPICFG_MSBFIRST BIT(8)
|
||||
+#define SPICFG_SPICLKPOL BIT(6)
|
||||
+#define SPICFG_RXCLKEDGE_FALLING BIT(5)
|
||||
+#define SPICFG_TXCLKEDGE_FALLING BIT(4)
|
||||
+#define SPICFG_HIZSPI BIT(3)
|
||||
+#define SPICFG_SPICLK_PRESCALE_MASK 0x7
|
||||
+#define SPICFG_SPICLK_DIV2 0
|
||||
+#define SPICFG_SPICLK_DIV4 1
|
||||
+#define SPICFG_SPICLK_DIV8 2
|
||||
+#define SPICFG_SPICLK_DIV16 3
|
||||
+#define SPICFG_SPICLK_DIV32 4
|
||||
+#define SPICFG_SPICLK_DIV64 5
|
||||
+#define SPICFG_SPICLK_DIV128 6
|
||||
+#define SPICFG_SPICLK_DISABLE 7
|
||||
+
|
||||
+/* SPICTL register bit field */
|
||||
+#define SPICTL_START BIT(4)
|
||||
+#define SPICTL_HIZSDO BIT(3)
|
||||
+#define SPICTL_STARTWR BIT(2)
|
||||
+#define SPICTL_STARTRD BIT(1)
|
||||
+#define SPICTL_SPIENA BIT(0)
|
||||
+
|
||||
+/* SPIUSER register bit field */
|
||||
+#define SPIUSER_USERMODE BIT(21)
|
||||
+#define SPIUSER_INSTR_PHASE BIT(20)
|
||||
+#define SPIUSER_ADDR_PHASE_MASK 0x7
|
||||
+#define SPIUSER_ADDR_PHASE_OFFSET 17
|
||||
+#define SPIUSER_MODE_PHASE BIT(16)
|
||||
+#define SPIUSER_DUMMY_PHASE_MASK 0x3
|
||||
+#define SPIUSER_DUMMY_PHASE_OFFSET 14
|
||||
+#define SPIUSER_DATA_PHASE_MASK 0x3
|
||||
+#define SPIUSER_DATA_PHASE_OFFSET 12
|
||||
+#define SPIUSER_DATA_READ (BIT(0) << SPIUSER_DATA_PHASE_OFFSET)
|
||||
+#define SPIUSER_DATA_WRITE (BIT(1) << SPIUSER_DATA_PHASE_OFFSET)
|
||||
+#define SPIUSER_ADDR_TYPE_OFFSET 9
|
||||
+#define SPIUSER_MODE_TYPE_OFFSET 6
|
||||
+#define SPIUSER_DUMMY_TYPE_OFFSET 3
|
||||
+#define SPIUSER_DATA_TYPE_OFFSET 0
|
||||
+#define SPIUSER_TRANSFER_MASK 0x7
|
||||
+#define SPIUSER_TRANSFER_SINGLE BIT(0)
|
||||
+#define SPIUSER_TRANSFER_DUAL BIT(1)
|
||||
+#define SPIUSER_TRANSFER_QUAD BIT(2)
|
||||
+
|
||||
+#define SPIUSER_TRANSFER_TYPE(type) ( \
|
||||
+ (type << SPIUSER_ADDR_TYPE_OFFSET) | \
|
||||
+ (type << SPIUSER_MODE_TYPE_OFFSET) | \
|
||||
+ (type << SPIUSER_DUMMY_TYPE_OFFSET) | \
|
||||
+ (type << SPIUSER_DATA_TYPE_OFFSET) \
|
||||
+)
|
||||
+
|
||||
+/* SPIFIFOSTAT register bit field */
|
||||
+#define SPIFIFOSTAT_TXEMPTY BIT(19)
|
||||
+#define SPIFIFOSTAT_RXEMPTY BIT(18)
|
||||
+#define SPIFIFOSTAT_TXFULL BIT(17)
|
||||
+#define SPIFIFOSTAT_RXFULL BIT(16)
|
||||
+#define SPIFIFOSTAT_FIFO_MASK 0xff
|
||||
+#define SPIFIFOSTAT_TX_OFFSET 8
|
||||
+#define SPIFIFOSTAT_RX_OFFSET 0
|
||||
+
|
||||
+#define SPI_FIFO_DEPTH 16
|
||||
+
|
||||
+/* SPIMODE register bit field */
|
||||
+#define SPIMODE_MODE_OFFSET 24
|
||||
+#define SPIMODE_DUMMY_OFFSET 0
|
||||
+
|
||||
+/* SPIARB register bit field */
|
||||
+#define SPICTL_ARB_EN BIT(31)
|
||||
+#define SPICTL_CSCTL1 BIT(16)
|
||||
+#define SPI1_POR BIT(1)
|
||||
+#define SPI0_POR BIT(0)
|
||||
+
|
||||
+#define RT2880_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | \
|
||||
+ SPI_CS_HIGH)
|
||||
+
|
||||
+static atomic_t hw_reset_count = ATOMIC_INIT(0);
|
||||
+
|
||||
+struct rt2880_spi {
|
||||
+ struct spi_master *master;
|
||||
+ void __iomem *base;
|
||||
+ u32 speed;
|
||||
+ u16 wait_loops;
|
||||
+ u16 mode;
|
||||
+ struct clk *clk;
|
||||
+};
|
||||
+
|
||||
+static inline struct rt2880_spi *spidev_to_rt2880_spi(struct spi_device *spi)
|
||||
+{
|
||||
+ return spi_master_get_devdata(spi->master);
|
||||
+}
|
||||
+
|
||||
+static inline u32 rt2880_spi_read(struct rt2880_spi *rs, u32 reg)
|
||||
+{
|
||||
+ return ioread32(rs->base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void rt2880_spi_write(struct rt2880_spi *rs, u32 reg,
|
||||
+ const u32 val)
|
||||
+{
|
||||
+ iowrite32(val, rs->base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void rt2880_spi_setbits(struct rt2880_spi *rs, u32 reg, u32 mask)
|
||||
+{
|
||||
+ void __iomem *addr = rs->base + reg;
|
||||
+
|
||||
+ iowrite32((ioread32(addr) | mask), addr);
|
||||
+}
|
||||
+
|
||||
+static inline void rt2880_spi_clrbits(struct rt2880_spi *rs, u32 reg, u32 mask)
|
||||
+{
|
||||
+ void __iomem *addr = rs->base + reg;
|
||||
+
|
||||
+ iowrite32((ioread32(addr) & ~mask), addr);
|
||||
+}
|
||||
+
|
||||
+static u32 rt2880_spi_baudrate_get(struct spi_device *spi, unsigned int speed)
|
||||
+{
|
||||
+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
|
||||
+ u32 rate;
|
||||
+ u32 prescale;
|
||||
+
|
||||
+ /*
|
||||
+ * the supported rates are: 2, 4, 8, ... 128
|
||||
+ * round up as we look for equal or less speed
|
||||
+ */
|
||||
+ rate = DIV_ROUND_UP(clk_get_rate(rs->clk), speed);
|
||||
+ rate = roundup_pow_of_two(rate);
|
||||
+
|
||||
+ /* Convert the rate to SPI clock divisor value. */
|
||||
+ prescale = ilog2(rate / 2);
|
||||
+
|
||||
+ /* some tolerance. double and add 100 */
|
||||
+ rs->wait_loops = (8 * HZ * loops_per_jiffy) /
|
||||
+ (clk_get_rate(rs->clk) / rate);
|
||||
+ rs->wait_loops = (rs->wait_loops << 1) + 100;
|
||||
+ rs->speed = speed;
|
||||
+
|
||||
+ dev_dbg(&spi->dev, "speed: %lu/%u, rate: %u, prescal: %u, loops: %hu\n",
|
||||
+ clk_get_rate(rs->clk) / rate, speed, rate, prescale,
|
||||
+ rs->wait_loops);
|
||||
+
|
||||
+ return prescale;
|
||||
+}
|
||||
+
|
||||
+static u32 get_arbiter_offset(struct spi_master *master)
|
||||
+{
|
||||
+ u32 offset;
|
||||
+
|
||||
+ offset = RAMIPS_SPI_ARBITER;
|
||||
+ if (master->bus_num == 1)
|
||||
+ offset -= RAMIPS_SPI_DEV_OFFSET;
|
||||
+
|
||||
+ return offset;
|
||||
+}
|
||||
+
|
||||
+static void rt2880_spi_set_cs(struct spi_device *spi, bool enable)
|
||||
+{
|
||||
+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
|
||||
+
|
||||
+ if (enable)
|
||||
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
|
||||
+ else
|
||||
+ rt2880_spi_clrbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
|
||||
+}
|
||||
+
|
||||
+static int rt2880_spi_wait_ready(struct rt2880_spi *rs, int len)
|
||||
+{
|
||||
+ int loop = rs->wait_loops * len;
|
||||
+
|
||||
+ while ((rt2880_spi_read(rs, RAMIPS_SPI_STAT) & SPISTAT_BUSY) && --loop)
|
||||
+ cpu_relax();
|
||||
+
|
||||
+ if (loop)
|
||||
+ return 0;
|
||||
+
|
||||
+ return -ETIMEDOUT;
|
||||
+}
|
||||
+
|
||||
+static void rt2880_dump_reg(struct spi_master *master)
|
||||
+{
|
||||
+ struct rt2880_spi *rs = spi_master_get_devdata(master);
|
||||
+
|
||||
+ dev_dbg(&master->dev, "stat: %08x, cfg: %08x, ctl: %08x, " \
|
||||
+ "data: %08x, arb: %08x\n",
|
||||
+ rt2880_spi_read(rs, RAMIPS_SPI_STAT),
|
||||
+ rt2880_spi_read(rs, RAMIPS_SPI_CFG),
|
||||
+ rt2880_spi_read(rs, RAMIPS_SPI_CTL),
|
||||
+ rt2880_spi_read(rs, RAMIPS_SPI_DATA),
|
||||
+ rt2880_spi_read(rs, get_arbiter_offset(master)));
|
||||
+}
|
||||
+
|
||||
+static int rt2880_spi_transfer_one(struct spi_master *master,
|
||||
+ struct spi_device *spi, struct spi_transfer *xfer)
|
||||
+{
|
||||
+ struct rt2880_spi *rs = spi_master_get_devdata(master);
|
||||
+ unsigned len;
|
||||
+ const u8 *tx = xfer->tx_buf;
|
||||
+ u8 *rx = xfer->rx_buf;
|
||||
+ int err = 0;
|
||||
+
|
||||
+ /* change clock speed */
|
||||
+ if (unlikely(rs->speed != xfer->speed_hz)) {
|
||||
+ u32 reg;
|
||||
+ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG);
|
||||
+ reg &= ~SPICFG_SPICLK_PRESCALE_MASK;
|
||||
+ reg |= rt2880_spi_baudrate_get(spi, xfer->speed_hz);
|
||||
+ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg);
|
||||
+ }
|
||||
+
|
||||
+ if (tx) {
|
||||
+ len = xfer->len;
|
||||
+ while (len-- > 0) {
|
||||
+ rt2880_spi_write(rs, RAMIPS_SPI_DATA, *tx++);
|
||||
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR);
|
||||
+ err = rt2880_spi_wait_ready(rs, 1);
|
||||
+ if (err) {
|
||||
+ dev_err(&spi->dev, "TX failed, err=%d\n", err);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (rx) {
|
||||
+ len = xfer->len;
|
||||
+ while (len-- > 0) {
|
||||
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD);
|
||||
+ err = rt2880_spi_wait_ready(rs, 1);
|
||||
+ if (err) {
|
||||
+ dev_err(&spi->dev, "RX failed, err=%d\n", err);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ *rx++ = (u8) rt2880_spi_read(rs, RAMIPS_SPI_DATA);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/* copy from spi.c */
|
||||
+static void spi_set_cs(struct spi_device *spi, bool enable)
|
||||
+{
|
||||
+ if (spi->mode & SPI_CS_HIGH)
|
||||
+ enable = !enable;
|
||||
+
|
||||
+ if (spi->cs_gpio >= 0)
|
||||
+ gpio_set_value(spi->cs_gpio, !enable);
|
||||
+ else if (spi->master->set_cs)
|
||||
+ spi->master->set_cs(spi, !enable);
|
||||
+}
|
||||
+
|
||||
+static int rt2880_spi_setup(struct spi_device *spi)
|
||||
+{
|
||||
+ struct spi_master *master = spi->master;
|
||||
+ struct rt2880_spi *rs = spi_master_get_devdata(master);
|
||||
+ u32 reg, old_reg, arbit_off;
|
||||
+
|
||||
+ if ((spi->max_speed_hz > master->max_speed_hz) ||
|
||||
+ (spi->max_speed_hz < master->min_speed_hz)) {
|
||||
+ dev_err(&spi->dev, "invalide requested speed %d Hz\n",
|
||||
+ spi->max_speed_hz);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (!(master->bits_per_word_mask &
|
||||
+ BIT(spi->bits_per_word - 1))) {
|
||||
+ dev_err(&spi->dev, "invalide bits_per_word %d\n",
|
||||
+ spi->bits_per_word);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* the hardware seems can't work on mode0 force it to mode3 */
|
||||
+ if ((spi->mode & (SPI_CPOL | SPI_CPHA)) == SPI_MODE_0) {
|
||||
+ dev_warn(&spi->dev, "force spi mode3\n");
|
||||
+ spi->mode |= SPI_MODE_3;
|
||||
+ }
|
||||
+
|
||||
+ /* chip polarity */
|
||||
+ arbit_off = get_arbiter_offset(master);
|
||||
+ reg = old_reg = rt2880_spi_read(rs, arbit_off);
|
||||
+ if (spi->mode & SPI_CS_HIGH) {
|
||||
+ switch (master->bus_num) {
|
||||
+ case 1:
|
||||
+ reg |= SPI1_POR;
|
||||
+ break;
|
||||
+ default:
|
||||
+ reg |= SPI0_POR;
|
||||
+ break;
|
||||
+ }
|
||||
+ } else {
|
||||
+ switch (master->bus_num) {
|
||||
+ case 1:
|
||||
+ reg &= ~SPI1_POR;
|
||||
+ break;
|
||||
+ default:
|
||||
+ reg &= ~SPI0_POR;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* enable spi1 */
|
||||
+ if (master->bus_num == 1)
|
||||
+ reg |= SPICTL_ARB_EN;
|
||||
+
|
||||
+ if (reg != old_reg)
|
||||
+ rt2880_spi_write(rs, arbit_off, reg);
|
||||
+
|
||||
+ /* deselected the spi device */
|
||||
+ spi_set_cs(spi, false);
|
||||
+
|
||||
+ rt2880_dump_reg(master);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_spi_prepare_message(struct spi_master *master,
|
||||
+ struct spi_message *msg)
|
||||
+{
|
||||
+ struct rt2880_spi *rs = spi_master_get_devdata(master);
|
||||
+ struct spi_device *spi = msg->spi;
|
||||
+ u32 reg;
|
||||
+
|
||||
+ if ((rs->mode == spi->mode) && (rs->speed == spi->max_speed_hz))
|
||||
+ return 0;
|
||||
+
|
||||
+#if 0
|
||||
+ /* set spido to tri-state */
|
||||
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_HIZSDO);
|
||||
+#endif
|
||||
+
|
||||
+ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG);
|
||||
+
|
||||
+ reg &= ~(SPICFG_MSBFIRST | SPICFG_SPICLKPOL |
|
||||
+ SPICFG_RXCLKEDGE_FALLING |
|
||||
+ SPICFG_TXCLKEDGE_FALLING |
|
||||
+ SPICFG_SPICLK_PRESCALE_MASK);
|
||||
+
|
||||
+ /* MSB */
|
||||
+ if (!(spi->mode & SPI_LSB_FIRST))
|
||||
+ reg |= SPICFG_MSBFIRST;
|
||||
+
|
||||
+ /* spi mode */
|
||||
+ switch (spi->mode & (SPI_CPOL | SPI_CPHA)) {
|
||||
+ case SPI_MODE_0:
|
||||
+ reg |= SPICFG_TXCLKEDGE_FALLING;
|
||||
+ break;
|
||||
+ case SPI_MODE_1:
|
||||
+ reg |= SPICFG_RXCLKEDGE_FALLING;
|
||||
+ break;
|
||||
+ case SPI_MODE_2:
|
||||
+ reg |= SPICFG_SPICLKPOL | SPICFG_RXCLKEDGE_FALLING;
|
||||
+ break;
|
||||
+ case SPI_MODE_3:
|
||||
+ reg |= SPICFG_SPICLKPOL | SPICFG_TXCLKEDGE_FALLING;
|
||||
+ break;
|
||||
+ }
|
||||
+ rs->mode = spi->mode;
|
||||
+
|
||||
+#if 0
|
||||
+ /* set spiclk and spiena to tri-state */
|
||||
+ reg |= SPICFG_HIZSPI;
|
||||
+#endif
|
||||
+
|
||||
+ /* clock divide */
|
||||
+ reg |= rt2880_spi_baudrate_get(spi, spi->max_speed_hz);
|
||||
+
|
||||
+ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_spi_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct spi_master *master;
|
||||
+ struct rt2880_spi *rs;
|
||||
+ void __iomem *base;
|
||||
+ struct resource *r;
|
||||
+ struct clk *clk;
|
||||
+ int ret;
|
||||
+
|
||||
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ base = devm_ioremap_resource(&pdev->dev, r);
|
||||
+ if (IS_ERR(base))
|
||||
+ return PTR_ERR(base);
|
||||
+
|
||||
+ clk = devm_clk_get(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(clk)) {
|
||||
+ dev_err(&pdev->dev, "unable to get SYS clock\n");
|
||||
+ return PTR_ERR(clk);
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_prepare_enable(clk);
|
||||
+ if (ret)
|
||||
+ goto err_clk;
|
||||
+
|
||||
+ master = spi_alloc_master(&pdev->dev, sizeof(*rs));
|
||||
+ if (master == NULL) {
|
||||
+ dev_dbg(&pdev->dev, "master allocation failed\n");
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_clk;
|
||||
+ }
|
||||
+
|
||||
+ master->dev.of_node = pdev->dev.of_node;
|
||||
+ master->mode_bits = RT2880_SPI_MODE_BITS;
|
||||
+ master->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
+ master->min_speed_hz = clk_get_rate(clk) / 128;
|
||||
+ master->max_speed_hz = clk_get_rate(clk) / 2;
|
||||
+ master->flags = SPI_MASTER_HALF_DUPLEX;
|
||||
+ master->setup = rt2880_spi_setup;
|
||||
+ master->prepare_message = rt2880_spi_prepare_message;
|
||||
+ master->set_cs = rt2880_spi_set_cs;
|
||||
+ master->transfer_one = rt2880_spi_transfer_one,
|
||||
+
|
||||
+ dev_set_drvdata(&pdev->dev, master);
|
||||
+
|
||||
+ rs = spi_master_get_devdata(master);
|
||||
+ rs->master = master;
|
||||
+ rs->base = base;
|
||||
+ rs->clk = clk;
|
||||
+
|
||||
+ if (atomic_inc_return(&hw_reset_count) == 1)
|
||||
+ device_reset(&pdev->dev);
|
||||
+
|
||||
+ ret = devm_spi_register_master(&pdev->dev, master);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&pdev->dev, "devm_spi_register_master error.\n");
|
||||
+ goto err_master;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+
|
||||
+err_master:
|
||||
+ spi_master_put(master);
|
||||
+ kfree(master);
|
||||
+err_clk:
|
||||
+ clk_disable_unprepare(clk);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_spi_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct spi_master *master;
|
||||
+ struct rt2880_spi *rs;
|
||||
+
|
||||
+ master = dev_get_drvdata(&pdev->dev);
|
||||
+ rs = spi_master_get_devdata(master);
|
||||
+
|
||||
+ clk_disable_unprepare(rs->clk);
|
||||
+ atomic_dec(&hw_reset_count);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+MODULE_ALIAS("platform:" DRIVER_NAME);
|
||||
+
|
||||
+static const struct of_device_id rt2880_spi_match[] = {
|
||||
+ { .compatible = "ralink,rt2880-spi" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, rt2880_spi_match);
|
||||
+
|
||||
+static struct platform_driver rt2880_spi_driver = {
|
||||
+ .driver = {
|
||||
+ .name = DRIVER_NAME,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = rt2880_spi_match,
|
||||
+ },
|
||||
+ .probe = rt2880_spi_probe,
|
||||
+ .remove = rt2880_spi_remove,
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(rt2880_spi_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Ralink SPI driver");
|
||||
+MODULE_AUTHOR("Sergiy <piratfm@gmail.com>");
|
||||
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
||||
+MODULE_LICENSE("GPL");
|
|
@ -1,487 +0,0 @@
|
|||
From cbd66c626e16743b05af807ad48012c0a097b9fb Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Roese <sr@denx.de>
|
||||
Date: Mon, 25 Mar 2019 09:29:25 +0100
|
||||
Subject: [PATCH] spi: mt7621: Move SPI driver out of staging
|
||||
|
||||
This patch moves the MT7621 SPI driver, which is used on some Ralink /
|
||||
MediaTek MT76xx MIPS SoC's, out of the staging directory. No changes to
|
||||
the source code are done in this patch.
|
||||
|
||||
This driver version was tested successfully on an MT7688 based platform
|
||||
with an SPI NOR on CS0 and an SPI NAND on CS1 without any issues (so
|
||||
far).
|
||||
|
||||
This patch also documents the devicetree bindings for the MT7621 SPI
|
||||
device driver.
|
||||
|
||||
Signed-off-by: Stefan Roese <sr@denx.de>
|
||||
Cc: Rob Herring <robh@kernel.org>
|
||||
Cc: Mark Brown <broonie@kernel.org>
|
||||
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Cc: NeilBrown <neil@brown.name>
|
||||
Cc: Sankalp Negi <sankalpnegi2310@gmail.com>
|
||||
Cc: Chuanhong Guo <gch981213@gmail.com>
|
||||
Cc: John Crispin <john@phrozen.org>
|
||||
Cc: Armando Miraglia <arma2ff0@gmail.com>
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
.../devicetree/bindings/spi/spi-mt7621.txt | 26 ++++++
|
||||
drivers/spi/Kconfig | 6 ++
|
||||
drivers/spi/Makefile | 1 +
|
||||
.../{staging/mt7621-spi => spi}/spi-mt7621.c | 83 +++++++++----------
|
||||
drivers/staging/Kconfig | 2 -
|
||||
drivers/staging/Makefile | 1 -
|
||||
drivers/staging/mt7621-spi/Kconfig | 6 --
|
||||
drivers/staging/mt7621-spi/Makefile | 1 -
|
||||
drivers/staging/mt7621-spi/TODO | 5 --
|
||||
9 files changed, 74 insertions(+), 57 deletions(-)
|
||||
create mode 100644 Documentation/devicetree/bindings/spi/spi-mt7621.txt
|
||||
rename drivers/{staging/mt7621-spi => spi}/spi-mt7621.c (88%)
|
||||
delete mode 100644 drivers/staging/mt7621-spi/Kconfig
|
||||
delete mode 100644 drivers/staging/mt7621-spi/Makefile
|
||||
delete mode 100644 drivers/staging/mt7621-spi/TODO
|
||||
|
||||
--- a/drivers/spi/Kconfig
|
||||
+++ b/drivers/spi/Kconfig
|
||||
@@ -569,6 +569,12 @@ config SPI_RT2880
|
||||
help
|
||||
This selects a driver for the Ralink RT288x/RT305x SPI Controller.
|
||||
|
||||
+config SPI_MT7621
|
||||
+ tristate "MediaTek MT7621 SPI Controller"
|
||||
+ depends on RALINK
|
||||
+ help
|
||||
+ This selects a driver for the MediaTek MT7621 SPI Controller.
|
||||
+
|
||||
config SPI_S3C24XX
|
||||
tristate "Samsung S3C24XX series SPI"
|
||||
depends on ARCH_S3C24XX
|
||||
--- a/drivers/spi/Makefile
|
||||
+++ b/drivers/spi/Makefile
|
||||
@@ -60,6 +60,7 @@ obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mp
|
||||
obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o
|
||||
obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o
|
||||
obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o
|
||||
+obj-$(CONFIG_SPI_MT7621) += spi-mt7621.o
|
||||
obj-$(CONFIG_SPI_MXS) += spi-mxs.o
|
||||
obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o
|
||||
obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/spi/spi-mt7621.c
|
||||
@@ -0,0 +1,416 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+//
|
||||
+// spi-mt7621.c -- MediaTek MT7621 SPI controller driver
|
||||
+//
|
||||
+// Copyright (C) 2011 Sergiy <piratfm@gmail.com>
|
||||
+// Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
|
||||
+// Copyright (C) 2014-2015 Felix Fietkau <nbd@nbd.name>
|
||||
+//
|
||||
+// Some parts are based on spi-orion.c:
|
||||
+// Author: Shadi Ammouri <shadi@marvell.com>
|
||||
+// Copyright (C) 2007-2008 Marvell Ltd.
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/spi/spi.h>
|
||||
+
|
||||
+#define DRIVER_NAME "spi-mt7621"
|
||||
+
|
||||
+/* in usec */
|
||||
+#define RALINK_SPI_WAIT_MAX_LOOP 2000
|
||||
+
|
||||
+/* SPISTAT register bit field */
|
||||
+#define SPISTAT_BUSY BIT(0)
|
||||
+
|
||||
+#define MT7621_SPI_TRANS 0x00
|
||||
+#define SPITRANS_BUSY BIT(16)
|
||||
+
|
||||
+#define MT7621_SPI_OPCODE 0x04
|
||||
+#define MT7621_SPI_DATA0 0x08
|
||||
+#define MT7621_SPI_DATA4 0x18
|
||||
+#define SPI_CTL_TX_RX_CNT_MASK 0xff
|
||||
+#define SPI_CTL_START BIT(8)
|
||||
+
|
||||
+#define MT7621_SPI_MASTER 0x28
|
||||
+#define MASTER_MORE_BUFMODE BIT(2)
|
||||
+#define MASTER_FULL_DUPLEX BIT(10)
|
||||
+#define MASTER_RS_CLK_SEL GENMASK(27, 16)
|
||||
+#define MASTER_RS_CLK_SEL_SHIFT 16
|
||||
+#define MASTER_RS_SLAVE_SEL GENMASK(31, 29)
|
||||
+
|
||||
+#define MT7621_SPI_MOREBUF 0x2c
|
||||
+#define MT7621_SPI_POLAR 0x38
|
||||
+#define MT7621_SPI_SPACE 0x3c
|
||||
+
|
||||
+#define MT7621_CPHA BIT(5)
|
||||
+#define MT7621_CPOL BIT(4)
|
||||
+#define MT7621_LSB_FIRST BIT(3)
|
||||
+
|
||||
+struct mt7621_spi {
|
||||
+ struct spi_controller *master;
|
||||
+ void __iomem *base;
|
||||
+ unsigned int sys_freq;
|
||||
+ unsigned int speed;
|
||||
+ struct clk *clk;
|
||||
+ int pending_write;
|
||||
+};
|
||||
+
|
||||
+static inline struct mt7621_spi *spidev_to_mt7621_spi(struct spi_device *spi)
|
||||
+{
|
||||
+ return spi_controller_get_devdata(spi->master);
|
||||
+}
|
||||
+
|
||||
+static inline u32 mt7621_spi_read(struct mt7621_spi *rs, u32 reg)
|
||||
+{
|
||||
+ return ioread32(rs->base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void mt7621_spi_write(struct mt7621_spi *rs, u32 reg, u32 val)
|
||||
+{
|
||||
+ iowrite32(val, rs->base + reg);
|
||||
+}
|
||||
+
|
||||
+static void mt7621_spi_set_cs(struct spi_device *spi, int enable)
|
||||
+{
|
||||
+ struct mt7621_spi *rs = spidev_to_mt7621_spi(spi);
|
||||
+ int cs = spi->chip_select;
|
||||
+ u32 polar = 0;
|
||||
+ u32 master;
|
||||
+
|
||||
+ /*
|
||||
+ * Select SPI device 7, enable "more buffer mode" and disable
|
||||
+ * full-duplex (only half-duplex really works on this chip
|
||||
+ * reliably)
|
||||
+ */
|
||||
+ master = mt7621_spi_read(rs, MT7621_SPI_MASTER);
|
||||
+ master |= MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE;
|
||||
+ master &= ~MASTER_FULL_DUPLEX;
|
||||
+ mt7621_spi_write(rs, MT7621_SPI_MASTER, master);
|
||||
+
|
||||
+ rs->pending_write = 0;
|
||||
+
|
||||
+ if (enable)
|
||||
+ polar = BIT(cs);
|
||||
+ mt7621_spi_write(rs, MT7621_SPI_POLAR, polar);
|
||||
+}
|
||||
+
|
||||
+static int mt7621_spi_prepare(struct spi_device *spi, unsigned int speed)
|
||||
+{
|
||||
+ struct mt7621_spi *rs = spidev_to_mt7621_spi(spi);
|
||||
+ u32 rate;
|
||||
+ u32 reg;
|
||||
+
|
||||
+ dev_dbg(&spi->dev, "speed:%u\n", speed);
|
||||
+
|
||||
+ rate = DIV_ROUND_UP(rs->sys_freq, speed);
|
||||
+ dev_dbg(&spi->dev, "rate-1:%u\n", rate);
|
||||
+
|
||||
+ if (rate > 4097)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (rate < 2)
|
||||
+ rate = 2;
|
||||
+
|
||||
+ reg = mt7621_spi_read(rs, MT7621_SPI_MASTER);
|
||||
+ reg &= ~MASTER_RS_CLK_SEL;
|
||||
+ reg |= (rate - 2) << MASTER_RS_CLK_SEL_SHIFT;
|
||||
+ rs->speed = speed;
|
||||
+
|
||||
+ reg &= ~MT7621_LSB_FIRST;
|
||||
+ if (spi->mode & SPI_LSB_FIRST)
|
||||
+ reg |= MT7621_LSB_FIRST;
|
||||
+
|
||||
+ /*
|
||||
+ * This SPI controller seems to be tested on SPI flash only and some
|
||||
+ * bits are swizzled under other SPI modes probably due to incorrect
|
||||
+ * wiring inside the silicon. Only mode 0 works correctly.
|
||||
+ */
|
||||
+ reg &= ~(MT7621_CPHA | MT7621_CPOL);
|
||||
+
|
||||
+ mt7621_spi_write(rs, MT7621_SPI_MASTER, reg);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mt7621_spi_wait_till_ready(struct mt7621_spi *rs)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < RALINK_SPI_WAIT_MAX_LOOP; i++) {
|
||||
+ u32 status;
|
||||
+
|
||||
+ status = mt7621_spi_read(rs, MT7621_SPI_TRANS);
|
||||
+ if ((status & SPITRANS_BUSY) == 0)
|
||||
+ return 0;
|
||||
+ cpu_relax();
|
||||
+ udelay(1);
|
||||
+ }
|
||||
+
|
||||
+ return -ETIMEDOUT;
|
||||
+}
|
||||
+
|
||||
+static void mt7621_spi_read_half_duplex(struct mt7621_spi *rs,
|
||||
+ int rx_len, u8 *buf)
|
||||
+{
|
||||
+ int tx_len;
|
||||
+
|
||||
+ /*
|
||||
+ * Combine with any pending write, and perform one or more half-duplex
|
||||
+ * transactions reading 'len' bytes. Data to be written is already in
|
||||
+ * MT7621_SPI_DATA.
|
||||
+ */
|
||||
+ tx_len = rs->pending_write;
|
||||
+ rs->pending_write = 0;
|
||||
+
|
||||
+ while (rx_len || tx_len) {
|
||||
+ int i;
|
||||
+ u32 val = (min(tx_len, 4) * 8) << 24;
|
||||
+ int rx = min(rx_len, 32);
|
||||
+
|
||||
+ if (tx_len > 4)
|
||||
+ val |= (tx_len - 4) * 8;
|
||||
+ val |= (rx * 8) << 12;
|
||||
+ mt7621_spi_write(rs, MT7621_SPI_MOREBUF, val);
|
||||
+
|
||||
+ tx_len = 0;
|
||||
+
|
||||
+ val = mt7621_spi_read(rs, MT7621_SPI_TRANS);
|
||||
+ val |= SPI_CTL_START;
|
||||
+ mt7621_spi_write(rs, MT7621_SPI_TRANS, val);
|
||||
+
|
||||
+ mt7621_spi_wait_till_ready(rs);
|
||||
+
|
||||
+ for (i = 0; i < rx; i++) {
|
||||
+ if ((i % 4) == 0)
|
||||
+ val = mt7621_spi_read(rs, MT7621_SPI_DATA0 + i);
|
||||
+ *buf++ = val & 0xff;
|
||||
+ val >>= 8;
|
||||
+ }
|
||||
+
|
||||
+ rx_len -= i;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline void mt7621_spi_flush(struct mt7621_spi *rs)
|
||||
+{
|
||||
+ mt7621_spi_read_half_duplex(rs, 0, NULL);
|
||||
+}
|
||||
+
|
||||
+static void mt7621_spi_write_half_duplex(struct mt7621_spi *rs,
|
||||
+ int tx_len, const u8 *buf)
|
||||
+{
|
||||
+ int len = rs->pending_write;
|
||||
+ int val = 0;
|
||||
+
|
||||
+ if (len & 3) {
|
||||
+ val = mt7621_spi_read(rs, MT7621_SPI_OPCODE + (len & ~3));
|
||||
+ if (len < 4) {
|
||||
+ val <<= (4 - len) * 8;
|
||||
+ val = swab32(val);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ while (tx_len > 0) {
|
||||
+ if (len >= 36) {
|
||||
+ rs->pending_write = len;
|
||||
+ mt7621_spi_flush(rs);
|
||||
+ len = 0;
|
||||
+ }
|
||||
+
|
||||
+ val |= *buf++ << (8 * (len & 3));
|
||||
+ len++;
|
||||
+ if ((len & 3) == 0) {
|
||||
+ if (len == 4)
|
||||
+ /* The byte-order of the opcode is weird! */
|
||||
+ val = swab32(val);
|
||||
+ mt7621_spi_write(rs, MT7621_SPI_OPCODE + len - 4, val);
|
||||
+ val = 0;
|
||||
+ }
|
||||
+ tx_len -= 1;
|
||||
+ }
|
||||
+
|
||||
+ if (len & 3) {
|
||||
+ if (len < 4) {
|
||||
+ val = swab32(val);
|
||||
+ val >>= (4 - len) * 8;
|
||||
+ }
|
||||
+ mt7621_spi_write(rs, MT7621_SPI_OPCODE + (len & ~3), val);
|
||||
+ }
|
||||
+
|
||||
+ rs->pending_write = len;
|
||||
+}
|
||||
+
|
||||
+static int mt7621_spi_transfer_one_message(struct spi_controller *master,
|
||||
+ struct spi_message *m)
|
||||
+{
|
||||
+ struct mt7621_spi *rs = spi_controller_get_devdata(master);
|
||||
+ struct spi_device *spi = m->spi;
|
||||
+ unsigned int speed = spi->max_speed_hz;
|
||||
+ struct spi_transfer *t = NULL;
|
||||
+ int status = 0;
|
||||
+
|
||||
+ mt7621_spi_wait_till_ready(rs);
|
||||
+
|
||||
+ list_for_each_entry(t, &m->transfers, transfer_list)
|
||||
+ if (t->speed_hz < speed)
|
||||
+ speed = t->speed_hz;
|
||||
+
|
||||
+ if (mt7621_spi_prepare(spi, speed)) {
|
||||
+ status = -EIO;
|
||||
+ goto msg_done;
|
||||
+ }
|
||||
+
|
||||
+ /* Assert CS */
|
||||
+ mt7621_spi_set_cs(spi, 1);
|
||||
+
|
||||
+ m->actual_length = 0;
|
||||
+ list_for_each_entry(t, &m->transfers, transfer_list) {
|
||||
+ if ((t->rx_buf) && (t->tx_buf)) {
|
||||
+ /*
|
||||
+ * This controller will shift some extra data out
|
||||
+ * of spi_opcode if (mosi_bit_cnt > 0) &&
|
||||
+ * (cmd_bit_cnt == 0). So the claimed full-duplex
|
||||
+ * support is broken since we have no way to read
|
||||
+ * the MISO value during that bit.
|
||||
+ */
|
||||
+ status = -EIO;
|
||||
+ goto msg_done;
|
||||
+ } else if (t->rx_buf) {
|
||||
+ mt7621_spi_read_half_duplex(rs, t->len, t->rx_buf);
|
||||
+ } else if (t->tx_buf) {
|
||||
+ mt7621_spi_write_half_duplex(rs, t->len, t->tx_buf);
|
||||
+ }
|
||||
+ m->actual_length += t->len;
|
||||
+ }
|
||||
+
|
||||
+ /* Flush data and deassert CS */
|
||||
+ mt7621_spi_flush(rs);
|
||||
+ mt7621_spi_set_cs(spi, 0);
|
||||
+
|
||||
+msg_done:
|
||||
+ m->status = status;
|
||||
+ spi_finalize_current_message(master);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mt7621_spi_setup(struct spi_device *spi)
|
||||
+{
|
||||
+ struct mt7621_spi *rs = spidev_to_mt7621_spi(spi);
|
||||
+
|
||||
+ if ((spi->max_speed_hz == 0) ||
|
||||
+ (spi->max_speed_hz > (rs->sys_freq / 2)))
|
||||
+ spi->max_speed_hz = (rs->sys_freq / 2);
|
||||
+
|
||||
+ if (spi->max_speed_hz < (rs->sys_freq / 4097)) {
|
||||
+ dev_err(&spi->dev, "setup: requested speed is too low %d Hz\n",
|
||||
+ spi->max_speed_hz);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mt7621_spi_match[] = {
|
||||
+ { .compatible = "ralink,mt7621-spi" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mt7621_spi_match);
|
||||
+
|
||||
+static int mt7621_spi_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ const struct of_device_id *match;
|
||||
+ struct spi_controller *master;
|
||||
+ struct mt7621_spi *rs;
|
||||
+ void __iomem *base;
|
||||
+ struct resource *r;
|
||||
+ int status = 0;
|
||||
+ struct clk *clk;
|
||||
+ int ret;
|
||||
+
|
||||
+ match = of_match_device(mt7621_spi_match, &pdev->dev);
|
||||
+ if (!match)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ base = devm_ioremap_resource(&pdev->dev, r);
|
||||
+ if (IS_ERR(base))
|
||||
+ return PTR_ERR(base);
|
||||
+
|
||||
+ clk = devm_clk_get(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(clk)) {
|
||||
+ dev_err(&pdev->dev, "unable to get SYS clock, err=%d\n",
|
||||
+ status);
|
||||
+ return PTR_ERR(clk);
|
||||
+ }
|
||||
+
|
||||
+ status = clk_prepare_enable(clk);
|
||||
+ if (status)
|
||||
+ return status;
|
||||
+
|
||||
+ master = spi_alloc_master(&pdev->dev, sizeof(*rs));
|
||||
+ if (!master) {
|
||||
+ dev_info(&pdev->dev, "master allocation failed\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ master->mode_bits = SPI_LSB_FIRST;
|
||||
+ master->flags = SPI_CONTROLLER_HALF_DUPLEX;
|
||||
+ master->setup = mt7621_spi_setup;
|
||||
+ master->transfer_one_message = mt7621_spi_transfer_one_message;
|
||||
+ master->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
+ master->dev.of_node = pdev->dev.of_node;
|
||||
+ master->num_chipselect = 2;
|
||||
+
|
||||
+ dev_set_drvdata(&pdev->dev, master);
|
||||
+
|
||||
+ rs = spi_controller_get_devdata(master);
|
||||
+ rs->base = base;
|
||||
+ rs->clk = clk;
|
||||
+ rs->master = master;
|
||||
+ rs->sys_freq = clk_get_rate(rs->clk);
|
||||
+ rs->pending_write = 0;
|
||||
+ dev_info(&pdev->dev, "sys_freq: %u\n", rs->sys_freq);
|
||||
+
|
||||
+ ret = device_reset(&pdev->dev);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "SPI reset failed!\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return devm_spi_register_controller(&pdev->dev, master);
|
||||
+}
|
||||
+
|
||||
+static int mt7621_spi_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct spi_controller *master;
|
||||
+ struct mt7621_spi *rs;
|
||||
+
|
||||
+ master = dev_get_drvdata(&pdev->dev);
|
||||
+ rs = spi_controller_get_devdata(master);
|
||||
+
|
||||
+ clk_disable_unprepare(rs->clk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+MODULE_ALIAS("platform:" DRIVER_NAME);
|
||||
+
|
||||
+static struct platform_driver mt7621_spi_driver = {
|
||||
+ .driver = {
|
||||
+ .name = DRIVER_NAME,
|
||||
+ .of_match_table = mt7621_spi_match,
|
||||
+ },
|
||||
+ .probe = mt7621_spi_probe,
|
||||
+ .remove = mt7621_spi_remove,
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(mt7621_spi_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("MT7621 SPI driver");
|
||||
+MODULE_AUTHOR("Felix Fietkau <nbd@nbd.name>");
|
||||
+MODULE_LICENSE("GPL");
|
|
@ -1,507 +0,0 @@
|
|||
From 723b8beaabf3c3c4b1ce69480141f1e926f3f3b2 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 27 Jul 2014 09:52:56 +0100
|
||||
Subject: [PATCH 44/53] i2c: MIPS: adds ralink I2C driver
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
.../devicetree/bindings/i2c/i2c-ralink.txt | 27 ++
|
||||
drivers/i2c/busses/Kconfig | 4 +
|
||||
drivers/i2c/busses/Makefile | 1 +
|
||||
drivers/i2c/busses/i2c-ralink.c | 327 ++++++++++++++++++++
|
||||
4 files changed, 359 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/i2c/i2c-ralink.txt
|
||||
create mode 100644 drivers/i2c/busses/i2c-ralink.c
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/i2c/i2c-ralink.txt
|
||||
@@ -0,0 +1,27 @@
|
||||
+I2C for Ralink platforms
|
||||
+
|
||||
+Required properties :
|
||||
+- compatible : Must be "link,rt3052-i2c"
|
||||
+- reg: physical base address of the controller and length of memory mapped
|
||||
+ region.
|
||||
+- #address-cells = <1>;
|
||||
+- #size-cells = <0>;
|
||||
+
|
||||
+Optional properties:
|
||||
+- Child nodes conforming to i2c bus binding
|
||||
+
|
||||
+Example :
|
||||
+
|
||||
+palmbus@10000000 {
|
||||
+ i2c@900 {
|
||||
+ compatible = "link,rt3052-i2c";
|
||||
+ reg = <0x900 0x100>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ hwmon@4b {
|
||||
+ compatible = "national,lm92";
|
||||
+ reg = <0x4b>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
--- a/drivers/i2c/busses/Kconfig
|
||||
+++ b/drivers/i2c/busses/Kconfig
|
||||
@@ -864,6 +864,11 @@ config I2C_RK3X
|
||||
This driver can also be built as a module. If so, the module will
|
||||
be called i2c-rk3x.
|
||||
|
||||
+config I2C_RALINK
|
||||
+ tristate "Ralink I2C Controller"
|
||||
+ depends on RALINK && !SOC_MT7621
|
||||
+ select OF_I2C
|
||||
+
|
||||
config HAVE_S3C2410_I2C
|
||||
bool
|
||||
help
|
||||
--- a/drivers/i2c/busses/Makefile
|
||||
+++ b/drivers/i2c/busses/Makefile
|
||||
@@ -84,6 +84,7 @@ obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
|
||||
obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o
|
||||
obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
|
||||
obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
|
||||
+obj-$(CONFIG_I2C_RALINK) += i2c-ralink.o
|
||||
obj-$(CONFIG_I2C_QUP) += i2c-qup.o
|
||||
obj-$(CONFIG_I2C_RIIC) += i2c-riic.o
|
||||
obj-$(CONFIG_I2C_RK3X) += i2c-rk3x.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/i2c/busses/i2c-ralink.c
|
||||
@@ -0,0 +1,435 @@
|
||||
+/*
|
||||
+ * drivers/i2c/busses/i2c-ralink.c
|
||||
+ *
|
||||
+ * Copyright (C) 2013 Steven Liu <steven_liu@mediatek.com>
|
||||
+ * Copyright (C) 2016 Michael Lee <igvtee@gmail.com>
|
||||
+ *
|
||||
+ * Improve driver for i2cdetect from i2c-tools to detect i2c devices on the bus.
|
||||
+ * (C) 2014 Sittisak <sittisaks@hotmail.com>
|
||||
+ *
|
||||
+ * This software is licensed under the terms of the GNU General Public
|
||||
+ * License version 2, as published by the Free Software Foundation, and
|
||||
+ * may be copied, distributed, and modified under those terms.
|
||||
+ *
|
||||
+ * 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/interrupt.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/clk.h>
|
||||
+
|
||||
+#define REG_CONFIG_REG 0x00
|
||||
+#define REG_CLKDIV_REG 0x04
|
||||
+#define REG_DEVADDR_REG 0x08
|
||||
+#define REG_ADDR_REG 0x0C
|
||||
+#define REG_DATAOUT_REG 0x10
|
||||
+#define REG_DATAIN_REG 0x14
|
||||
+#define REG_STATUS_REG 0x18
|
||||
+#define REG_STARTXFR_REG 0x1C
|
||||
+#define REG_BYTECNT_REG 0x20
|
||||
+
|
||||
+/* REG_CONFIG_REG */
|
||||
+#define I2C_ADDRLEN_OFFSET 5
|
||||
+#define I2C_DEVADLEN_OFFSET 2
|
||||
+#define I2C_ADDRLEN_MASK 0x3
|
||||
+#define I2C_ADDR_DIS BIT(1)
|
||||
+#define I2C_DEVADDR_DIS BIT(0)
|
||||
+#define I2C_ADDRLEN_8 (7 << I2C_ADDRLEN_OFFSET)
|
||||
+#define I2C_DEVADLEN_7 (6 << I2C_DEVADLEN_OFFSET)
|
||||
+#define I2C_CONF_DEFAULT (I2C_ADDRLEN_8 | I2C_DEVADLEN_7)
|
||||
+
|
||||
+/* REG_CLKDIV_REG */
|
||||
+#define I2C_CLKDIV_MASK 0xffff
|
||||
+
|
||||
+/* REG_DEVADDR_REG */
|
||||
+#define I2C_DEVADDR_MASK 0x7f
|
||||
+
|
||||
+/* REG_ADDR_REG */
|
||||
+#define I2C_ADDR_MASK 0xff
|
||||
+
|
||||
+/* REG_STATUS_REG */
|
||||
+#define I2C_STARTERR BIT(4)
|
||||
+#define I2C_ACKERR BIT(3)
|
||||
+#define I2C_DATARDY BIT(2)
|
||||
+#define I2C_SDOEMPTY BIT(1)
|
||||
+#define I2C_BUSY BIT(0)
|
||||
+
|
||||
+/* REG_STARTXFR_REG */
|
||||
+#define NOSTOP_CMD BIT(2)
|
||||
+#define NODATA_CMD BIT(1)
|
||||
+#define READ_CMD BIT(0)
|
||||
+
|
||||
+/* REG_BYTECNT_REG */
|
||||
+#define BYTECNT_MAX 64
|
||||
+#define SET_BYTECNT(x) (x - 1)
|
||||
+
|
||||
+/* timeout waiting for I2C devices to respond (clock streching) */
|
||||
+#define TIMEOUT_MS 1000
|
||||
+#define DELAY_INTERVAL_US 100
|
||||
+
|
||||
+struct rt_i2c {
|
||||
+ void __iomem *base;
|
||||
+ struct clk *clk;
|
||||
+ struct device *dev;
|
||||
+ struct i2c_adapter adap;
|
||||
+ u32 cur_clk;
|
||||
+ u32 clk_div;
|
||||
+ u32 flags;
|
||||
+};
|
||||
+
|
||||
+static void rt_i2c_w32(struct rt_i2c *i2c, u32 val, unsigned reg)
|
||||
+{
|
||||
+ iowrite32(val, i2c->base + reg);
|
||||
+}
|
||||
+
|
||||
+static u32 rt_i2c_r32(struct rt_i2c *i2c, unsigned reg)
|
||||
+{
|
||||
+ return ioread32(i2c->base + reg);
|
||||
+}
|
||||
+
|
||||
+static int poll_down_timeout(void __iomem *addr, u32 mask)
|
||||
+{
|
||||
+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS);
|
||||
+
|
||||
+ do {
|
||||
+ if (!(readl_relaxed(addr) & mask))
|
||||
+ return 0;
|
||||
+
|
||||
+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
|
||||
+ } while (time_before(jiffies, timeout));
|
||||
+
|
||||
+ return (readl_relaxed(addr) & mask) ? -EAGAIN : 0;
|
||||
+}
|
||||
+
|
||||
+static int rt_i2c_wait_idle(struct rt_i2c *i2c)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = poll_down_timeout(i2c->base + REG_STATUS_REG, I2C_BUSY);
|
||||
+ if (ret < 0)
|
||||
+ dev_dbg(i2c->dev, "idle err(%d)\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int poll_up_timeout(void __iomem *addr, u32 mask)
|
||||
+{
|
||||
+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS);
|
||||
+ u32 status;
|
||||
+
|
||||
+ do {
|
||||
+ status = readl_relaxed(addr);
|
||||
+
|
||||
+ /* check error status */
|
||||
+ if (status & I2C_STARTERR)
|
||||
+ return -EAGAIN;
|
||||
+ else if (status & I2C_ACKERR)
|
||||
+ return -ENXIO;
|
||||
+ else if (status & mask)
|
||||
+ return 0;
|
||||
+
|
||||
+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
|
||||
+ } while (time_before(jiffies, timeout));
|
||||
+
|
||||
+ return -ETIMEDOUT;
|
||||
+}
|
||||
+
|
||||
+static int rt_i2c_wait_rx_done(struct rt_i2c *i2c)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = poll_up_timeout(i2c->base + REG_STATUS_REG, I2C_DATARDY);
|
||||
+ if (ret < 0)
|
||||
+ dev_dbg(i2c->dev, "rx err(%d)\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int rt_i2c_wait_tx_done(struct rt_i2c *i2c)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = poll_up_timeout(i2c->base + REG_STATUS_REG, I2C_SDOEMPTY);
|
||||
+ if (ret < 0)
|
||||
+ dev_dbg(i2c->dev, "tx err(%d)\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void rt_i2c_reset(struct rt_i2c *i2c)
|
||||
+{
|
||||
+ device_reset(i2c->adap.dev.parent);
|
||||
+ barrier();
|
||||
+ rt_i2c_w32(i2c, i2c->clk_div, REG_CLKDIV_REG);
|
||||
+}
|
||||
+
|
||||
+static void rt_i2c_dump_reg(struct rt_i2c *i2c)
|
||||
+{
|
||||
+ dev_dbg(i2c->dev, "conf %08x, clkdiv %08x, devaddr %08x, " \
|
||||
+ "addr %08x, dataout %08x, datain %08x, " \
|
||||
+ "status %08x, startxfr %08x, bytecnt %08x\n",
|
||||
+ rt_i2c_r32(i2c, REG_CONFIG_REG),
|
||||
+ rt_i2c_r32(i2c, REG_CLKDIV_REG),
|
||||
+ rt_i2c_r32(i2c, REG_DEVADDR_REG),
|
||||
+ rt_i2c_r32(i2c, REG_ADDR_REG),
|
||||
+ rt_i2c_r32(i2c, REG_DATAOUT_REG),
|
||||
+ rt_i2c_r32(i2c, REG_DATAIN_REG),
|
||||
+ rt_i2c_r32(i2c, REG_STATUS_REG),
|
||||
+ rt_i2c_r32(i2c, REG_STARTXFR_REG),
|
||||
+ rt_i2c_r32(i2c, REG_BYTECNT_REG));
|
||||
+}
|
||||
+
|
||||
+static int rt_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
|
||||
+ int num)
|
||||
+{
|
||||
+ struct rt_i2c *i2c;
|
||||
+ struct i2c_msg *pmsg;
|
||||
+ unsigned char addr;
|
||||
+ int i, j, ret;
|
||||
+ u32 cmd;
|
||||
+
|
||||
+ i2c = i2c_get_adapdata(adap);
|
||||
+
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ pmsg = &msgs[i];
|
||||
+ if (i == (num - 1))
|
||||
+ cmd = 0;
|
||||
+ else
|
||||
+ cmd = NOSTOP_CMD;
|
||||
+
|
||||
+ dev_dbg(i2c->dev, "addr: 0x%x, len: %d, flags: 0x%x, stop: %d\n",
|
||||
+ pmsg->addr, pmsg->len, pmsg->flags,
|
||||
+ (cmd == 0)? 1 : 0);
|
||||
+
|
||||
+ /* wait hardware idle */
|
||||
+ if ((ret = rt_i2c_wait_idle(i2c)))
|
||||
+ goto err_timeout;
|
||||
+
|
||||
+ if (pmsg->flags & I2C_M_TEN) {
|
||||
+ rt_i2c_w32(i2c, I2C_CONF_DEFAULT, REG_CONFIG_REG);
|
||||
+ /* 10 bits address */
|
||||
+ addr = 0x78 | ((pmsg->addr >> 8) & 0x03);
|
||||
+ rt_i2c_w32(i2c, addr & I2C_DEVADDR_MASK,
|
||||
+ REG_DEVADDR_REG);
|
||||
+ rt_i2c_w32(i2c, pmsg->addr & I2C_ADDR_MASK,
|
||||
+ REG_ADDR_REG);
|
||||
+ } else {
|
||||
+ rt_i2c_w32(i2c, I2C_CONF_DEFAULT | I2C_ADDR_DIS,
|
||||
+ REG_CONFIG_REG);
|
||||
+ /* 7 bits address */
|
||||
+ rt_i2c_w32(i2c, pmsg->addr & I2C_DEVADDR_MASK,
|
||||
+ REG_DEVADDR_REG);
|
||||
+ }
|
||||
+
|
||||
+ /* buffer length */
|
||||
+ if (pmsg->len == 0)
|
||||
+ cmd |= NODATA_CMD;
|
||||
+ else
|
||||
+ rt_i2c_w32(i2c, SET_BYTECNT(pmsg->len),
|
||||
+ REG_BYTECNT_REG);
|
||||
+
|
||||
+ j = 0;
|
||||
+ if (pmsg->flags & I2C_M_RD) {
|
||||
+ cmd |= READ_CMD;
|
||||
+ /* start transfer */
|
||||
+ barrier();
|
||||
+ rt_i2c_w32(i2c, cmd, REG_STARTXFR_REG);
|
||||
+ do {
|
||||
+ /* wait */
|
||||
+ if ((ret = rt_i2c_wait_rx_done(i2c)))
|
||||
+ goto err_timeout;
|
||||
+ /* read data */
|
||||
+ if (pmsg->len)
|
||||
+ pmsg->buf[j] = rt_i2c_r32(i2c,
|
||||
+ REG_DATAIN_REG);
|
||||
+ j++;
|
||||
+ } while (j < pmsg->len);
|
||||
+ } else {
|
||||
+ do {
|
||||
+ /* write data */
|
||||
+ if (pmsg->len)
|
||||
+ rt_i2c_w32(i2c, pmsg->buf[j],
|
||||
+ REG_DATAOUT_REG);
|
||||
+ /* start transfer */
|
||||
+ if (j == 0) {
|
||||
+ barrier();
|
||||
+ rt_i2c_w32(i2c, cmd, REG_STARTXFR_REG);
|
||||
+ }
|
||||
+ /* wait */
|
||||
+ if ((ret = rt_i2c_wait_tx_done(i2c)))
|
||||
+ goto err_timeout;
|
||||
+ j++;
|
||||
+ } while (j < pmsg->len);
|
||||
+ }
|
||||
+ }
|
||||
+ /* the return value is number of executed messages */
|
||||
+ ret = i;
|
||||
+
|
||||
+ return ret;
|
||||
+
|
||||
+err_timeout:
|
||||
+ rt_i2c_dump_reg(i2c);
|
||||
+ rt_i2c_reset(i2c);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static u32 rt_i2c_func(struct i2c_adapter *a)
|
||||
+{
|
||||
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
|
||||
+}
|
||||
+
|
||||
+static const struct i2c_algorithm rt_i2c_algo = {
|
||||
+ .master_xfer = rt_i2c_master_xfer,
|
||||
+ .functionality = rt_i2c_func,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id i2c_rt_dt_ids[] = {
|
||||
+ { .compatible = "ralink,rt2880-i2c" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(of, i2c_rt_dt_ids);
|
||||
+
|
||||
+static struct i2c_adapter_quirks rt_i2c_quirks = {
|
||||
+ .max_write_len = BYTECNT_MAX,
|
||||
+ .max_read_len = BYTECNT_MAX,
|
||||
+};
|
||||
+
|
||||
+static int rt_i2c_init(struct rt_i2c *i2c)
|
||||
+{
|
||||
+ u32 reg;
|
||||
+
|
||||
+ /* i2c_sclk = periph_clk / ((2 * clk_div) + 5) */
|
||||
+ i2c->clk_div = (clk_get_rate(i2c->clk) - (5 * i2c->cur_clk)) /
|
||||
+ (2 * i2c->cur_clk);
|
||||
+ if (i2c->clk_div < 8)
|
||||
+ i2c->clk_div = 8;
|
||||
+ if (i2c->clk_div > I2C_CLKDIV_MASK)
|
||||
+ i2c->clk_div = I2C_CLKDIV_MASK;
|
||||
+
|
||||
+ /* check support combinde/repeated start message */
|
||||
+ rt_i2c_w32(i2c, NOSTOP_CMD, REG_STARTXFR_REG);
|
||||
+ reg = rt_i2c_r32(i2c, REG_STARTXFR_REG) & NOSTOP_CMD;
|
||||
+
|
||||
+ rt_i2c_reset(i2c);
|
||||
+
|
||||
+ return reg;
|
||||
+}
|
||||
+
|
||||
+static int rt_i2c_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct resource *res;
|
||||
+ struct rt_i2c *i2c;
|
||||
+ struct i2c_adapter *adap;
|
||||
+ const struct of_device_id *match;
|
||||
+ int ret, restart;
|
||||
+
|
||||
+ match = of_match_device(i2c_rt_dt_ids, &pdev->dev);
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "no memory resource found\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ i2c = devm_kzalloc(&pdev->dev, sizeof(struct rt_i2c), GFP_KERNEL);
|
||||
+ if (!i2c) {
|
||||
+ dev_err(&pdev->dev, "failed to allocate i2c_adapter\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ i2c->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(i2c->base))
|
||||
+ return PTR_ERR(i2c->base);
|
||||
+
|
||||
+ i2c->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(i2c->clk)) {
|
||||
+ dev_err(&pdev->dev, "no clock defined\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+ clk_prepare_enable(i2c->clk);
|
||||
+ i2c->dev = &pdev->dev;
|
||||
+
|
||||
+ if (of_property_read_u32(pdev->dev.of_node,
|
||||
+ "clock-frequency", &i2c->cur_clk))
|
||||
+ i2c->cur_clk = 100000;
|
||||
+
|
||||
+ adap = &i2c->adap;
|
||||
+ adap->owner = THIS_MODULE;
|
||||
+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
|
||||
+ adap->algo = &rt_i2c_algo;
|
||||
+ adap->retries = 3;
|
||||
+ adap->dev.parent = &pdev->dev;
|
||||
+ i2c_set_adapdata(adap, i2c);
|
||||
+ adap->dev.of_node = pdev->dev.of_node;
|
||||
+ strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
|
||||
+ adap->quirks = &rt_i2c_quirks;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, i2c);
|
||||
+
|
||||
+ restart = rt_i2c_init(i2c);
|
||||
+
|
||||
+ ret = i2c_add_adapter(adap);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&pdev->dev, "failed to add adapter\n");
|
||||
+ clk_disable_unprepare(i2c->clk);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ dev_info(&pdev->dev, "clock %uKHz, re-start %ssupport\n",
|
||||
+ i2c->cur_clk/1000, restart ? "" : "not ");
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int rt_i2c_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct rt_i2c *i2c = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ i2c_del_adapter(&i2c->adap);
|
||||
+ clk_disable_unprepare(i2c->clk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver rt_i2c_driver = {
|
||||
+ .probe = rt_i2c_probe,
|
||||
+ .remove = rt_i2c_remove,
|
||||
+ .driver = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .name = "i2c-ralink",
|
||||
+ .of_match_table = i2c_rt_dt_ids,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init i2c_rt_init (void)
|
||||
+{
|
||||
+ return platform_driver_register(&rt_i2c_driver);
|
||||
+}
|
||||
+subsys_initcall(i2c_rt_init);
|
||||
+
|
||||
+static void __exit i2c_rt_exit (void)
|
||||
+{
|
||||
+ platform_driver_unregister(&rt_i2c_driver);
|
||||
+}
|
||||
+module_exit(i2c_rt_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Steven Liu <steven_liu@mediatek.com>");
|
||||
+MODULE_DESCRIPTION("Ralink I2c host driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_ALIAS("platform:Ralink-I2C");
|
|
@ -1,473 +0,0 @@
|
|||
From d5c54ff3d1db0a4348fa04d8e78f3bf6063e3afc Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 7 Dec 2015 17:21:27 +0100
|
||||
Subject: [PATCH 45/53] i2c: add mt7621 driver
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/i2c/busses/Kconfig | 4 +
|
||||
drivers/i2c/busses/Makefile | 1 +
|
||||
drivers/i2c/busses/i2c-mt7621.c | 303 +++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 308 insertions(+)
|
||||
create mode 100644 drivers/i2c/busses/i2c-mt7621.c
|
||||
|
||||
--- a/drivers/i2c/busses/Kconfig
|
||||
+++ b/drivers/i2c/busses/Kconfig
|
||||
@@ -869,6 +869,11 @@ config I2C_RALINK
|
||||
depends on RALINK && !SOC_MT7621
|
||||
select OF_I2C
|
||||
|
||||
+config I2C_MT7621
|
||||
+ tristate "MT7621/MT7628 I2C Controller"
|
||||
+ depends on RALINK && (SOC_MT7620 || SOC_MT7621)
|
||||
+ select OF_I2C
|
||||
+
|
||||
config HAVE_S3C2410_I2C
|
||||
bool
|
||||
help
|
||||
--- a/drivers/i2c/busses/Makefile
|
||||
+++ b/drivers/i2c/busses/Makefile
|
||||
@@ -85,6 +85,7 @@ obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o
|
||||
obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
|
||||
obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
|
||||
obj-$(CONFIG_I2C_RALINK) += i2c-ralink.o
|
||||
+obj-$(CONFIG_I2C_MT7621) += i2c-mt7621.o
|
||||
obj-$(CONFIG_I2C_QUP) += i2c-qup.o
|
||||
obj-$(CONFIG_I2C_RIIC) += i2c-riic.o
|
||||
obj-$(CONFIG_I2C_RK3X) += i2c-rk3x.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/i2c/busses/i2c-mt7621.c
|
||||
@@ -0,0 +1,433 @@
|
||||
+/*
|
||||
+ * drivers/i2c/busses/i2c-mt7621.c
|
||||
+ *
|
||||
+ * Copyright (C) 2013 Steven Liu <steven_liu@mediatek.com>
|
||||
+ * Copyright (C) 2016 Michael Lee <igvtee@gmail.com>
|
||||
+ *
|
||||
+ * Improve driver for i2cdetect from i2c-tools to detect i2c devices on the bus.
|
||||
+ * (C) 2014 Sittisak <sittisaks@hotmail.com>
|
||||
+ *
|
||||
+ * This software is licensed under the terms of the GNU General Public
|
||||
+ * License version 2, as published by the Free Software Foundation, and
|
||||
+ * may be copied, distributed, and modified under those terms.
|
||||
+ *
|
||||
+ * 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/interrupt.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/clk.h>
|
||||
+
|
||||
+#define REG_SM0CFG0 0x08
|
||||
+#define REG_SM0DOUT 0x10
|
||||
+#define REG_SM0DIN 0x14
|
||||
+#define REG_SM0ST 0x18
|
||||
+#define REG_SM0AUTO 0x1C
|
||||
+#define REG_SM0CFG1 0x20
|
||||
+#define REG_SM0CFG2 0x28
|
||||
+#define REG_SM0CTL0 0x40
|
||||
+#define REG_SM0CTL1 0x44
|
||||
+#define REG_SM0D0 0x50
|
||||
+#define REG_SM0D1 0x54
|
||||
+#define REG_PINTEN 0x5C
|
||||
+#define REG_PINTST 0x60
|
||||
+#define REG_PINTCL 0x64
|
||||
+
|
||||
+/* REG_SM0CFG0 */
|
||||
+#define I2C_DEVADDR_MASK 0x7f
|
||||
+
|
||||
+/* REG_SM0ST */
|
||||
+#define I2C_DATARDY BIT(2)
|
||||
+#define I2C_SDOEMPTY BIT(1)
|
||||
+#define I2C_BUSY BIT(0)
|
||||
+
|
||||
+/* REG_SM0AUTO */
|
||||
+#define READ_CMD BIT(0)
|
||||
+
|
||||
+/* REG_SM0CFG1 */
|
||||
+#define BYTECNT_MAX 64
|
||||
+#define SET_BYTECNT(x) (x - 1)
|
||||
+
|
||||
+/* REG_SM0CFG2 */
|
||||
+#define AUTOMODE_EN BIT(0)
|
||||
+
|
||||
+/* REG_SM0CTL0 */
|
||||
+#define ODRAIN_HIGH_SM0 BIT(31)
|
||||
+#define VSYNC_SHIFT 28
|
||||
+#define VSYNC_MASK 0x3
|
||||
+#define VSYNC_PULSE (0x1 << VSYNC_SHIFT)
|
||||
+#define VSYNC_RISING (0x2 << VSYNC_SHIFT)
|
||||
+#define CLK_DIV_SHIFT 16
|
||||
+#define CLK_DIV_MASK 0xfff
|
||||
+#define DEG_CNT_SHIFT 8
|
||||
+#define DEG_CNT_MASK 0xff
|
||||
+#define WAIT_HIGH BIT(6)
|
||||
+#define DEG_EN BIT(5)
|
||||
+#define CS_STATUA BIT(4)
|
||||
+#define SCL_STATUS BIT(3)
|
||||
+#define SDA_STATUS BIT(2)
|
||||
+#define SM0_EN BIT(1)
|
||||
+#define SCL_STRECH BIT(0)
|
||||
+
|
||||
+/* REG_SM0CTL1 */
|
||||
+#define ACK_SHIFT 16
|
||||
+#define ACK_MASK 0xff
|
||||
+#define PGLEN_SHIFT 8
|
||||
+#define PGLEN_MASK 0x7
|
||||
+#define SM0_MODE_SHIFT 4
|
||||
+#define SM0_MODE_MASK 0x7
|
||||
+#define SM0_MODE_START 0x1
|
||||
+#define SM0_MODE_WRITE 0x2
|
||||
+#define SM0_MODE_STOP 0x3
|
||||
+#define SM0_MODE_READ_NACK 0x4
|
||||
+#define SM0_MODE_READ_ACK 0x5
|
||||
+#define SM0_TRI_BUSY BIT(0)
|
||||
+
|
||||
+/* timeout waiting for I2C devices to respond (clock streching) */
|
||||
+#define TIMEOUT_MS 1000
|
||||
+#define DELAY_INTERVAL_US 100
|
||||
+
|
||||
+struct mtk_i2c {
|
||||
+ void __iomem *base;
|
||||
+ struct clk *clk;
|
||||
+ struct device *dev;
|
||||
+ struct i2c_adapter adap;
|
||||
+ u32 cur_clk;
|
||||
+ u32 clk_div;
|
||||
+ u32 flags;
|
||||
+};
|
||||
+
|
||||
+static void mtk_i2c_w32(struct mtk_i2c *i2c, u32 val, unsigned reg)
|
||||
+{
|
||||
+ iowrite32(val, i2c->base + reg);
|
||||
+}
|
||||
+
|
||||
+static u32 mtk_i2c_r32(struct mtk_i2c *i2c, unsigned reg)
|
||||
+{
|
||||
+ return ioread32(i2c->base + reg);
|
||||
+}
|
||||
+
|
||||
+static int poll_down_timeout(void __iomem *addr, u32 mask)
|
||||
+{
|
||||
+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS);
|
||||
+
|
||||
+ do {
|
||||
+ if (!(readl_relaxed(addr) & mask))
|
||||
+ return 0;
|
||||
+
|
||||
+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
|
||||
+ } while (time_before(jiffies, timeout));
|
||||
+
|
||||
+ return (readl_relaxed(addr) & mask) ? -EAGAIN : 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_i2c_wait_idle(struct mtk_i2c *i2c)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = poll_down_timeout(i2c->base + REG_SM0ST, I2C_BUSY);
|
||||
+ if (ret < 0)
|
||||
+ dev_dbg(i2c->dev, "idle err(%d)\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int poll_up_timeout(void __iomem *addr, u32 mask)
|
||||
+{
|
||||
+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS);
|
||||
+ u32 status;
|
||||
+
|
||||
+ do {
|
||||
+ status = readl_relaxed(addr);
|
||||
+ if (status & mask)
|
||||
+ return 0;
|
||||
+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
|
||||
+ } while (time_before(jiffies, timeout));
|
||||
+
|
||||
+ return -ETIMEDOUT;
|
||||
+}
|
||||
+
|
||||
+static int mtk_i2c_wait_rx_done(struct mtk_i2c *i2c)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = poll_up_timeout(i2c->base + REG_SM0ST, I2C_DATARDY);
|
||||
+ if (ret < 0)
|
||||
+ dev_dbg(i2c->dev, "rx err(%d)\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int mtk_i2c_wait_tx_done(struct mtk_i2c *i2c)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = poll_up_timeout(i2c->base + REG_SM0ST, I2C_SDOEMPTY);
|
||||
+ if (ret < 0)
|
||||
+ dev_dbg(i2c->dev, "tx err(%d)\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void mtk_i2c_reset(struct mtk_i2c *i2c)
|
||||
+{
|
||||
+ u32 reg;
|
||||
+ device_reset(i2c->adap.dev.parent);
|
||||
+ barrier();
|
||||
+
|
||||
+ /* ctrl0 */
|
||||
+ reg = ODRAIN_HIGH_SM0 | VSYNC_PULSE | (i2c->clk_div << CLK_DIV_SHIFT) |
|
||||
+ WAIT_HIGH | SM0_EN;
|
||||
+ mtk_i2c_w32(i2c, reg, REG_SM0CTL0);
|
||||
+
|
||||
+ /* auto mode */
|
||||
+ mtk_i2c_w32(i2c, AUTOMODE_EN, REG_SM0CFG2);
|
||||
+}
|
||||
+
|
||||
+static void mtk_i2c_dump_reg(struct mtk_i2c *i2c)
|
||||
+{
|
||||
+ dev_dbg(i2c->dev, "cfg0 %08x, dout %08x, din %08x, " \
|
||||
+ "status %08x, auto %08x, cfg1 %08x, " \
|
||||
+ "cfg2 %08x, ctl0 %08x, ctl1 %08x\n",
|
||||
+ mtk_i2c_r32(i2c, REG_SM0CFG0),
|
||||
+ mtk_i2c_r32(i2c, REG_SM0DOUT),
|
||||
+ mtk_i2c_r32(i2c, REG_SM0DIN),
|
||||
+ mtk_i2c_r32(i2c, REG_SM0ST),
|
||||
+ mtk_i2c_r32(i2c, REG_SM0AUTO),
|
||||
+ mtk_i2c_r32(i2c, REG_SM0CFG1),
|
||||
+ mtk_i2c_r32(i2c, REG_SM0CFG2),
|
||||
+ mtk_i2c_r32(i2c, REG_SM0CTL0),
|
||||
+ mtk_i2c_r32(i2c, REG_SM0CTL1));
|
||||
+}
|
||||
+
|
||||
+static int mtk_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
|
||||
+ int num)
|
||||
+{
|
||||
+ struct mtk_i2c *i2c;
|
||||
+ struct i2c_msg *pmsg;
|
||||
+ int i, j, ret;
|
||||
+ u32 cmd;
|
||||
+
|
||||
+ i2c = i2c_get_adapdata(adap);
|
||||
+
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ pmsg = &msgs[i];
|
||||
+ cmd = 0;
|
||||
+
|
||||
+ dev_dbg(i2c->dev, "addr: 0x%x, len: %d, flags: 0x%x\n",
|
||||
+ pmsg->addr, pmsg->len, pmsg->flags);
|
||||
+
|
||||
+ /* wait hardware idle */
|
||||
+ if ((ret = mtk_i2c_wait_idle(i2c)))
|
||||
+ goto err_timeout;
|
||||
+
|
||||
+ if (pmsg->flags & I2C_M_TEN) {
|
||||
+ dev_dbg(i2c->dev, "10 bits addr not supported\n");
|
||||
+ return -EINVAL;
|
||||
+ } else {
|
||||
+ /* 7 bits address */
|
||||
+ mtk_i2c_w32(i2c, pmsg->addr & I2C_DEVADDR_MASK,
|
||||
+ REG_SM0CFG0);
|
||||
+ }
|
||||
+
|
||||
+ /* buffer length */
|
||||
+ if (pmsg->len == 0) {
|
||||
+ dev_dbg(i2c->dev, "length is 0\n");
|
||||
+ return -EINVAL;
|
||||
+ } else
|
||||
+ mtk_i2c_w32(i2c, SET_BYTECNT(pmsg->len),
|
||||
+ REG_SM0CFG1);
|
||||
+
|
||||
+ j = 0;
|
||||
+ if (pmsg->flags & I2C_M_RD) {
|
||||
+ cmd |= READ_CMD;
|
||||
+ /* start transfer */
|
||||
+ barrier();
|
||||
+ mtk_i2c_w32(i2c, cmd, REG_SM0AUTO);
|
||||
+ do {
|
||||
+ /* wait */
|
||||
+ if ((ret = mtk_i2c_wait_rx_done(i2c)))
|
||||
+ goto err_timeout;
|
||||
+ /* read data */
|
||||
+ if (pmsg->len)
|
||||
+ pmsg->buf[j] = mtk_i2c_r32(i2c,
|
||||
+ REG_SM0DIN);
|
||||
+ j++;
|
||||
+ } while (j < pmsg->len);
|
||||
+ } else {
|
||||
+ do {
|
||||
+ /* write data */
|
||||
+ if (pmsg->len)
|
||||
+ mtk_i2c_w32(i2c, pmsg->buf[j],
|
||||
+ REG_SM0DOUT);
|
||||
+ /* start transfer */
|
||||
+ if (j == 0) {
|
||||
+ barrier();
|
||||
+ mtk_i2c_w32(i2c, cmd, REG_SM0AUTO);
|
||||
+ }
|
||||
+ /* wait */
|
||||
+ if ((ret = mtk_i2c_wait_tx_done(i2c)))
|
||||
+ goto err_timeout;
|
||||
+ j++;
|
||||
+ } while (j < pmsg->len);
|
||||
+ }
|
||||
+ }
|
||||
+ /* the return value is number of executed messages */
|
||||
+ ret = i;
|
||||
+
|
||||
+ return ret;
|
||||
+
|
||||
+err_timeout:
|
||||
+ mtk_i2c_dump_reg(i2c);
|
||||
+ mtk_i2c_reset(i2c);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static u32 mtk_i2c_func(struct i2c_adapter *a)
|
||||
+{
|
||||
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
|
||||
+}
|
||||
+
|
||||
+static const struct i2c_algorithm mtk_i2c_algo = {
|
||||
+ .master_xfer = mtk_i2c_master_xfer,
|
||||
+ .functionality = mtk_i2c_func,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id i2c_mtk_dt_ids[] = {
|
||||
+ { .compatible = "mediatek,mt7621-i2c" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(of, i2c_mtk_dt_ids);
|
||||
+
|
||||
+static struct i2c_adapter_quirks mtk_i2c_quirks = {
|
||||
+ .max_write_len = BYTECNT_MAX,
|
||||
+ .max_read_len = BYTECNT_MAX,
|
||||
+};
|
||||
+
|
||||
+static void mtk_i2c_init(struct mtk_i2c *i2c)
|
||||
+{
|
||||
+ i2c->clk_div = clk_get_rate(i2c->clk) / i2c->cur_clk;
|
||||
+ if (i2c->clk_div > CLK_DIV_MASK)
|
||||
+ i2c->clk_div = CLK_DIV_MASK;
|
||||
+
|
||||
+ mtk_i2c_reset(i2c);
|
||||
+}
|
||||
+
|
||||
+static int mtk_i2c_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct resource *res;
|
||||
+ struct mtk_i2c *i2c;
|
||||
+ struct i2c_adapter *adap;
|
||||
+ const struct of_device_id *match;
|
||||
+ int ret;
|
||||
+
|
||||
+ match = of_match_device(i2c_mtk_dt_ids, &pdev->dev);
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "no memory resource found\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ i2c = devm_kzalloc(&pdev->dev, sizeof(struct mtk_i2c), GFP_KERNEL);
|
||||
+ if (!i2c) {
|
||||
+ dev_err(&pdev->dev, "failed to allocate i2c_adapter\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ i2c->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(i2c->base))
|
||||
+ return PTR_ERR(i2c->base);
|
||||
+
|
||||
+ i2c->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(i2c->clk)) {
|
||||
+ dev_err(&pdev->dev, "no clock defined\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+ clk_prepare_enable(i2c->clk);
|
||||
+ i2c->dev = &pdev->dev;
|
||||
+
|
||||
+ if (of_property_read_u32(pdev->dev.of_node,
|
||||
+ "clock-frequency", &i2c->cur_clk))
|
||||
+ i2c->cur_clk = 100000;
|
||||
+
|
||||
+ adap = &i2c->adap;
|
||||
+ adap->owner = THIS_MODULE;
|
||||
+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
|
||||
+ adap->algo = &mtk_i2c_algo;
|
||||
+ adap->retries = 3;
|
||||
+ adap->dev.parent = &pdev->dev;
|
||||
+ i2c_set_adapdata(adap, i2c);
|
||||
+ adap->dev.of_node = pdev->dev.of_node;
|
||||
+ strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
|
||||
+ adap->quirks = &mtk_i2c_quirks;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, i2c);
|
||||
+
|
||||
+ mtk_i2c_init(i2c);
|
||||
+
|
||||
+ ret = i2c_add_adapter(adap);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&pdev->dev, "failed to add adapter\n");
|
||||
+ clk_disable_unprepare(i2c->clk);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ dev_info(&pdev->dev, "clock %uKHz, re-start not support\n",
|
||||
+ i2c->cur_clk/1000);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int mtk_i2c_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mtk_i2c *i2c = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ i2c_del_adapter(&i2c->adap);
|
||||
+ clk_disable_unprepare(i2c->clk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver mtk_i2c_driver = {
|
||||
+ .probe = mtk_i2c_probe,
|
||||
+ .remove = mtk_i2c_remove,
|
||||
+ .driver = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .name = "i2c-mt7621",
|
||||
+ .of_match_table = i2c_mtk_dt_ids,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init i2c_mtk_init (void)
|
||||
+{
|
||||
+ return platform_driver_register(&mtk_i2c_driver);
|
||||
+}
|
||||
+subsys_initcall(i2c_mtk_init);
|
||||
+
|
||||
+static void __exit i2c_mtk_exit (void)
|
||||
+{
|
||||
+ platform_driver_unregister(&mtk_i2c_driver);
|
||||
+}
|
||||
+module_exit(i2c_mtk_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Steven Liu <steven_liu@mediatek.com>");
|
||||
+MODULE_DESCRIPTION("MT7621 I2c host driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_ALIAS("platform:MT7621-I2C");
|
|
@ -1,43 +0,0 @@
|
|||
From 23147af14531cbdada194b94120ef8774f46292d Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 13 Nov 2014 19:08:40 +0100
|
||||
Subject: [PATCH 46/53] mmc: MIPS: ralink: add sdhci for mt7620a SoC
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/mmc/host/Kconfig | 2 +
|
||||
drivers/mmc/host/Makefile | 1 +
|
||||
drivers/mmc/host/mtk-mmc/Kconfig | 16 +
|
||||
drivers/mmc/host/mtk-mmc/Makefile | 42 +
|
||||
drivers/mmc/host/mtk-mmc/board.h | 137 ++
|
||||
drivers/mmc/host/mtk-mmc/dbg.c | 347 ++++
|
||||
drivers/mmc/host/mtk-mmc/dbg.h | 156 ++
|
||||
drivers/mmc/host/mtk-mmc/mt6575_sd.h | 1001 +++++++++++
|
||||
drivers/mmc/host/mtk-mmc/sd.c | 3060 ++++++++++++++++++++++++++++++++++
|
||||
9 files changed, 4762 insertions(+)
|
||||
create mode 100644 drivers/mmc/host/mtk-mmc/Kconfig
|
||||
create mode 100644 drivers/mmc/host/mtk-mmc/Makefile
|
||||
create mode 100644 drivers/mmc/host/mtk-mmc/board.h
|
||||
create mode 100644 drivers/mmc/host/mtk-mmc/dbg.c
|
||||
create mode 100644 drivers/mmc/host/mtk-mmc/dbg.h
|
||||
create mode 100644 drivers/mmc/host/mtk-mmc/mt6575_sd.h
|
||||
create mode 100644 drivers/mmc/host/mtk-mmc/sd.c
|
||||
|
||||
--- a/drivers/mmc/host/Kconfig
|
||||
+++ b/drivers/mmc/host/Kconfig
|
||||
@@ -901,3 +901,5 @@ config MMC_SDHCI_XENON
|
||||
This selects Marvell Xenon eMMC/SD/SDIO SDHCI.
|
||||
If you have a controller with this interface, say Y or M here.
|
||||
If unsure, say N.
|
||||
+
|
||||
+source "drivers/mmc/host/mtk-mmc/Kconfig"
|
||||
--- a/drivers/mmc/host/Makefile
|
||||
+++ b/drivers/mmc/host/Makefile
|
||||
@@ -3,6 +3,7 @@
|
||||
# Makefile for MMC/SD host controller drivers
|
||||
#
|
||||
|
||||
+obj-$(CONFIG_MTK_MMC) += mtk-mmc/
|
||||
obj-$(CONFIG_MMC_ARMMMCI) += armmmci.o
|
||||
armmmci-y := mmci.o
|
||||
armmmci-$(CONFIG_MMC_QCOM_DML) += mmci_qcom_dml.o
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,22 +0,0 @@
|
|||
From a7eb46e0ea4a11e4dfb56ab129bf816d1059a6c5 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 7 Dec 2015 17:31:08 +0100
|
||||
Subject: [PATCH 51/53] serial: add ugly custom baud rate hack
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/tty/serial/serial_core.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/tty/serial/serial_core.c
|
||||
+++ b/drivers/tty/serial/serial_core.c
|
||||
@@ -428,6 +428,9 @@ uart_get_baud_rate(struct uart_port *por
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (tty_termios_baud_rate(termios) == 2500000)
|
||||
+ return 250000;
|
||||
+
|
||||
for (try = 0; try < 2; try++) {
|
||||
baud = tty_termios_baud_rate(termios);
|
||||
|
|
@ -1,217 +0,0 @@
|
|||
From fc8f96309c21c1bc3276427309cd7d361347d66e Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 7 Dec 2015 17:16:50 +0100
|
||||
Subject: [PATCH 52/53] pwm: add mediatek support
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/pwm/Kconfig | 9 +++
|
||||
drivers/pwm/Makefile | 1 +
|
||||
drivers/pwm/pwm-mediatek.c | 173 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 183 insertions(+)
|
||||
create mode 100644 drivers/pwm/pwm-mediatek.c
|
||||
|
||||
--- a/drivers/pwm/Kconfig
|
||||
+++ b/drivers/pwm/Kconfig
|
||||
@@ -302,6 +302,15 @@ config PWM_MEDIATEK
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called pwm-mediatek.
|
||||
|
||||
+config PWM_MEDIATEK_RAMIPS
|
||||
+ tristate "Mediatek PWM support"
|
||||
+ depends on RALINK && OF
|
||||
+ help
|
||||
+ Generic PWM framework driver for Mediatek ARM SoC.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module
|
||||
+ will be called pwm-mxs.
|
||||
+
|
||||
config PWM_MXS
|
||||
tristate "Freescale MXS PWM support"
|
||||
depends on ARCH_MXS && OF
|
||||
--- a/drivers/pwm/Makefile
|
||||
+++ b/drivers/pwm/Makefile
|
||||
@@ -28,6 +28,7 @@ obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-p
|
||||
obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o
|
||||
obj-$(CONFIG_PWM_MESON) += pwm-meson.o
|
||||
obj-$(CONFIG_PWM_MEDIATEK) += pwm-mediatek.o
|
||||
+obj-$(CONFIG_PWM_MEDIATEK_RAMIPS) += pwm-mediatek-ramips.o
|
||||
obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o
|
||||
obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
|
||||
obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/pwm/pwm-mediatek-ramips.c
|
||||
@@ -0,0 +1,173 @@
|
||||
+/*
|
||||
+ * Mediatek Pulse Width Modulator driver
|
||||
+ *
|
||||
+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
|
||||
+ *
|
||||
+ * This file is licensed under the terms of the GNU General Public
|
||||
+ * License version 2. This program is licensed "as is" without any
|
||||
+ * warranty of any kind, whether express or implied.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/ioport.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pwm.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
+#define NUM_PWM 4
|
||||
+
|
||||
+/* PWM registers and bits definitions */
|
||||
+#define PWMCON 0x00
|
||||
+#define PWMHDUR 0x04
|
||||
+#define PWMLDUR 0x08
|
||||
+#define PWMGDUR 0x0c
|
||||
+#define PWMWAVENUM 0x28
|
||||
+#define PWMDWIDTH 0x2c
|
||||
+#define PWMTHRES 0x30
|
||||
+
|
||||
+/**
|
||||
+ * struct mtk_pwm_chip - struct representing pwm chip
|
||||
+ *
|
||||
+ * @mmio_base: base address of pwm chip
|
||||
+ * @chip: linux pwm chip representation
|
||||
+ */
|
||||
+struct mtk_pwm_chip {
|
||||
+ void __iomem *mmio_base;
|
||||
+ struct pwm_chip chip;
|
||||
+};
|
||||
+
|
||||
+static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
|
||||
+{
|
||||
+ return container_of(chip, struct mtk_pwm_chip, chip);
|
||||
+}
|
||||
+
|
||||
+static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
|
||||
+ unsigned long offset)
|
||||
+{
|
||||
+ return ioread32(chip->mmio_base + 0x10 + (num * 0x40) + offset);
|
||||
+}
|
||||
+
|
||||
+static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
|
||||
+ unsigned int num, unsigned long offset,
|
||||
+ unsigned long val)
|
||||
+{
|
||||
+ iowrite32(val, chip->mmio_base + 0x10 + (num * 0x40) + offset);
|
||||
+}
|
||||
+
|
||||
+static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
+ int duty_ns, int period_ns)
|
||||
+{
|
||||
+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
|
||||
+ u32 resolution = 100 / 4;
|
||||
+ u32 clkdiv = 0;
|
||||
+
|
||||
+ while (period_ns / resolution > 8191) {
|
||||
+ clkdiv++;
|
||||
+ resolution *= 2;
|
||||
+ }
|
||||
+
|
||||
+ if (clkdiv > 7)
|
||||
+ return -1;
|
||||
+
|
||||
+ mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | BIT(3) | clkdiv);
|
||||
+ mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution);
|
||||
+ mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
+{
|
||||
+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = ioread32(pc->mmio_base);
|
||||
+ val |= BIT(pwm->hwpwm);
|
||||
+ iowrite32(val, pc->mmio_base);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mtk_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
+{
|
||||
+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = ioread32(pc->mmio_base);
|
||||
+ val &= ~BIT(pwm->hwpwm);
|
||||
+ iowrite32(val, pc->mmio_base);
|
||||
+}
|
||||
+
|
||||
+static const struct pwm_ops mtk_pwm_ops = {
|
||||
+ .config = mtk_pwm_config,
|
||||
+ .enable = mtk_pwm_enable,
|
||||
+ .disable = mtk_pwm_disable,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int mtk_pwm_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mtk_pwm_chip *pc;
|
||||
+ struct resource *r;
|
||||
+ int ret;
|
||||
+
|
||||
+ pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
|
||||
+ if (!pc)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ pc->mmio_base = devm_ioremap_resource(&pdev->dev, r);
|
||||
+ if (IS_ERR(pc->mmio_base))
|
||||
+ return PTR_ERR(pc->mmio_base);
|
||||
+
|
||||
+ platform_set_drvdata(pdev, pc);
|
||||
+
|
||||
+ pc->chip.dev = &pdev->dev;
|
||||
+ pc->chip.ops = &mtk_pwm_ops;
|
||||
+ pc->chip.base = -1;
|
||||
+ pc->chip.npwm = NUM_PWM;
|
||||
+
|
||||
+ ret = pwmchip_add(&pc->chip);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int mtk_pwm_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mtk_pwm_chip *pc = platform_get_drvdata(pdev);
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < NUM_PWM; i++)
|
||||
+ pwm_disable(&pc->chip.pwms[i]);
|
||||
+
|
||||
+ return pwmchip_remove(&pc->chip);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mtk_pwm_of_match[] = {
|
||||
+ { .compatible = "mediatek,mt7628-pwm" },
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
|
||||
+
|
||||
+static struct platform_driver mtk_pwm_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "mtk-pwm",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = mtk_pwm_of_match,
|
||||
+ },
|
||||
+ .probe = mtk_pwm_probe,
|
||||
+ .remove = mtk_pwm_remove,
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(mtk_pwm_driver);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
|
||||
+MODULE_ALIAS("platform:mtk-pwm");
|
|
@ -1,214 +0,0 @@
|
|||
mtd: spi-nor: add support for switching between 3-byte and 4-byte addressing on w25q256 flash
|
||||
|
||||
On some devices the flash chip needs to be in 3-byte addressing mode during
|
||||
reboot, otherwise the boot loader will fail to start.
|
||||
This mode however does not allow regular reads/writes onto the upper 16M
|
||||
half. W25Q256 has separate read commands for reading from >16M, however
|
||||
it does not have any separate write commands.
|
||||
This patch changes the code to leave the chip in 3-byte mode most of the
|
||||
time and only switch during erase/write cycles that go to >16M
|
||||
addresses.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -89,6 +89,10 @@ struct flash_info {
|
||||
#define NO_CHIP_ERASE BIT(12) /* Chip does not support chip erase */
|
||||
#define SPI_NOR_SKIP_SFDP BIT(13) /* Skip parsing of SFDP tables */
|
||||
#define USE_CLSR BIT(14) /* use CLSR command */
|
||||
+#define SPI_NOR_4B_READ_OP BIT(15) /*
|
||||
+ * Like SPI_NOR_4B_OPCODES, but for read
|
||||
+ * op code only.
|
||||
+ */
|
||||
};
|
||||
|
||||
#define JEDEC_MFR(info) ((info)->id[0])
|
||||
@@ -240,6 +244,15 @@ static inline u8 spi_nor_convert_3to4_er
|
||||
ARRAY_SIZE(spi_nor_3to4_erase));
|
||||
}
|
||||
|
||||
+static void spi_nor_set_4byte_read(struct spi_nor *nor,
|
||||
+ const struct flash_info *info)
|
||||
+{
|
||||
+ nor->addr_width = 3;
|
||||
+ nor->ext_addr = 0;
|
||||
+ nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode);
|
||||
+ nor->flags |= SNOR_F_4B_EXT_ADDR;
|
||||
+}
|
||||
+
|
||||
static void spi_nor_set_4byte_opcodes(struct spi_nor *nor,
|
||||
const struct flash_info *info)
|
||||
{
|
||||
@@ -467,6 +480,36 @@ static int spi_nor_erase_sector(struct s
|
||||
return nor->write_reg(nor, nor->erase_opcode, buf, nor->addr_width);
|
||||
}
|
||||
|
||||
+static int spi_nor_check_ext_addr(struct spi_nor *nor, u32 addr)
|
||||
+{
|
||||
+ bool ext_addr;
|
||||
+ int ret;
|
||||
+ u8 cmd;
|
||||
+
|
||||
+ if (!(nor->flags & SNOR_F_4B_EXT_ADDR))
|
||||
+ return 0;
|
||||
+
|
||||
+ ext_addr = !!(addr & 0xff000000);
|
||||
+ if (nor->ext_addr == ext_addr)
|
||||
+ return 0;
|
||||
+
|
||||
+ cmd = ext_addr ? SPINOR_OP_EN4B : SPINOR_OP_EX4B;
|
||||
+ write_enable(nor);
|
||||
+ ret = nor->write_reg(nor, cmd, NULL, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ cmd = 0;
|
||||
+ ret = nor->write_reg(nor, SPINOR_OP_WREAR, &cmd, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ nor->addr_width = 3 + ext_addr;
|
||||
+ nor->ext_addr = ext_addr;
|
||||
+ write_disable(nor);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Erase an address range on the nor chip. The address range may extend
|
||||
* one or more erase sectors. Return an error is there is a problem erasing.
|
||||
@@ -492,6 +535,10 @@ static int spi_nor_erase(struct mtd_info
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ ret = spi_nor_check_ext_addr(nor, addr + len);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
/* whole-chip erase? */
|
||||
if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
|
||||
unsigned long timeout;
|
||||
@@ -542,6 +589,7 @@ static int spi_nor_erase(struct mtd_info
|
||||
write_disable(nor);
|
||||
|
||||
erase_err:
|
||||
+ spi_nor_check_ext_addr(nor, 0);
|
||||
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
|
||||
|
||||
instr->state = ret ? MTD_ERASE_FAILED : MTD_ERASE_DONE;
|
||||
@@ -834,7 +882,9 @@ static int spi_nor_lock(struct mtd_info
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ spi_nor_check_ext_addr(nor, ofs + len);
|
||||
ret = nor->flash_lock(nor, ofs, len);
|
||||
+ spi_nor_check_ext_addr(nor, 0);
|
||||
|
||||
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK);
|
||||
return ret;
|
||||
@@ -849,7 +899,9 @@ static int spi_nor_unlock(struct mtd_inf
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ spi_nor_check_ext_addr(nor, ofs + len);
|
||||
ret = nor->flash_unlock(nor, ofs, len);
|
||||
+ spi_nor_check_ext_addr(nor, 0);
|
||||
|
||||
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
|
||||
return ret;
|
||||
@@ -1182,7 +1234,7 @@ static const struct flash_info spi_nor_i
|
||||
{ "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) },
|
||||
{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) },
|
||||
{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
|
||||
- { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
+ { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_READ_OP) },
|
||||
{ "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024,
|
||||
SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) },
|
||||
|
||||
@@ -1245,6 +1297,9 @@ static int spi_nor_read(struct mtd_info
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ if (nor->flags & SNOR_F_4B_EXT_ADDR)
|
||||
+ nor->addr_width = 4;
|
||||
+
|
||||
while (len) {
|
||||
loff_t addr = from;
|
||||
|
||||
@@ -1269,6 +1324,18 @@ static int spi_nor_read(struct mtd_info
|
||||
ret = 0;
|
||||
|
||||
read_err:
|
||||
+ if (nor->flags & SNOR_F_4B_EXT_ADDR) {
|
||||
+ u8 val = 0;
|
||||
+
|
||||
+ if ((from + len) & 0xff000000) {
|
||||
+ write_enable(nor);
|
||||
+ nor->write_reg(nor, SPINOR_OP_WREAR, &val, 1);
|
||||
+ write_disable(nor);
|
||||
+ }
|
||||
+
|
||||
+ nor->addr_width = 3;
|
||||
+ }
|
||||
+
|
||||
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ);
|
||||
return ret;
|
||||
}
|
||||
@@ -1370,6 +1437,10 @@ static int spi_nor_write(struct mtd_info
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ ret = spi_nor_check_ext_addr(nor, to + len);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
for (i = 0; i < len; ) {
|
||||
ssize_t written;
|
||||
loff_t addr = to + i;
|
||||
@@ -1410,6 +1481,7 @@ static int spi_nor_write(struct mtd_info
|
||||
}
|
||||
|
||||
write_err:
|
||||
+ spi_nor_check_ext_addr(nor, 0);
|
||||
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
|
||||
return ret;
|
||||
}
|
||||
@@ -2826,8 +2898,10 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
} else if (mtd->size > 0x1000000) {
|
||||
/* enable 4-byte addressing if the device exceeds 16MiB */
|
||||
nor->addr_width = 4;
|
||||
- if (JEDEC_MFR(info) == SNOR_MFR_SPANSION ||
|
||||
- info->flags & SPI_NOR_4B_OPCODES)
|
||||
+ if (info->flags & SPI_NOR_4B_READ_OP)
|
||||
+ spi_nor_set_4byte_read(nor, info);
|
||||
+ else if (JEDEC_MFR(info) == SNOR_MFR_SPANSION ||
|
||||
+ info->flags & SPI_NOR_4B_OPCODES)
|
||||
spi_nor_set_4byte_opcodes(nor, info);
|
||||
else
|
||||
set_4byte(nor, info, 1);
|
||||
--- a/include/linux/mtd/spi-nor.h
|
||||
+++ b/include/linux/mtd/spi-nor.h
|
||||
@@ -102,6 +102,7 @@
|
||||
/* Used for Macronix and Winbond flashes. */
|
||||
#define SPINOR_OP_EN4B 0xb7 /* Enter 4-byte mode */
|
||||
#define SPINOR_OP_EX4B 0xe9 /* Exit 4-byte mode */
|
||||
+#define SPINOR_OP_WREAR 0xc5 /* Write extended address register */
|
||||
|
||||
/* Used for Spansion flashes only. */
|
||||
#define SPINOR_OP_BRWR 0x17 /* Bank register write */
|
||||
@@ -229,6 +230,7 @@ enum spi_nor_option_flags {
|
||||
SNOR_F_S3AN_ADDR_DEFAULT = BIT(3),
|
||||
SNOR_F_READY_XSR_RDY = BIT(4),
|
||||
SNOR_F_USE_CLSR = BIT(5),
|
||||
+ SNOR_F_4B_EXT_ADDR = BIT(6),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -280,6 +282,7 @@ struct spi_nor {
|
||||
enum spi_nor_protocol reg_proto;
|
||||
bool sst_write_second;
|
||||
u32 flags;
|
||||
+ u8 ext_addr;
|
||||
u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE];
|
||||
|
||||
int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
|
|
@ -1,73 +0,0 @@
|
|||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -142,20 +142,29 @@ static int read_fsr(struct spi_nor *nor)
|
||||
* location. Return the configuration register value.
|
||||
* Returns negative if error occurred.
|
||||
*/
|
||||
-static int read_cr(struct spi_nor *nor)
|
||||
+static int _read_cr(struct spi_nor *nor, u8 reg)
|
||||
{
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
- ret = nor->read_reg(nor, SPINOR_OP_RDCR, &val, 1);
|
||||
+ ret = nor->read_reg(nor, reg, &val, 1);
|
||||
if (ret < 0) {
|
||||
- dev_err(nor->dev, "error %d reading CR\n", ret);
|
||||
+ dev_err(nor->dev, "error %d reading %s\n", ret,
|
||||
+ (reg==SPINOR_OP_RDCR)?"CR":"XCR");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
+static inline int read_cr(struct spi_nor *nor) {
|
||||
+ return _read_cr(nor, SPINOR_OP_RDCR);
|
||||
+}
|
||||
+
|
||||
+static inline int read_xcr(struct spi_nor *nor) {
|
||||
+ return _read_cr(nor, SPINOR_OP_RDXCR);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Write status register 1 byte
|
||||
* Returns negative if error occurred.
|
||||
@@ -2898,9 +2907,16 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
} else if (mtd->size > 0x1000000) {
|
||||
/* enable 4-byte addressing if the device exceeds 16MiB */
|
||||
nor->addr_width = 4;
|
||||
- if (info->flags & SPI_NOR_4B_READ_OP)
|
||||
- spi_nor_set_4byte_read(nor, info);
|
||||
- else if (JEDEC_MFR(info) == SNOR_MFR_SPANSION ||
|
||||
+ if (info->flags & SPI_NOR_4B_READ_OP) {
|
||||
+ if (JEDEC_MFR(info) == SNOR_MFR_WINBOND) {
|
||||
+ ret = read_xcr(nor);
|
||||
+ if (!(ret > 0 && (ret & XCR_DEF_4B_ADDR_MODE)))
|
||||
+ spi_nor_set_4byte_read(nor, info);
|
||||
+ else
|
||||
+ set_4byte(nor, info, 1);
|
||||
+ } else
|
||||
+ spi_nor_set_4byte_read(nor, info);
|
||||
+ } else if (JEDEC_MFR(info) == SNOR_MFR_SPANSION ||
|
||||
info->flags & SPI_NOR_4B_OPCODES)
|
||||
spi_nor_set_4byte_opcodes(nor, info);
|
||||
else
|
||||
--- a/include/linux/mtd/spi-nor.h
|
||||
+++ b/include/linux/mtd/spi-nor.h
|
||||
@@ -103,6 +103,7 @@
|
||||
#define SPINOR_OP_EN4B 0xb7 /* Enter 4-byte mode */
|
||||
#define SPINOR_OP_EX4B 0xe9 /* Exit 4-byte mode */
|
||||
#define SPINOR_OP_WREAR 0xc5 /* Write extended address register */
|
||||
+#define SPINOR_OP_RDXCR 0x15 /* Read extended configuration register */
|
||||
|
||||
/* Used for Spansion flashes only. */
|
||||
#define SPINOR_OP_BRWR 0x17 /* Bank register write */
|
||||
@@ -135,6 +136,7 @@
|
||||
|
||||
/* Configuration Register bits. */
|
||||
#define CR_QUAD_EN_SPAN BIT(1) /* Spansion Quad I/O */
|
||||
+#define XCR_DEF_4B_ADDR_MODE BIT(1) /* Winbond 4B mode default */
|
||||
|
||||
/* Status Register 2 bits. */
|
||||
#define SR2_QUAD_EN_BIT7 BIT(7)
|
|
@ -1,15 +0,0 @@
|
|||
--- a/drivers/usb/dwc2/platform.c
|
||||
+++ b/drivers/usb/dwc2/platform.c
|
||||
@@ -407,6 +407,12 @@ static int dwc2_driver_probe(struct plat
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
+ /* Enable USB port before any regs access */
|
||||
+ if (dwc2_readl(hsotg->regs + PCGCTL) & 0x0f) {
|
||||
+ dwc2_writel(0x00, hsotg->regs + PCGCTL);
|
||||
+ /* TODO: mdelay(25) here? vendor driver don't use it */
|
||||
+ }
|
||||
+
|
||||
retval = dwc2_get_dr_mode(hsotg);
|
||||
if (retval)
|
||||
goto error;
|
|
@ -1,10 +0,0 @@
|
|||
--- a/arch/mips/ralink/Kconfig
|
||||
+++ b/arch/mips/ralink/Kconfig
|
||||
@@ -58,6 +58,7 @@ choice
|
||||
select COMMON_CLK
|
||||
select CLKSRC_MIPS_GIC
|
||||
select HW_HAS_PCI
|
||||
+ select WEAK_REORDERING_BEYOND_LLSC
|
||||
endchoice
|
||||
|
||||
choice
|
|
@ -1,19 +0,0 @@
|
|||
--- a/arch/mips/kernel/mips-cm.c
|
||||
+++ b/arch/mips/kernel/mips-cm.c
|
||||
@@ -237,6 +237,7 @@ int mips_cm_probe(void)
|
||||
|
||||
/* disable CM regions */
|
||||
write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR);
|
||||
+ /*
|
||||
write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK);
|
||||
write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR);
|
||||
write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK);
|
||||
@@ -244,7 +245,7 @@ int mips_cm_probe(void)
|
||||
write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK);
|
||||
write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR);
|
||||
write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK);
|
||||
-
|
||||
+*/
|
||||
/* probe for an L2-only sync region */
|
||||
mips_cm_probe_l2sync();
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
--- a/arch/mips/pci/pci-mt7620.c
|
||||
+++ b/arch/mips/pci/pci-mt7620.c
|
||||
@@ -33,7 +33,6 @@
|
||||
#define RALINK_GPIOMODE 0x60
|
||||
|
||||
#define PPLL_CFG1 0x9c
|
||||
-#define PDRV_SW_SET BIT(23)
|
||||
|
||||
#define PPLL_DRV 0xa0
|
||||
#define PDRV_SW_SET (1<<31)
|
|
@ -1,97 +0,0 @@
|
|||
--- a/drivers/misc/Makefile
|
||||
+++ b/drivers/misc/Makefile
|
||||
@@ -56,6 +56,7 @@ obj-$(CONFIG_CXL_BASE) += cxl/
|
||||
obj-$(CONFIG_ASPEED_LPC_CTRL) += aspeed-lpc-ctrl.o
|
||||
obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o
|
||||
obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
|
||||
+obj-$(CONFIG_SOC_MT7620) += linkit.o
|
||||
|
||||
lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o
|
||||
lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/misc/linkit.c
|
||||
@@ -0,0 +1,84 @@
|
||||
+/*
|
||||
+ * 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
|
||||
+ * publishhed by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/mtd/mtd.h>
|
||||
+#include <linux/gpio.h>
|
||||
+
|
||||
+#define LINKIT_LATCH_GPIO 11
|
||||
+
|
||||
+struct linkit_hw_data {
|
||||
+ char board[16];
|
||||
+ char rev[16];
|
||||
+};
|
||||
+
|
||||
+static void sanify_string(char *s)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < 15; i++)
|
||||
+ if (s[i] <= 0x20)
|
||||
+ s[i] = '\0';
|
||||
+ s[15] = '\0';
|
||||
+}
|
||||
+
|
||||
+static int linkit_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct linkit_hw_data hw;
|
||||
+ struct mtd_info *mtd;
|
||||
+ size_t retlen;
|
||||
+ int ret;
|
||||
+
|
||||
+ mtd = get_mtd_device_nm("factory");
|
||||
+ if (IS_ERR(mtd))
|
||||
+ return PTR_ERR(mtd);
|
||||
+
|
||||
+ ret = mtd_read(mtd, 0x400, sizeof(hw), &retlen, (u_char *) &hw);
|
||||
+ put_mtd_device(mtd);
|
||||
+
|
||||
+ sanify_string(hw.board);
|
||||
+ sanify_string(hw.rev);
|
||||
+
|
||||
+ dev_info(&pdev->dev, "Version : %s\n", hw.board);
|
||||
+ dev_info(&pdev->dev, "Revision : %s\n", hw.rev);
|
||||
+
|
||||
+ if (!strcmp(hw.board, "LINKITS7688")) {
|
||||
+ dev_info(&pdev->dev, "setting up bootstrap latch\n");
|
||||
+
|
||||
+ if (devm_gpio_request(&pdev->dev, LINKIT_LATCH_GPIO, "bootstrap")) {
|
||||
+ dev_err(&pdev->dev, "failed to setup bootstrap gpio\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ gpio_direction_output(LINKIT_LATCH_GPIO, 0);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id linkit_match[] = {
|
||||
+ { .compatible = "mediatek,linkit" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, linkit_match);
|
||||
+
|
||||
+static struct platform_driver linkit_driver = {
|
||||
+ .probe = linkit_probe,
|
||||
+ .driver = {
|
||||
+ .name = "mtk-linkit",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = linkit_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+int __init linkit_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&linkit_driver);
|
||||
+}
|
||||
+late_initcall_sync(linkit_init);
|
|
@ -1,61 +0,0 @@
|
|||
There is a variant of MT7621 which contains only one CPU core instead of 2.
|
||||
This is not reflected in the config register, so the kernel detects more
|
||||
physical cores, which leads to a hang on SMP bringup.
|
||||
Add a hack to detect missing cores.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/arch/mips/kernel/smp-cps.c
|
||||
+++ b/arch/mips/kernel/smp-cps.c
|
||||
@@ -47,6 +47,11 @@ static unsigned core_vpe_count(unsigned
|
||||
return mips_cps_numvps(cluster, core);
|
||||
}
|
||||
|
||||
+bool __weak plat_cpu_core_present(int core)
|
||||
+{
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
static void __init cps_smp_setup(void)
|
||||
{
|
||||
unsigned int nclusters, ncores, nvpes, core_vpes;
|
||||
@@ -64,6 +69,8 @@ static void __init cps_smp_setup(void)
|
||||
|
||||
ncores = mips_cps_numcores(cl);
|
||||
for (c = 0; c < ncores; c++) {
|
||||
+ if (!plat_cpu_core_present(c))
|
||||
+ continue;
|
||||
core_vpes = core_vpe_count(cl, c);
|
||||
|
||||
if (c > 0)
|
||||
--- a/arch/mips/ralink/mt7621.c
|
||||
+++ b/arch/mips/ralink/mt7621.c
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <asm/mips-cps.h>
|
||||
#include <asm/mach-ralink/ralink_regs.h>
|
||||
#include <asm/mach-ralink/mt7621.h>
|
||||
+#include <asm/mips-boards/launch.h>
|
||||
|
||||
#include <pinmux.h>
|
||||
|
||||
@@ -162,6 +163,20 @@ void __init ralink_of_remap(void)
|
||||
panic("Failed to remap core resources");
|
||||
}
|
||||
|
||||
+bool plat_cpu_core_present(int core)
|
||||
+{
|
||||
+ struct cpulaunch *launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH);
|
||||
+
|
||||
+ if (!core)
|
||||
+ return true;
|
||||
+ launch += core * 2; /* 2 VPEs per core */
|
||||
+ if (!(launch->flags & LAUNCH_FREADY))
|
||||
+ return false;
|
||||
+ if (launch->flags & (LAUNCH_FGO | LAUNCH_FGONE))
|
||||
+ return false;
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
void prom_soc_init(struct ralink_soc_info *soc_info)
|
||||
{
|
||||
void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
|
|
@ -1,87 +0,0 @@
|
|||
--- a/arch/mips/ralink/mt7621.c
|
||||
+++ b/arch/mips/ralink/mt7621.c
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
+#include <linux/jiffies.h>
|
||||
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/smp-ops.h>
|
||||
@@ -16,6 +17,7 @@
|
||||
#include <asm/mach-ralink/ralink_regs.h>
|
||||
#include <asm/mach-ralink/mt7621.h>
|
||||
#include <asm/mips-boards/launch.h>
|
||||
+#include <asm/delay.h>
|
||||
|
||||
#include <pinmux.h>
|
||||
|
||||
@@ -177,6 +179,58 @@ bool plat_cpu_core_present(int core)
|
||||
return true;
|
||||
}
|
||||
|
||||
+#define LPS_PREC 8
|
||||
+/*
|
||||
+* Re-calibration lpj(loop-per-jiffy).
|
||||
+* (derived from kernel/calibrate.c)
|
||||
+*/
|
||||
+static int udelay_recal(void)
|
||||
+{
|
||||
+ unsigned int i, lpj = 0;
|
||||
+ unsigned long ticks, loopbit;
|
||||
+ int lps_precision = LPS_PREC;
|
||||
+
|
||||
+ lpj = (1<<12);
|
||||
+
|
||||
+ while ((lpj <<= 1) != 0) {
|
||||
+ /* wait for "start of" clock tick */
|
||||
+ ticks = jiffies;
|
||||
+ while (ticks == jiffies)
|
||||
+ /* nothing */;
|
||||
+
|
||||
+ /* Go .. */
|
||||
+ ticks = jiffies;
|
||||
+ __delay(lpj);
|
||||
+ ticks = jiffies - ticks;
|
||||
+ if (ticks)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Do a binary approximation to get lpj set to
|
||||
+ * equal one clock (up to lps_precision bits)
|
||||
+ */
|
||||
+ lpj >>= 1;
|
||||
+ loopbit = lpj;
|
||||
+ while (lps_precision-- && (loopbit >>= 1)) {
|
||||
+ lpj |= loopbit;
|
||||
+ ticks = jiffies;
|
||||
+ while (ticks == jiffies)
|
||||
+ /* nothing */;
|
||||
+ ticks = jiffies;
|
||||
+ __delay(lpj);
|
||||
+ if (jiffies != ticks) /* longer than 1 tick */
|
||||
+ lpj &= ~loopbit;
|
||||
+ }
|
||||
+ printk(KERN_INFO "%d CPUs re-calibrate udelay(lpj = %d)\n", NR_CPUS, lpj);
|
||||
+
|
||||
+ for(i=0; i< NR_CPUS; i++)
|
||||
+ cpu_data[i].udelay_val = lpj;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+device_initcall(udelay_recal);
|
||||
+
|
||||
void prom_soc_init(struct ralink_soc_info *soc_info)
|
||||
{
|
||||
void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
|
||||
--- a/arch/mips/ralink/Kconfig
|
||||
+++ b/arch/mips/ralink/Kconfig
|
||||
@@ -59,6 +59,7 @@ choice
|
||||
select CLKSRC_MIPS_GIC
|
||||
select HW_HAS_PCI
|
||||
select WEAK_REORDERING_BEYOND_LLSC
|
||||
+ select GENERIC_CLOCKEVENTS_BROADCAST
|
||||
endchoice
|
||||
|
||||
choice
|
|
@ -1,224 +0,0 @@
|
|||
--- a/arch/mips/include/asm/mach-ralink/mt7621.h
|
||||
+++ b/arch/mips/include/asm/mach-ralink/mt7621.h
|
||||
@@ -19,6 +19,10 @@
|
||||
#define SYSC_REG_CHIP_REV 0x0c
|
||||
#define SYSC_REG_SYSTEM_CONFIG0 0x10
|
||||
#define SYSC_REG_SYSTEM_CONFIG1 0x14
|
||||
+#define SYSC_REG_CLKCFG0 0x2c
|
||||
+#define SYSC_REG_CUR_CLK_STS 0x44
|
||||
+
|
||||
+#define MEMC_REG_CPU_PLL 0x648
|
||||
|
||||
#define CHIP_REV_PKG_MASK 0x1
|
||||
#define CHIP_REV_PKG_SHIFT 16
|
||||
@@ -26,6 +30,22 @@
|
||||
#define CHIP_REV_VER_SHIFT 8
|
||||
#define CHIP_REV_ECO_MASK 0xf
|
||||
|
||||
+#define XTAL_MODE_SEL_MASK 0x7
|
||||
+#define XTAL_MODE_SEL_SHIFT 6
|
||||
+
|
||||
+#define CPU_CLK_SEL_MASK 0x3
|
||||
+#define CPU_CLK_SEL_SHIFT 30
|
||||
+
|
||||
+#define CUR_CPU_FDIV_MASK 0x1f
|
||||
+#define CUR_CPU_FDIV_SHIFT 8
|
||||
+#define CUR_CPU_FFRAC_MASK 0x1f
|
||||
+#define CUR_CPU_FFRAC_SHIFT 0
|
||||
+
|
||||
+#define CPU_PLL_PREDIV_MASK 0x3
|
||||
+#define CPU_PLL_PREDIV_SHIFT 12
|
||||
+#define CPU_PLL_FBDIV_MASK 0x7f
|
||||
+#define CPU_PLL_FBDIV_SHIFT 4
|
||||
+
|
||||
#define MT7621_DRAM_BASE 0x0
|
||||
#define MT7621_DDR2_SIZE_MIN 32
|
||||
#define MT7621_DDR2_SIZE_MAX 256
|
||||
--- a/arch/mips/ralink/mt7621.c
|
||||
+++ b/arch/mips/ralink/mt7621.c
|
||||
@@ -10,6 +10,10 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/jiffies.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/clkdev.h>
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <dt-bindings/clock/mt7621-clk.h>
|
||||
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/smp-ops.h>
|
||||
@@ -18,16 +22,12 @@
|
||||
#include <asm/mach-ralink/mt7621.h>
|
||||
#include <asm/mips-boards/launch.h>
|
||||
#include <asm/delay.h>
|
||||
+#include <asm/time.h>
|
||||
|
||||
#include <pinmux.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
-#define SYSC_REG_SYSCFG 0x10
|
||||
-#define SYSC_REG_CPLL_CLKCFG0 0x2c
|
||||
-#define SYSC_REG_CUR_CLK_STS 0x44
|
||||
-#define CPU_CLK_SEL (BIT(30) | BIT(31))
|
||||
-
|
||||
#define MT7621_GPIO_MODE_UART1 1
|
||||
#define MT7621_GPIO_MODE_I2C 2
|
||||
#define MT7621_GPIO_MODE_UART3_MASK 0x3
|
||||
@@ -113,49 +113,89 @@ static struct rt2880_pmx_group mt7621_pi
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
+static struct clk *clks[MT7621_CLK_MAX];
|
||||
+static struct clk_onecell_data clk_data = {
|
||||
+ .clks = clks,
|
||||
+ .clk_num = ARRAY_SIZE(clks),
|
||||
+};
|
||||
+
|
||||
phys_addr_t mips_cpc_default_phys_base(void)
|
||||
{
|
||||
panic("Cannot detect cpc address");
|
||||
}
|
||||
|
||||
-void __init ralink_clk_init(void)
|
||||
+static struct clk *__init mt7621_add_sys_clkdev(
|
||||
+ const char *id, unsigned long rate)
|
||||
{
|
||||
- int cpu_fdiv = 0;
|
||||
- int cpu_ffrac = 0;
|
||||
- int fbdiv = 0;
|
||||
- u32 clk_sts, syscfg;
|
||||
- u8 clk_sel = 0, xtal_mode;
|
||||
- u32 cpu_clk;
|
||||
+ struct clk *clk;
|
||||
+ int err;
|
||||
+
|
||||
+ clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate);
|
||||
+ if (IS_ERR(clk))
|
||||
+ panic("failed to allocate %s clock structure", id);
|
||||
+
|
||||
+ err = clk_register_clkdev(clk, id, NULL);
|
||||
+ if (err)
|
||||
+ panic("unable to register %s clock device", id);
|
||||
|
||||
- if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0)
|
||||
- clk_sel = 1;
|
||||
+ return clk;
|
||||
+}
|
||||
+
|
||||
+void __init ralink_clk_init(void)
|
||||
+{
|
||||
+ u32 syscfg, xtal_sel, clkcfg, clk_sel, curclk, ffiv, ffrac;
|
||||
+ u32 pll, prediv, fbdiv;
|
||||
+ u32 xtal_clk, cpu_clk, bus_clk;
|
||||
+ const static u32 prediv_tbl[] = {0, 1, 2, 2};
|
||||
+
|
||||
+ syscfg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
|
||||
+ xtal_sel = (syscfg >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK;
|
||||
+
|
||||
+ clkcfg = rt_sysc_r32(SYSC_REG_CLKCFG0);
|
||||
+ clk_sel = (clkcfg >> CPU_CLK_SEL_SHIFT) & CPU_CLK_SEL_MASK;
|
||||
+
|
||||
+ curclk = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
|
||||
+ ffiv = (curclk >> CUR_CPU_FDIV_SHIFT) & CUR_CPU_FDIV_MASK;
|
||||
+ ffrac = (curclk >> CUR_CPU_FFRAC_SHIFT) & CUR_CPU_FFRAC_MASK;
|
||||
+
|
||||
+ if (xtal_sel <= 2)
|
||||
+ xtal_clk = 20 * 1000 * 1000;
|
||||
+ else if (xtal_sel <= 5)
|
||||
+ xtal_clk = 40 * 1000 * 1000;
|
||||
+ else
|
||||
+ xtal_clk = 25 * 1000 * 1000;
|
||||
|
||||
switch (clk_sel) {
|
||||
case 0:
|
||||
- clk_sts = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
|
||||
- cpu_fdiv = ((clk_sts >> 8) & 0x1F);
|
||||
- cpu_ffrac = (clk_sts & 0x1F);
|
||||
- cpu_clk = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000;
|
||||
+ cpu_clk = 500 * 1000 * 1000;
|
||||
break;
|
||||
-
|
||||
case 1:
|
||||
- fbdiv = ((rt_sysc_r32(0x648) >> 4) & 0x7F) + 1;
|
||||
- syscfg = rt_sysc_r32(SYSC_REG_SYSCFG);
|
||||
- xtal_mode = (syscfg >> 6) & 0x7;
|
||||
- if (xtal_mode >= 6) {
|
||||
- /* 25Mhz Xtal */
|
||||
- cpu_clk = 25 * fbdiv * 1000 * 1000;
|
||||
- } else if (xtal_mode >= 3) {
|
||||
- /* 40Mhz Xtal */
|
||||
- cpu_clk = 40 * fbdiv * 1000 * 1000;
|
||||
- } else {
|
||||
- /* 20Mhz Xtal */
|
||||
- cpu_clk = 20 * fbdiv * 1000 * 1000;
|
||||
- }
|
||||
+ pll = rt_memc_r32(MEMC_REG_CPU_PLL);
|
||||
+ fbdiv = (pll >> CPU_PLL_FBDIV_SHIFT) & CPU_PLL_FBDIV_MASK;
|
||||
+ prediv = (pll >> CPU_PLL_PREDIV_SHIFT) & CPU_PLL_PREDIV_MASK;
|
||||
+ cpu_clk = ((fbdiv + 1) * xtal_clk) >> prediv_tbl[prediv];
|
||||
break;
|
||||
+ default:
|
||||
+ cpu_clk = xtal_clk;
|
||||
}
|
||||
+
|
||||
+ cpu_clk = cpu_clk / ffiv * ffrac;
|
||||
+ bus_clk = cpu_clk / 4;
|
||||
+
|
||||
+ clks[MT7621_CLK_CPU] = mt7621_add_sys_clkdev("cpu", cpu_clk);
|
||||
+ clks[MT7621_CLK_BUS] = mt7621_add_sys_clkdev("bus", bus_clk);
|
||||
+
|
||||
+ pr_info("CPU Clock: %dMHz\n", cpu_clk / 1000000);
|
||||
+ mips_hpt_frequency = cpu_clk / 2;
|
||||
}
|
||||
|
||||
+static void __init mt7621_clocks_init_dt(struct device_node *np)
|
||||
+{
|
||||
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
+}
|
||||
+
|
||||
+CLK_OF_DECLARE(ar7100, "mediatek,mt7621-pll", mt7621_clocks_init_dt);
|
||||
+
|
||||
void __init ralink_of_remap(void)
|
||||
{
|
||||
rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc");
|
||||
--- a/arch/mips/ralink/timer-gic.c
|
||||
+++ b/arch/mips/ralink/timer-gic.c
|
||||
@@ -11,14 +11,14 @@
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/clk-provider.h>
|
||||
-#include <linux/clocksource.h>
|
||||
+#include <asm/time.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void __init plat_time_init(void)
|
||||
{
|
||||
ralink_of_remap();
|
||||
-
|
||||
+ ralink_clk_init();
|
||||
of_clk_init(NULL);
|
||||
timer_probe();
|
||||
}
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/clock/mt7621-clk.h
|
||||
@@ -0,0 +1,18 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2018 Weijie Gao <hackpascal@gmail.com>
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef __DT_BINDINGS_MT7621_CLK_H
|
||||
+#define __DT_BINDINGS_MT7621_CLK_H
|
||||
+
|
||||
+#define MT7621_CLK_CPU 0
|
||||
+#define MT7621_CLK_BUS 1
|
||||
+
|
||||
+#define MT7621_CLK_MAX 2
|
||||
+
|
||||
+#endif /* __DT_BINDINGS_MT7621_CLK_H */
|
|
@ -1,125 +0,0 @@
|
|||
From b5a52351a66f3c2a7a207548aa87d78ff2d336c0 Mon Sep 17 00:00:00 2001
|
||||
From: Chuanhong Guo <gch981213@gmail.com>
|
||||
Date: Wed, 10 Jul 2019 00:24:48 +0800
|
||||
Subject: [PATCH] MIPS: ralink: mt7621: add memory detection support
|
||||
|
||||
mt7621 has the following memory map:
|
||||
0x0-0x1c000000: lower 448m memory
|
||||
0x1c000000-0x2000000: peripheral registers
|
||||
0x20000000-0x2400000: higher 64m memory
|
||||
|
||||
detect_memory_region in arch/mips/kernel/setup.c only add the first
|
||||
memory region and isn't suitable for 512m memory detection because
|
||||
it may accidentally read the memory area for peripheral registers.
|
||||
|
||||
This commit adds memory detection capability for mt7621:
|
||||
1. add the highmem area when 512m is detected.
|
||||
2. guard memcmp from accessing peripheral registers:
|
||||
This only happens when some weird user decided to change
|
||||
kernel load address to 256m or higher address. Since this
|
||||
is a quite unusual case, we just skip 512m testing and return
|
||||
256m as memory size.
|
||||
|
||||
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
|
||||
---
|
||||
arch/mips/include/asm/mach-ralink/mt7621.h | 7 ++---
|
||||
arch/mips/ralink/mt7621.c | 30 +++++++++++++++++++---
|
||||
2 files changed, 30 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/arch/mips/include/asm/mach-ralink/mt7621.h
|
||||
+++ b/arch/mips/include/asm/mach-ralink/mt7621.h
|
||||
@@ -46,9 +46,10 @@
|
||||
#define CPU_PLL_FBDIV_MASK 0x7f
|
||||
#define CPU_PLL_FBDIV_SHIFT 4
|
||||
|
||||
-#define MT7621_DRAM_BASE 0x0
|
||||
-#define MT7621_DDR2_SIZE_MIN 32
|
||||
-#define MT7621_DDR2_SIZE_MAX 256
|
||||
+#define MT7621_LOWMEM_BASE 0x0
|
||||
+#define MT7621_LOWMEM_MAX_SIZE 0x1C000000
|
||||
+#define MT7621_HIGHMEM_BASE 0x20000000
|
||||
+#define MT7621_HIGHMEM_SIZE 0x4000000
|
||||
|
||||
#define MT7621_CHIP_NAME0 0x3637544D
|
||||
#define MT7621_CHIP_NAME1 0x20203132
|
||||
--- a/arch/mips/ralink/mt7621.c
|
||||
+++ b/arch/mips/ralink/mt7621.c
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <linux/clk-provider.h>
|
||||
#include <dt-bindings/clock/mt7621-clk.h>
|
||||
|
||||
+#include <asm/bootinfo.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/smp-ops.h>
|
||||
#include <asm/mips-cps.h>
|
||||
@@ -57,6 +58,8 @@
|
||||
#define MT7621_GPIO_MODE_SDHCI_SHIFT 18
|
||||
#define MT7621_GPIO_MODE_SDHCI_GPIO 1
|
||||
|
||||
+static void *detect_magic __initdata = detect_memory_region;
|
||||
+
|
||||
static struct rt2880_pmx_func uart1_grp[] = { FUNC("uart1", 0, 1, 2) };
|
||||
static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 3, 2) };
|
||||
static struct rt2880_pmx_func uart3_grp[] = {
|
||||
@@ -141,6 +144,28 @@ static struct clk *__init mt7621_add_sys
|
||||
return clk;
|
||||
}
|
||||
|
||||
+void __init mt7621_memory_detect(void)
|
||||
+{
|
||||
+ void *dm = &detect_magic;
|
||||
+ phys_addr_t size;
|
||||
+
|
||||
+ for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) {
|
||||
+ if (!memcmp(dm, dm + size, sizeof(detect_magic)))
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if ((size == 256 * SZ_1M) &&
|
||||
+ (CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) &&
|
||||
+ memcmp(dm, dm + size, sizeof(detect_magic))) {
|
||||
+ add_memory_region(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE,
|
||||
+ BOOT_MEM_RAM);
|
||||
+ add_memory_region(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE,
|
||||
+ BOOT_MEM_RAM);
|
||||
+ } else {
|
||||
+ add_memory_region(MT7621_LOWMEM_BASE, size, BOOT_MEM_RAM);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void __init ralink_clk_init(void)
|
||||
{
|
||||
u32 syscfg, xtal_sel, clkcfg, clk_sel, curclk, ffiv, ffrac;
|
||||
@@ -319,10 +344,7 @@ void prom_soc_init(struct ralink_soc_inf
|
||||
(rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
|
||||
(rev & CHIP_REV_ECO_MASK));
|
||||
|
||||
- soc_info->mem_size_min = MT7621_DDR2_SIZE_MIN;
|
||||
- soc_info->mem_size_max = MT7621_DDR2_SIZE_MAX;
|
||||
- soc_info->mem_base = MT7621_DRAM_BASE;
|
||||
-
|
||||
+ soc_info->mem_detect = mt7621_memory_detect;
|
||||
rt2880_pinmux_data = mt7621_pinmux_data;
|
||||
|
||||
|
||||
--- a/arch/mips/ralink/common.h
|
||||
+++ b/arch/mips/ralink/common.h
|
||||
@@ -19,6 +19,7 @@ struct ralink_soc_info {
|
||||
unsigned long mem_size;
|
||||
unsigned long mem_size_min;
|
||||
unsigned long mem_size_max;
|
||||
+ void (*mem_detect)(void);
|
||||
};
|
||||
extern struct ralink_soc_info soc_info;
|
||||
|
||||
--- a/arch/mips/ralink/of.c
|
||||
+++ b/arch/mips/ralink/of.c
|
||||
@@ -89,6 +89,8 @@ void __init plat_mem_setup(void)
|
||||
of_scan_flat_dt(early_init_dt_find_memory, NULL);
|
||||
if (memory_dtb)
|
||||
of_scan_flat_dt(early_init_dt_scan_memory, NULL);
|
||||
+ else if (soc_info.mem_detect)
|
||||
+ soc_info.mem_detect();
|
||||
else if (soc_info.mem_size)
|
||||
add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M,
|
||||
BOOT_MEM_RAM);
|
|
@ -1,15 +0,0 @@
|
|||
--- a/arch/mips/ralink/irq-gic.c
|
||||
+++ b/arch/mips/ralink/irq-gic.c
|
||||
@@ -15,6 +15,12 @@
|
||||
|
||||
int get_c0_perfcount_int(void)
|
||||
{
|
||||
+ /*
|
||||
+ * Performance counter events are routed through GIC.
|
||||
+ * Prevent them from firing on CPU IRQ7 as well
|
||||
+ */
|
||||
+ clear_c0_status(IE_SW0 << 7);
|
||||
+
|
||||
return gic_get_c0_perfcount_int();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
|
|
@ -1,20 +0,0 @@
|
|||
--- a/drivers/net/ethernet/Kconfig
|
||||
+++ b/drivers/net/ethernet/Kconfig
|
||||
@@ -159,6 +159,7 @@ source "drivers/net/ethernet/packetengin
|
||||
source "drivers/net/ethernet/pasemi/Kconfig"
|
||||
source "drivers/net/ethernet/qlogic/Kconfig"
|
||||
source "drivers/net/ethernet/qualcomm/Kconfig"
|
||||
+source "drivers/net/ethernet/ralink/Kconfig"
|
||||
source "drivers/net/ethernet/realtek/Kconfig"
|
||||
source "drivers/net/ethernet/renesas/Kconfig"
|
||||
source "drivers/net/ethernet/rdc/Kconfig"
|
||||
--- a/drivers/net/ethernet/Makefile
|
||||
+++ b/drivers/net/ethernet/Makefile
|
||||
@@ -70,6 +70,7 @@ obj-$(CONFIG_NET_PACKET_ENGINE) += packe
|
||||
obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/
|
||||
obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/
|
||||
obj-$(CONFIG_NET_VENDOR_QUALCOMM) += qualcomm/
|
||||
+obj-$(CONFIG_NET_VENDOR_RALINK) += ralink/
|
||||
obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/
|
||||
obj-$(CONFIG_NET_VENDOR_RENESAS) += renesas/
|
||||
obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
|
|
@ -1,19 +0,0 @@
|
|||
--- a/arch/mips/include/asm/mach-ralink/mt7620.h
|
||||
+++ b/arch/mips/include/asm/mach-ralink/mt7620.h
|
||||
@@ -137,4 +137,16 @@ static inline int mt7620_get_eco(void)
|
||||
return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK;
|
||||
}
|
||||
|
||||
+static inline int mt7620_get_chipver(void)
|
||||
+{
|
||||
+ return (rt_sysc_r32(SYSC_REG_CHIP_REV) >> CHIP_REV_VER_SHIFT) &
|
||||
+ CHIP_REV_VER_MASK;
|
||||
+}
|
||||
+
|
||||
+static inline int mt7620_get_pkg(void)
|
||||
+{
|
||||
+ return (rt_sysc_r32(SYSC_REG_CHIP_REV) >> CHIP_REV_PKG_SHIFT) &
|
||||
+ CHIP_REV_PKG_MASK;
|
||||
+}
|
||||
+
|
||||
#endif
|
|
@ -1,14 +0,0 @@
|
|||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -1066,6 +1066,11 @@ static const struct flash_info spi_nor_i
|
||||
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
|
||||
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
|
||||
},
|
||||
+ {
|
||||
+ "gd25q512", INFO(0xc84020, 0, 64 * 1024, 1024,
|
||||
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
|
||||
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4B_OPCODES)
|
||||
+ },
|
||||
|
||||
/* Intel/Numonyx -- xxxs33b */
|
||||
{ "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) },
|
|
@ -1,72 +0,0 @@
|
|||
This hack can be dropped after the next stable release from
|
||||
v5.x-tree.
|
||||
|
||||
The problem was fixed upstream by
|
||||
|
||||
commit 2bffa65da43e ("mtd: spi-nor: Add a post BFPT fixup for MX25L25635E")
|
||||
|
||||
For reference see:
|
||||
<https://github.com/openwrt/openwrt/pull/1743>
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -1103,6 +1103,7 @@ static const struct flash_info spi_nor_i
|
||||
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
|
||||
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
|
||||
{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
+ { "mx25l25635f", INFO(0xc22019, 0, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
|
||||
{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_OPCODES) },
|
||||
{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
|
||||
{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
|
||||
@@ -1275,11 +1276,12 @@ static const struct flash_info spi_nor_i
|
||||
{ },
|
||||
};
|
||||
|
||||
-static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
|
||||
+static const struct flash_info *spi_nor_read_id(struct spi_nor *nor,
|
||||
+ const char *name)
|
||||
{
|
||||
int tmp;
|
||||
u8 id[SPI_NOR_MAX_ID_LEN];
|
||||
- const struct flash_info *info;
|
||||
+ const struct flash_info *info, *first_match = NULL;
|
||||
|
||||
tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
|
||||
if (tmp < 0) {
|
||||
@@ -1290,10 +1292,16 @@ static const struct flash_info *spi_nor_
|
||||
for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
|
||||
info = &spi_nor_ids[tmp];
|
||||
if (info->id_len) {
|
||||
- if (!memcmp(info->id, id, info->id_len))
|
||||
- return &spi_nor_ids[tmp];
|
||||
+ if (!memcmp(info->id, id, info->id_len)) {
|
||||
+ if (!name || !strcmp(name, info->name))
|
||||
+ return info;
|
||||
+ if (!first_match)
|
||||
+ first_match = info;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
+ if (first_match)
|
||||
+ return first_match;
|
||||
dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n",
|
||||
id[0], id[1], id[2]);
|
||||
return ERR_PTR(-ENODEV);
|
||||
@@ -2773,7 +2781,7 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
info = spi_nor_match_id(name);
|
||||
/* Try to auto-detect if chip name wasn't specified or not found */
|
||||
if (!info)
|
||||
- info = spi_nor_read_id(nor);
|
||||
+ info = spi_nor_read_id(nor, NULL);
|
||||
if (IS_ERR_OR_NULL(info))
|
||||
return -ENOENT;
|
||||
|
||||
@@ -2784,7 +2792,7 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
if (name && info->id_len) {
|
||||
const struct flash_info *jinfo;
|
||||
|
||||
- jinfo = spi_nor_read_id(nor);
|
||||
+ jinfo = spi_nor_read_id(nor, name);
|
||||
if (IS_ERR(jinfo)) {
|
||||
return PTR_ERR(jinfo);
|
||||
} else if (jinfo != info) {
|
|
@ -1,21 +0,0 @@
|
|||
--- a/arch/mips/pci/pci-mt7620.c
|
||||
+++ b/arch/mips/pci/pci-mt7620.c
|
||||
@@ -35,6 +35,7 @@
|
||||
#define PPLL_CFG1 0x9c
|
||||
|
||||
#define PPLL_DRV 0xa0
|
||||
+#define PPLL_LD (1<<23)
|
||||
#define PDRV_SW_SET (1<<31)
|
||||
#define LC_CKDRVPD (1<<19)
|
||||
#define LC_CKDRVOHZ (1<<18)
|
||||
@@ -242,8 +243,8 @@ static int mt7620_pci_hw_init(struct pla
|
||||
rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
|
||||
mdelay(100);
|
||||
|
||||
- if (!(rt_sysc_r32(PPLL_CFG1) & PDRV_SW_SET)) {
|
||||
- dev_err(&pdev->dev, "MT7620 PPLL unlock\n");
|
||||
+ if (!(rt_sysc_r32(PPLL_CFG1) & PPLL_LD)) {
|
||||
+ dev_err(&pdev->dev, "MT7620 PPLL is unlocked, aborting init\n");
|
||||
reset_control_assert(rstpcie0);
|
||||
rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
|
||||
return -1;
|
|
@ -1,220 +0,0 @@
|
|||
CONFIG_ARCH_BINFMT_ELF_STATE=y
|
||||
CONFIG_ARCH_CLOCKSOURCE_DATA=y
|
||||
CONFIG_ARCH_DISCARD_MEMBLOCK=y
|
||||
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
|
||||
# CONFIG_ARCH_HAS_GCOV_PROFILE_ALL is not set
|
||||
CONFIG_ARCH_HAS_RESET_CONTROLLER=y
|
||||
# CONFIG_ARCH_HAS_SG_CHAIN is not set
|
||||
# CONFIG_ARCH_HAS_STRICT_KERNEL_RWX is not set
|
||||
# CONFIG_ARCH_HAS_STRICT_MODULE_RWX is not set
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MAX=15
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
|
||||
# CONFIG_ARCH_OPTIONAL_KERNEL_RWX is not set
|
||||
# CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT is not set
|
||||
CONFIG_ARCH_SUPPORTS_UPROBES=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
|
||||
CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
|
||||
CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
|
||||
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
|
||||
CONFIG_BLK_MQ_PCI=y
|
||||
CONFIG_CEVT_R4K=y
|
||||
# CONFIG_CEVT_SYSTICK_QUIRK is not set
|
||||
CONFIG_CLKDEV_LOOKUP=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
|
||||
CONFIG_CMDLINE_BOOL=y
|
||||
# CONFIG_CMDLINE_OVERRIDE is not set
|
||||
CONFIG_CPU_GENERIC_DUMP_TLB=y
|
||||
CONFIG_CPU_HAS_PREFETCH=y
|
||||
CONFIG_CPU_HAS_RIXI=y
|
||||
CONFIG_CPU_HAS_SYNC=y
|
||||
CONFIG_CPU_LITTLE_ENDIAN=y
|
||||
CONFIG_CPU_MIPS32=y
|
||||
# CONFIG_CPU_MIPS32_R1 is not set
|
||||
CONFIG_CPU_MIPS32_R2=y
|
||||
CONFIG_CPU_MIPSR2=y
|
||||
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
|
||||
CONFIG_CPU_R4K_CACHE_TLB=y
|
||||
CONFIG_CPU_R4K_FPU=y
|
||||
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
|
||||
CONFIG_CPU_SUPPORTS_HIGHMEM=y
|
||||
CONFIG_CPU_SUPPORTS_MSA=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_WORKQUEUE=y
|
||||
CONFIG_CSRC_R4K=y
|
||||
CONFIG_DMA_NONCOHERENT=y
|
||||
# CONFIG_DTB_RT2880_EVAL is not set
|
||||
CONFIG_DTB_RT_NONE=y
|
||||
CONFIG_DTC=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_GENERIC_ATOMIC64=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||
CONFIG_GENERIC_CPU_AUTOPROBE=y
|
||||
CONFIG_GENERIC_IO=y
|
||||
CONFIG_GENERIC_IRQ_CHIP=y
|
||||
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_SCHED_CLOCK=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_RALINK=y
|
||||
# CONFIG_GRO_CELLS is not set
|
||||
CONFIG_HANDLE_DOMAIN_IRQ=y
|
||||
CONFIG_HARDWARE_WATCHPOINTS=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
|
||||
# CONFIG_HAVE_ARCH_BITREVERSE is not set
|
||||
CONFIG_HAVE_ARCH_JUMP_LABEL=y
|
||||
CONFIG_HAVE_ARCH_KGDB=y
|
||||
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
|
||||
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
|
||||
CONFIG_HAVE_CBPF_JIT=y
|
||||
CONFIG_HAVE_CC_STACKPROTECTOR=y
|
||||
CONFIG_HAVE_CLK=y
|
||||
CONFIG_HAVE_CONTEXT_TRACKING=y
|
||||
CONFIG_HAVE_COPY_THREAD_TLS=y
|
||||
CONFIG_HAVE_C_RECORDMCOUNT=y
|
||||
CONFIG_HAVE_DEBUG_KMEMLEAK=y
|
||||
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
|
||||
CONFIG_HAVE_DMA_API_DEBUG=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_IDE=y
|
||||
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
|
||||
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
|
||||
CONFIG_HAVE_KVM=y
|
||||
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
|
||||
CONFIG_HAVE_MEMBLOCK=y
|
||||
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
|
||||
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
|
||||
CONFIG_HAVE_NET_DSA=y
|
||||
CONFIG_HAVE_OPROFILE=y
|
||||
CONFIG_HAVE_PERF_EVENTS=y
|
||||
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
|
||||
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
|
||||
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
|
||||
CONFIG_HW_HAS_PCI=y
|
||||
CONFIG_HZ_PERIODIC=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_IP17XX_PHY=y
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_INTC=y
|
||||
CONFIG_IRQ_MIPS_CPU=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_MIPS_ASID_BITS=8
|
||||
CONFIG_MIPS_ASID_SHIFT=0
|
||||
CONFIG_MIPS_CLOCK_VSYSCALL=y
|
||||
# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
|
||||
# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
|
||||
# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
|
||||
CONFIG_MIPS_CMDLINE_FROM_DTB=y
|
||||
# CONFIG_MIPS_ELF_APPENDED_DTB is not set
|
||||
# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set
|
||||
CONFIG_MIPS_L1_CACHE_SHIFT=4
|
||||
CONFIG_MIPS_L1_CACHE_SHIFT_4=y
|
||||
# CONFIG_MIPS_MACHINE is not set
|
||||
# CONFIG_MIPS_NO_APPENDED_DTB is not set
|
||||
CONFIG_MIPS_RAW_APPENDED_DTB=y
|
||||
CONFIG_MIPS_SPRAM=y
|
||||
CONFIG_MODULES_USE_ELF_REL=y
|
||||
# CONFIG_MTD_CFI_INTELEXT is not set
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
CONFIG_MTD_M25P80=y
|
||||
CONFIG_MTD_PHYSMAP=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_MTD_SPLIT_LZMA_FW=y
|
||||
CONFIG_MTD_SPLIT_UIMAGE_FW=y
|
||||
CONFIG_MTD_SPLIT_WRGG_FW=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_PER_CPU_KM=y
|
||||
CONFIG_NET_RALINK_MDIO=y
|
||||
CONFIG_NET_RALINK_MDIO_RT2880=y
|
||||
CONFIG_NET_RALINK_RT2880=y
|
||||
CONFIG_NET_RALINK_SOC=y
|
||||
CONFIG_NET_VENDOR_RALINK=y
|
||||
CONFIG_NLS=m
|
||||
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
|
||||
# CONFIG_NO_IOPORT_MAP is not set
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_ADDRESS_PCI=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OF_NET=y
|
||||
CONFIG_OF_PCI=y
|
||||
CONFIG_OF_PCI_IRQ=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_DRIVERS_LEGACY=y
|
||||
CONFIG_PERF_USE_VMALLOC=y
|
||||
CONFIG_PGTABLE_LEVELS=2
|
||||
CONFIG_PHYLIB=y
|
||||
# CONFIG_PHY_RALINK_USB is not set
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_RT2880=y
|
||||
# CONFIG_PINCTRL_SINGLE is not set
|
||||
CONFIG_RALINK=y
|
||||
CONFIG_RALINK_WDT=y
|
||||
# CONFIG_RCU_NEED_SEGCBLIST is not set
|
||||
# CONFIG_RCU_STALL_COMMON is not set
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
# CONFIG_SCHED_INFO is not set
|
||||
# CONFIG_SCSI_DMA is not set
|
||||
# CONFIG_SERIAL_8250_FSL is not set
|
||||
CONFIG_SERIAL_8250_RT288X=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
# CONFIG_SOC_MT7620 is not set
|
||||
# CONFIG_SOC_MT7621 is not set
|
||||
CONFIG_SOC_RT288X=y
|
||||
# CONFIG_SOC_RT305X is not set
|
||||
# CONFIG_SOC_RT3883 is not set
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_MASTER=y
|
||||
# CONFIG_SPI_MT7621 is not set
|
||||
CONFIG_SPI_RT2880=y
|
||||
CONFIG_SRCU=y
|
||||
CONFIG_SWCONFIG=y
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
|
||||
CONFIG_SYS_HAS_CPU_MIPS32_R2=y
|
||||
CONFIG_SYS_HAS_EARLY_PRINTK=y
|
||||
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
|
||||
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
|
||||
CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
|
||||
CONFIG_SYS_SUPPORTS_MIPS16=y
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TINY_SRCU=y
|
||||
CONFIG_USB=m
|
||||
CONFIG_USB_COMMON=m
|
||||
CONFIG_USB_EHCI_HCD=m
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=m
|
||||
CONFIG_USB_OHCI_HCD=m
|
||||
CONFIG_USB_OHCI_HCD_PLATFORM=m
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_USE_OF=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
|
@ -1,195 +0,0 @@
|
|||
CONFIG_ARCH_BINFMT_ELF_STATE=y
|
||||
CONFIG_ARCH_CLOCKSOURCE_DATA=y
|
||||
CONFIG_ARCH_DISCARD_MEMBLOCK=y
|
||||
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
|
||||
# CONFIG_ARCH_HAS_GCOV_PROFILE_ALL is not set
|
||||
CONFIG_ARCH_HAS_RESET_CONTROLLER=y
|
||||
# CONFIG_ARCH_HAS_SG_CHAIN is not set
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
|
||||
CONFIG_ARCH_SUPPORTS_UPROBES=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
|
||||
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
|
||||
CONFIG_CEVT_R4K=y
|
||||
CONFIG_CEVT_SYSTICK_QUIRK=y
|
||||
CONFIG_CLKDEV_LOOKUP=y
|
||||
CONFIG_CLKEVT_RT3352=y
|
||||
CONFIG_CLKSRC_MMIO=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
|
||||
CONFIG_CMDLINE_BOOL=y
|
||||
# CONFIG_CMDLINE_OVERRIDE is not set
|
||||
CONFIG_CPU_GENERIC_DUMP_TLB=y
|
||||
CONFIG_CPU_HAS_PREFETCH=y
|
||||
CONFIG_CPU_HAS_RIXI=y
|
||||
CONFIG_CPU_HAS_SYNC=y
|
||||
CONFIG_CPU_LITTLE_ENDIAN=y
|
||||
CONFIG_CPU_MIPS32=y
|
||||
# CONFIG_CPU_MIPS32_R1 is not set
|
||||
CONFIG_CPU_MIPS32_R2=y
|
||||
CONFIG_CPU_MIPSR2=y
|
||||
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
|
||||
CONFIG_CPU_R4K_CACHE_TLB=y
|
||||
CONFIG_CPU_R4K_FPU=y
|
||||
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
|
||||
CONFIG_CPU_SUPPORTS_HIGHMEM=y
|
||||
CONFIG_CPU_SUPPORTS_MSA=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_WORKQUEUE=y
|
||||
CONFIG_CSRC_R4K=y
|
||||
CONFIG_DEBUG_PINCTRL=y
|
||||
CONFIG_DMA_NONCOHERENT=y
|
||||
# CONFIG_DTB_RT305X_EVAL is not set
|
||||
CONFIG_DTB_RT_NONE=y
|
||||
CONFIG_DTC=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_GENERIC_ATOMIC64=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||
CONFIG_GENERIC_IO=y
|
||||
CONFIG_GENERIC_IRQ_CHIP=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_PHY=y
|
||||
CONFIG_GENERIC_SCHED_CLOCK=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_RALINK=y
|
||||
CONFIG_HANDLE_DOMAIN_IRQ=y
|
||||
CONFIG_HARDWARE_WATCHPOINTS=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
|
||||
# CONFIG_HAVE_ARCH_BITREVERSE is not set
|
||||
CONFIG_HAVE_ARCH_JUMP_LABEL=y
|
||||
CONFIG_HAVE_ARCH_KGDB=y
|
||||
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
|
||||
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
|
||||
CONFIG_HAVE_CBPF_JIT=y
|
||||
CONFIG_HAVE_CC_STACKPROTECTOR=y
|
||||
CONFIG_HAVE_CLK=y
|
||||
CONFIG_HAVE_CONTEXT_TRACKING=y
|
||||
CONFIG_HAVE_C_RECORDMCOUNT=y
|
||||
CONFIG_HAVE_DEBUG_KMEMLEAK=y
|
||||
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
|
||||
CONFIG_HAVE_DMA_API_DEBUG=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_IDE=y
|
||||
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
|
||||
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
|
||||
CONFIG_HAVE_KVM=y
|
||||
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
|
||||
CONFIG_HAVE_MEMBLOCK=y
|
||||
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
|
||||
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
|
||||
CONFIG_HAVE_NET_DSA=y
|
||||
CONFIG_HAVE_OPROFILE=y
|
||||
CONFIG_HAVE_PERF_EVENTS=y
|
||||
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
|
||||
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
|
||||
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
|
||||
CONFIG_HZ_PERIODIC=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_INTC=y
|
||||
CONFIG_IRQ_MIPS_CPU=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_MDIO_BOARDINFO=y
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_MIPS_ASID_BITS=8
|
||||
CONFIG_MIPS_ASID_SHIFT=0
|
||||
CONFIG_MIPS_CLOCK_VSYSCALL=y
|
||||
# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
|
||||
# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
|
||||
# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
|
||||
CONFIG_MIPS_CMDLINE_FROM_DTB=y
|
||||
# CONFIG_MIPS_ELF_APPENDED_DTB is not set
|
||||
# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set
|
||||
CONFIG_MIPS_L1_CACHE_SHIFT=5
|
||||
# CONFIG_MIPS_MACHINE is not set
|
||||
# CONFIG_MIPS_NO_APPENDED_DTB is not set
|
||||
CONFIG_MIPS_RAW_APPENDED_DTB=y
|
||||
CONFIG_MIPS_SPRAM=y
|
||||
CONFIG_MODULES_USE_ELF_REL=y
|
||||
# CONFIG_MTD_CFI_INTELEXT is not set
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
CONFIG_MTD_M25P80=y
|
||||
CONFIG_MTD_PHYSMAP=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
|
||||
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384
|
||||
CONFIG_MTD_SPLIT_JIMAGE_FW=y
|
||||
CONFIG_MTD_SPLIT_SEAMA_FW=y
|
||||
CONFIG_MTD_SPLIT_UIMAGE_FW=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_PER_CPU_KM=y
|
||||
CONFIG_NET_RALINK_ESW_RT3050=y
|
||||
CONFIG_NET_RALINK_RT3050=y
|
||||
CONFIG_NET_RALINK_SOC=y
|
||||
CONFIG_NET_VENDOR_RALINK=y
|
||||
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
|
||||
# CONFIG_NO_IOPORT_MAP is not set
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OF_NET=y
|
||||
CONFIG_PCI_DRIVERS_LEGACY=y
|
||||
CONFIG_PERF_USE_VMALLOC=y
|
||||
CONFIG_PGTABLE_LEVELS=2
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHY_RALINK_USB=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_RT2880=y
|
||||
# CONFIG_PINCTRL_SINGLE is not set
|
||||
CONFIG_RALINK=y
|
||||
# CONFIG_RALINK_ILL_ACC is not set
|
||||
CONFIG_RALINK_WDT=y
|
||||
# CONFIG_RCU_STALL_COMMON is not set
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
# CONFIG_SCHED_INFO is not set
|
||||
# CONFIG_SCSI_DMA is not set
|
||||
# CONFIG_SERIAL_8250_FSL is not set
|
||||
CONFIG_SERIAL_8250_RT288X=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
# CONFIG_SOC_MT7620 is not set
|
||||
# CONFIG_SOC_MT7621 is not set
|
||||
# CONFIG_SOC_RT288X is not set
|
||||
CONFIG_SOC_RT305X=y
|
||||
# CONFIG_SOC_RT3883 is not set
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_MASTER=y
|
||||
# CONFIG_SPI_MT7621 is not set
|
||||
CONFIG_SPI_RT2880=y
|
||||
CONFIG_SRCU=y
|
||||
CONFIG_SWCONFIG=y
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
|
||||
CONFIG_SYS_HAS_CPU_MIPS32_R2=y
|
||||
CONFIG_SYS_HAS_EARLY_PRINTK=y
|
||||
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
|
||||
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
|
||||
CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
|
||||
CONFIG_SYS_SUPPORTS_MIPS16=y
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_USE_OF=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
|
@ -1,222 +0,0 @@
|
|||
CONFIG_AR8216_PHY=y
|
||||
CONFIG_ARCH_BINFMT_ELF_STATE=y
|
||||
CONFIG_ARCH_CLOCKSOURCE_DATA=y
|
||||
CONFIG_ARCH_DISCARD_MEMBLOCK=y
|
||||
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
|
||||
# CONFIG_ARCH_HAS_GCOV_PROFILE_ALL is not set
|
||||
CONFIG_ARCH_HAS_RESET_CONTROLLER=y
|
||||
# CONFIG_ARCH_HAS_SG_CHAIN is not set
|
||||
# CONFIG_ARCH_HAS_STRICT_KERNEL_RWX is not set
|
||||
# CONFIG_ARCH_HAS_STRICT_MODULE_RWX is not set
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MAX=15
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
|
||||
# CONFIG_ARCH_OPTIONAL_KERNEL_RWX is not set
|
||||
# CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT is not set
|
||||
CONFIG_ARCH_SUPPORTS_UPROBES=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
|
||||
CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
|
||||
CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
|
||||
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
|
||||
CONFIG_BLK_MQ_PCI=y
|
||||
CONFIG_CEVT_R4K=y
|
||||
# CONFIG_CEVT_SYSTICK_QUIRK is not set
|
||||
CONFIG_CLKDEV_LOOKUP=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
|
||||
CONFIG_CMDLINE_BOOL=y
|
||||
# CONFIG_CMDLINE_OVERRIDE is not set
|
||||
CONFIG_CPU_GENERIC_DUMP_TLB=y
|
||||
CONFIG_CPU_HAS_PREFETCH=y
|
||||
CONFIG_CPU_HAS_RIXI=y
|
||||
CONFIG_CPU_HAS_SYNC=y
|
||||
CONFIG_CPU_LITTLE_ENDIAN=y
|
||||
CONFIG_CPU_MIPS32=y
|
||||
# CONFIG_CPU_MIPS32_R1 is not set
|
||||
CONFIG_CPU_MIPS32_R2=y
|
||||
CONFIG_CPU_MIPSR2=y
|
||||
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
|
||||
CONFIG_CPU_R4K_CACHE_TLB=y
|
||||
CONFIG_CPU_R4K_FPU=y
|
||||
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
|
||||
CONFIG_CPU_SUPPORTS_HIGHMEM=y
|
||||
CONFIG_CPU_SUPPORTS_MSA=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_WORKQUEUE=y
|
||||
CONFIG_CSRC_R4K=y
|
||||
CONFIG_DEBUG_PINCTRL=y
|
||||
CONFIG_DMA_NONCOHERENT=y
|
||||
# CONFIG_DTB_RT3883_EVAL is not set
|
||||
CONFIG_DTB_RT_NONE=y
|
||||
CONFIG_DTC=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_ETHERNET_PACKET_MANGLE=y
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_GENERIC_ATOMIC64=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||
CONFIG_GENERIC_CPU_AUTOPROBE=y
|
||||
CONFIG_GENERIC_IO=y
|
||||
CONFIG_GENERIC_IRQ_CHIP=y
|
||||
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_PHY=y
|
||||
CONFIG_GENERIC_SCHED_CLOCK=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_RALINK=y
|
||||
# CONFIG_GRO_CELLS is not set
|
||||
CONFIG_HANDLE_DOMAIN_IRQ=y
|
||||
CONFIG_HARDWARE_WATCHPOINTS=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
|
||||
# CONFIG_HAVE_ARCH_BITREVERSE is not set
|
||||
CONFIG_HAVE_ARCH_JUMP_LABEL=y
|
||||
CONFIG_HAVE_ARCH_KGDB=y
|
||||
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
|
||||
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
|
||||
CONFIG_HAVE_CBPF_JIT=y
|
||||
CONFIG_HAVE_CC_STACKPROTECTOR=y
|
||||
CONFIG_HAVE_CLK=y
|
||||
CONFIG_HAVE_CONTEXT_TRACKING=y
|
||||
CONFIG_HAVE_COPY_THREAD_TLS=y
|
||||
CONFIG_HAVE_C_RECORDMCOUNT=y
|
||||
CONFIG_HAVE_DEBUG_KMEMLEAK=y
|
||||
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
|
||||
CONFIG_HAVE_DMA_API_DEBUG=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_IDE=y
|
||||
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
|
||||
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
|
||||
CONFIG_HAVE_KVM=y
|
||||
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
|
||||
CONFIG_HAVE_MEMBLOCK=y
|
||||
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
|
||||
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
|
||||
CONFIG_HAVE_NET_DSA=y
|
||||
CONFIG_HAVE_OPROFILE=y
|
||||
CONFIG_HAVE_PERF_EVENTS=y
|
||||
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
|
||||
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
|
||||
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
|
||||
CONFIG_HW_HAS_PCI=y
|
||||
CONFIG_HZ_PERIODIC=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_INTC=y
|
||||
CONFIG_IRQ_MIPS_CPU=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MFD_SYSCON=y
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_MIPS_ASID_BITS=8
|
||||
CONFIG_MIPS_ASID_SHIFT=0
|
||||
CONFIG_MIPS_CLOCK_VSYSCALL=y
|
||||
# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
|
||||
# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
|
||||
# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
|
||||
CONFIG_MIPS_CMDLINE_FROM_DTB=y
|
||||
# CONFIG_MIPS_ELF_APPENDED_DTB is not set
|
||||
# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set
|
||||
CONFIG_MIPS_L1_CACHE_SHIFT=5
|
||||
# CONFIG_MIPS_MACHINE is not set
|
||||
# CONFIG_MIPS_NO_APPENDED_DTB is not set
|
||||
CONFIG_MIPS_RAW_APPENDED_DTB=y
|
||||
CONFIG_MIPS_SPRAM=y
|
||||
CONFIG_MODULES_USE_ELF_REL=y
|
||||
# CONFIG_MTD_CFI_INTELEXT is not set
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
CONFIG_MTD_M25P80=y
|
||||
CONFIG_MTD_PHYSMAP=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
|
||||
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384
|
||||
CONFIG_MTD_SPLIT_SEAMA_FW=y
|
||||
CONFIG_MTD_SPLIT_UIMAGE_FW=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_PER_CPU_KM=y
|
||||
CONFIG_NET_RALINK_MDIO=y
|
||||
CONFIG_NET_RALINK_MDIO_RT2880=y
|
||||
CONFIG_NET_RALINK_RT3883=y
|
||||
CONFIG_NET_RALINK_SOC=y
|
||||
CONFIG_NET_VENDOR_RALINK=y
|
||||
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
|
||||
# CONFIG_NO_IOPORT_MAP is not set
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_ADDRESS_PCI=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OF_NET=y
|
||||
CONFIG_OF_PCI=y
|
||||
CONFIG_OF_PCI_IRQ=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_DRIVERS_LEGACY=y
|
||||
CONFIG_PERF_USE_VMALLOC=y
|
||||
CONFIG_PGTABLE_LEVELS=2
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHY_RALINK_USB=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_RT2880=y
|
||||
# CONFIG_PINCTRL_SINGLE is not set
|
||||
CONFIG_RALINK=y
|
||||
CONFIG_RALINK_WDT=y
|
||||
# CONFIG_RCU_NEED_SEGCBLIST is not set
|
||||
# CONFIG_RCU_STALL_COMMON is not set
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_REGMAP_MMIO=y
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
CONFIG_RTL8366_SMI=y
|
||||
CONFIG_RTL8367B_PHY=y
|
||||
CONFIG_RTL8367_PHY=y
|
||||
# CONFIG_SCHED_INFO is not set
|
||||
# CONFIG_SCSI_DMA is not set
|
||||
# CONFIG_SERIAL_8250_FSL is not set
|
||||
CONFIG_SERIAL_8250_RT288X=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
# CONFIG_SOC_MT7620 is not set
|
||||
# CONFIG_SOC_MT7621 is not set
|
||||
# CONFIG_SOC_RT288X is not set
|
||||
# CONFIG_SOC_RT305X is not set
|
||||
CONFIG_SOC_RT3883=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_MASTER=y
|
||||
# CONFIG_SPI_MT7621 is not set
|
||||
CONFIG_SPI_RT2880=y
|
||||
CONFIG_SRCU=y
|
||||
CONFIG_SWCONFIG=y
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
|
||||
CONFIG_SYS_HAS_CPU_MIPS32_R2=y
|
||||
CONFIG_SYS_HAS_EARLY_PRINTK=y
|
||||
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
|
||||
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
|
||||
CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
|
||||
CONFIG_SYS_SUPPORTS_MIPS16=y
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TINY_SRCU=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_USE_OF=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
Loading…
Reference in New Issue