diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-19 19:40:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-19 19:40:47 -0400 |
commit | fce4a1dda2f1a9a25b3e5b7cd951070e0b42a818 (patch) | |
tree | 03a3f76c5b3d4f3b05dff44c307dbbb64ec5c510 | |
parent | e1f2084ed200eb31f2c9d1efe70569c76889c980 (diff) | |
parent | 6f6c3c33c027f2c83d53e8562cd9daa73fe8108b (diff) |
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus: (48 commits)
MIPS: Move arch_get_unmapped_area and gang to new file.
MIPS: Cleanup arch_get_unmapped_area
MIPS: Octeon: Don't request interrupts for unused IPI mailbox bits.
Octeon: Fix interrupt irq settings for performance counters.
MIPS: Fix build warnings on defconfigs
MIPS: Lemote 2F, Malta: Fix build warning
MIPS: Set ELF AT_PLATFORM string for Loongson2 processors
MIPS: Set ELF AT_PLATFORM string for BMIPS processors
MIPS: Introduce set_elf_platform() helper function
MIPS: JZ4740: setup: Autodetect physical memory.
MIPS: BCM47xx: Fix MAC address parsing.
MIPS: BCM47xx: Extend the filling of SPROM from NVRAM
MIPS: BCM47xx: Register SSB fallback sprom callback
MIPS: BCM47xx: Extend bcm47xx_fill_sprom with prefix.
SSB: Change fallback sprom to callback mechanism.
MIPS: Alchemy: Clean up GPIO registers and accessors
MIPS: Alchemy: Cleanup DMA addresses
MIPS: Alchemy: Rewrite ethernet platform setup
MIPS: Alchemy: Rewrite UART setup and constants.
MIPS: Alchemy: Convert dbdma.c to syscore_ops
...
138 files changed, 9331 insertions, 925 deletions
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index 7ff9b5492041..aef6c917b45a 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms | |||
@@ -11,6 +11,7 @@ platforms += dec | |||
11 | platforms += emma | 11 | platforms += emma |
12 | platforms += jazz | 12 | platforms += jazz |
13 | platforms += jz4740 | 13 | platforms += jz4740 |
14 | platforms += lantiq | ||
14 | platforms += lasat | 15 | platforms += lasat |
15 | platforms += loongson | 16 | platforms += loongson |
16 | platforms += mipssim | 17 | platforms += mipssim |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 351c80fbba7e..2d1cf9740953 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -212,6 +212,24 @@ config MACH_JZ4740 | |||
212 | select HAVE_PWM | 212 | select HAVE_PWM |
213 | select HAVE_CLK | 213 | select HAVE_CLK |
214 | 214 | ||
215 | config LANTIQ | ||
216 | bool "Lantiq based platforms" | ||
217 | select DMA_NONCOHERENT | ||
218 | select IRQ_CPU | ||
219 | select CEVT_R4K | ||
220 | select CSRC_R4K | ||
221 | select SYS_HAS_CPU_MIPS32_R1 | ||
222 | select SYS_HAS_CPU_MIPS32_R2 | ||
223 | select SYS_SUPPORTS_BIG_ENDIAN | ||
224 | select SYS_SUPPORTS_32BIT_KERNEL | ||
225 | select SYS_SUPPORTS_MULTITHREADING | ||
226 | select SYS_HAS_EARLY_PRINTK | ||
227 | select ARCH_REQUIRE_GPIOLIB | ||
228 | select SWAP_IO_SPACE | ||
229 | select BOOT_RAW | ||
230 | select HAVE_CLK | ||
231 | select MIPS_MACHINE | ||
232 | |||
215 | config LASAT | 233 | config LASAT |
216 | bool "LASAT Networks platforms" | 234 | bool "LASAT Networks platforms" |
217 | select CEVT_R4K | 235 | select CEVT_R4K |
@@ -736,6 +754,33 @@ config CAVIUM_OCTEON_REFERENCE_BOARD | |||
736 | Hikari | 754 | Hikari |
737 | Say Y here for most Octeon reference boards. | 755 | Say Y here for most Octeon reference boards. |
738 | 756 | ||
757 | config NLM_XLR_BOARD | ||
758 | bool "Netlogic XLR/XLS based systems" | ||
759 | depends on EXPERIMENTAL | ||
760 | select BOOT_ELF32 | ||
761 | select NLM_COMMON | ||
762 | select NLM_XLR | ||
763 | select SYS_HAS_CPU_XLR | ||
764 | select SYS_SUPPORTS_SMP | ||
765 | select HW_HAS_PCI | ||
766 | select SWAP_IO_SPACE | ||
767 | select SYS_SUPPORTS_32BIT_KERNEL | ||
768 | select SYS_SUPPORTS_64BIT_KERNEL | ||
769 | select 64BIT_PHYS_ADDR | ||
770 | select SYS_SUPPORTS_BIG_ENDIAN | ||
771 | select SYS_SUPPORTS_HIGHMEM | ||
772 | select DMA_COHERENT | ||
773 | select NR_CPUS_DEFAULT_32 | ||
774 | select CEVT_R4K | ||
775 | select CSRC_R4K | ||
776 | select IRQ_CPU | ||
777 | select ZONE_DMA if 64BIT | ||
778 | select SYNC_R4K | ||
779 | select SYS_HAS_EARLY_PRINTK | ||
780 | help | ||
781 | Support for systems based on Netlogic XLR and XLS processors. | ||
782 | Say Y here if you have a XLR or XLS based board. | ||
783 | |||
739 | endchoice | 784 | endchoice |
740 | 785 | ||
741 | source "arch/mips/alchemy/Kconfig" | 786 | source "arch/mips/alchemy/Kconfig" |
@@ -743,6 +788,7 @@ source "arch/mips/ath79/Kconfig" | |||
743 | source "arch/mips/bcm63xx/Kconfig" | 788 | source "arch/mips/bcm63xx/Kconfig" |
744 | source "arch/mips/jazz/Kconfig" | 789 | source "arch/mips/jazz/Kconfig" |
745 | source "arch/mips/jz4740/Kconfig" | 790 | source "arch/mips/jz4740/Kconfig" |
791 | source "arch/mips/lantiq/Kconfig" | ||
746 | source "arch/mips/lasat/Kconfig" | 792 | source "arch/mips/lasat/Kconfig" |
747 | source "arch/mips/pmc-sierra/Kconfig" | 793 | source "arch/mips/pmc-sierra/Kconfig" |
748 | source "arch/mips/powertv/Kconfig" | 794 | source "arch/mips/powertv/Kconfig" |
@@ -752,6 +798,7 @@ source "arch/mips/txx9/Kconfig" | |||
752 | source "arch/mips/vr41xx/Kconfig" | 798 | source "arch/mips/vr41xx/Kconfig" |
753 | source "arch/mips/cavium-octeon/Kconfig" | 799 | source "arch/mips/cavium-octeon/Kconfig" |
754 | source "arch/mips/loongson/Kconfig" | 800 | source "arch/mips/loongson/Kconfig" |
801 | source "arch/mips/netlogic/Kconfig" | ||
755 | 802 | ||
756 | endmenu | 803 | endmenu |
757 | 804 | ||
@@ -1420,6 +1467,17 @@ config CPU_BMIPS5000 | |||
1420 | help | 1467 | help |
1421 | Broadcom BMIPS5000 processors. | 1468 | Broadcom BMIPS5000 processors. |
1422 | 1469 | ||
1470 | config CPU_XLR | ||
1471 | bool "Netlogic XLR SoC" | ||
1472 | depends on SYS_HAS_CPU_XLR | ||
1473 | select CPU_SUPPORTS_32BIT_KERNEL | ||
1474 | select CPU_SUPPORTS_64BIT_KERNEL | ||
1475 | select CPU_SUPPORTS_HIGHMEM | ||
1476 | select WEAK_ORDERING | ||
1477 | select WEAK_REORDERING_BEYOND_LLSC | ||
1478 | select CPU_SUPPORTS_HUGEPAGES | ||
1479 | help | ||
1480 | Netlogic Microsystems XLR/XLS processors. | ||
1423 | endchoice | 1481 | endchoice |
1424 | 1482 | ||
1425 | if CPU_LOONGSON2F | 1483 | if CPU_LOONGSON2F |
@@ -1550,6 +1608,9 @@ config SYS_HAS_CPU_BMIPS4380 | |||
1550 | config SYS_HAS_CPU_BMIPS5000 | 1608 | config SYS_HAS_CPU_BMIPS5000 |
1551 | bool | 1609 | bool |
1552 | 1610 | ||
1611 | config SYS_HAS_CPU_XLR | ||
1612 | bool | ||
1613 | |||
1553 | # | 1614 | # |
1554 | # CPU may reorder R->R, R->W, W->R, W->W | 1615 | # CPU may reorder R->R, R->W, W->R, W->W |
1555 | # Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC | 1616 | # Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 53e3514ba10e..884819cd0607 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -191,6 +191,18 @@ endif | |||
191 | # | 191 | # |
192 | include $(srctree)/arch/mips/Kbuild.platforms | 192 | include $(srctree)/arch/mips/Kbuild.platforms |
193 | 193 | ||
194 | # | ||
195 | # NETLOGIC SOC Common (common) | ||
196 | # | ||
197 | cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/mach-netlogic | ||
198 | cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/netlogic | ||
199 | |||
200 | # | ||
201 | # NETLOGIC XLR/XLS SoC, Simulator and boards | ||
202 | # | ||
203 | core-$(CONFIG_NLM_XLR) += arch/mips/netlogic/xlr/ | ||
204 | load-$(CONFIG_NLM_XLR_BOARD) += 0xffffffff84000000 | ||
205 | |||
194 | cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic | 206 | cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic |
195 | drivers-$(CONFIG_PCI) += arch/mips/pci/ | 207 | drivers-$(CONFIG_PCI) += arch/mips/pci/ |
196 | 208 | ||
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index ca0506a8585a..3a5abb54d505 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
37 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
38 | #include <linux/module.h> | 38 | #include <linux/module.h> |
39 | #include <linux/sysdev.h> | 39 | #include <linux/syscore_ops.h> |
40 | #include <asm/mach-au1x00/au1000.h> | 40 | #include <asm/mach-au1x00/au1000.h> |
41 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | 41 | #include <asm/mach-au1x00/au1xxx_dbdma.h> |
42 | 42 | ||
@@ -58,7 +58,8 @@ static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock); | |||
58 | /* I couldn't find a macro that did this... */ | 58 | /* I couldn't find a macro that did this... */ |
59 | #define ALIGN_ADDR(x, a) ((((u32)(x)) + (a-1)) & ~(a-1)) | 59 | #define ALIGN_ADDR(x, a) ((((u32)(x)) + (a-1)) & ~(a-1)) |
60 | 60 | ||
61 | static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE; | 61 | static dbdma_global_t *dbdma_gptr = |
62 | (dbdma_global_t *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR); | ||
62 | static int dbdma_initialized; | 63 | static int dbdma_initialized; |
63 | 64 | ||
64 | static dbdev_tab_t dbdev_tab[] = { | 65 | static dbdev_tab_t dbdev_tab[] = { |
@@ -299,7 +300,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, | |||
299 | if (ctp != NULL) { | 300 | if (ctp != NULL) { |
300 | memset(ctp, 0, sizeof(chan_tab_t)); | 301 | memset(ctp, 0, sizeof(chan_tab_t)); |
301 | ctp->chan_index = chan = i; | 302 | ctp->chan_index = chan = i; |
302 | dcp = DDMA_CHANNEL_BASE; | 303 | dcp = KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR); |
303 | dcp += (0x0100 * chan); | 304 | dcp += (0x0100 * chan); |
304 | ctp->chan_ptr = (au1x_dma_chan_t *)dcp; | 305 | ctp->chan_ptr = (au1x_dma_chan_t *)dcp; |
305 | cp = (au1x_dma_chan_t *)dcp; | 306 | cp = (au1x_dma_chan_t *)dcp; |
@@ -958,105 +959,75 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr) | |||
958 | } | 959 | } |
959 | 960 | ||
960 | 961 | ||
961 | struct alchemy_dbdma_sysdev { | 962 | static unsigned long alchemy_dbdma_pm_data[NUM_DBDMA_CHANS + 1][6]; |
962 | struct sys_device sysdev; | ||
963 | u32 pm_regs[NUM_DBDMA_CHANS + 1][6]; | ||
964 | }; | ||
965 | 963 | ||
966 | static int alchemy_dbdma_suspend(struct sys_device *dev, | 964 | static int alchemy_dbdma_suspend(void) |
967 | pm_message_t state) | ||
968 | { | 965 | { |
969 | struct alchemy_dbdma_sysdev *sdev = | ||
970 | container_of(dev, struct alchemy_dbdma_sysdev, sysdev); | ||
971 | int i; | 966 | int i; |
972 | u32 addr; | 967 | void __iomem *addr; |
973 | 968 | ||
974 | addr = DDMA_GLOBAL_BASE; | 969 | addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR); |
975 | sdev->pm_regs[0][0] = au_readl(addr + 0x00); | 970 | alchemy_dbdma_pm_data[0][0] = __raw_readl(addr + 0x00); |
976 | sdev->pm_regs[0][1] = au_readl(addr + 0x04); | 971 | alchemy_dbdma_pm_data[0][1] = __raw_readl(addr + 0x04); |
977 | sdev->pm_regs[0][2] = au_readl(addr + 0x08); | 972 | alchemy_dbdma_pm_data[0][2] = __raw_readl(addr + 0x08); |
978 | sdev->pm_regs[0][3] = au_readl(addr + 0x0c); | 973 | alchemy_dbdma_pm_data[0][3] = __raw_readl(addr + 0x0c); |
979 | 974 | ||
980 | /* save channel configurations */ | 975 | /* save channel configurations */ |
981 | for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) { | 976 | addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR); |
982 | sdev->pm_regs[i][0] = au_readl(addr + 0x00); | 977 | for (i = 1; i <= NUM_DBDMA_CHANS; i++) { |
983 | sdev->pm_regs[i][1] = au_readl(addr + 0x04); | 978 | alchemy_dbdma_pm_data[i][0] = __raw_readl(addr + 0x00); |
984 | sdev->pm_regs[i][2] = au_readl(addr + 0x08); | 979 | alchemy_dbdma_pm_data[i][1] = __raw_readl(addr + 0x04); |
985 | sdev->pm_regs[i][3] = au_readl(addr + 0x0c); | 980 | alchemy_dbdma_pm_data[i][2] = __raw_readl(addr + 0x08); |
986 | sdev->pm_regs[i][4] = au_readl(addr + 0x10); | 981 | alchemy_dbdma_pm_data[i][3] = __raw_readl(addr + 0x0c); |
987 | sdev->pm_regs[i][5] = au_readl(addr + 0x14); | 982 | alchemy_dbdma_pm_data[i][4] = __raw_readl(addr + 0x10); |
983 | alchemy_dbdma_pm_data[i][5] = __raw_readl(addr + 0x14); | ||
988 | 984 | ||
989 | /* halt channel */ | 985 | /* halt channel */ |
990 | au_writel(sdev->pm_regs[i][0] & ~1, addr + 0x00); | 986 | __raw_writel(alchemy_dbdma_pm_data[i][0] & ~1, addr + 0x00); |
991 | au_sync(); | 987 | wmb(); |
992 | while (!(au_readl(addr + 0x14) & 1)) | 988 | while (!(__raw_readl(addr + 0x14) & 1)) |
993 | au_sync(); | 989 | wmb(); |
994 | 990 | ||
995 | addr += 0x100; /* next channel base */ | 991 | addr += 0x100; /* next channel base */ |
996 | } | 992 | } |
997 | /* disable channel interrupts */ | 993 | /* disable channel interrupts */ |
998 | au_writel(0, DDMA_GLOBAL_BASE + 0x0c); | 994 | addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR); |
999 | au_sync(); | 995 | __raw_writel(0, addr + 0x0c); |
996 | wmb(); | ||
1000 | 997 | ||
1001 | return 0; | 998 | return 0; |
1002 | } | 999 | } |
1003 | 1000 | ||
1004 | static int alchemy_dbdma_resume(struct sys_device *dev) | 1001 | static void alchemy_dbdma_resume(void) |
1005 | { | 1002 | { |
1006 | struct alchemy_dbdma_sysdev *sdev = | ||
1007 | container_of(dev, struct alchemy_dbdma_sysdev, sysdev); | ||
1008 | int i; | 1003 | int i; |
1009 | u32 addr; | 1004 | void __iomem *addr; |
1010 | 1005 | ||
1011 | addr = DDMA_GLOBAL_BASE; | 1006 | addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR); |
1012 | au_writel(sdev->pm_regs[0][0], addr + 0x00); | 1007 | __raw_writel(alchemy_dbdma_pm_data[0][0], addr + 0x00); |
1013 | au_writel(sdev->pm_regs[0][1], addr + 0x04); | 1008 | __raw_writel(alchemy_dbdma_pm_data[0][1], addr + 0x04); |
1014 | au_writel(sdev->pm_regs[0][2], addr + 0x08); | 1009 | __raw_writel(alchemy_dbdma_pm_data[0][2], addr + 0x08); |
1015 | au_writel(sdev->pm_regs[0][3], addr + 0x0c); | 1010 | __raw_writel(alchemy_dbdma_pm_data[0][3], addr + 0x0c); |
1016 | 1011 | ||
1017 | /* restore channel configurations */ | 1012 | /* restore channel configurations */ |
1018 | for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) { | 1013 | addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR); |
1019 | au_writel(sdev->pm_regs[i][0], addr + 0x00); | 1014 | for (i = 1; i <= NUM_DBDMA_CHANS; i++) { |
1020 | au_writel(sdev->pm_regs[i][1], addr + 0x04); | 1015 | __raw_writel(alchemy_dbdma_pm_data[i][0], addr + 0x00); |
1021 | au_writel(sdev->pm_regs[i][2], addr + 0x08); | 1016 | __raw_writel(alchemy_dbdma_pm_data[i][1], addr + 0x04); |
1022 | au_writel(sdev->pm_regs[i][3], addr + 0x0c); | 1017 | __raw_writel(alchemy_dbdma_pm_data[i][2], addr + 0x08); |
1023 | au_writel(sdev->pm_regs[i][4], addr + 0x10); | 1018 | __raw_writel(alchemy_dbdma_pm_data[i][3], addr + 0x0c); |
1024 | au_writel(sdev->pm_regs[i][5], addr + 0x14); | 1019 | __raw_writel(alchemy_dbdma_pm_data[i][4], addr + 0x10); |
1025 | au_sync(); | 1020 | __raw_writel(alchemy_dbdma_pm_data[i][5], addr + 0x14); |
1021 | wmb(); | ||
1026 | addr += 0x100; /* next channel base */ | 1022 | addr += 0x100; /* next channel base */ |
1027 | } | 1023 | } |
1028 | |||
1029 | return 0; | ||
1030 | } | 1024 | } |
1031 | 1025 | ||
1032 | static struct sysdev_class alchemy_dbdma_sysdev_class = { | 1026 | static struct syscore_ops alchemy_dbdma_syscore_ops = { |
1033 | .name = "dbdma", | ||
1034 | .suspend = alchemy_dbdma_suspend, | 1027 | .suspend = alchemy_dbdma_suspend, |
1035 | .resume = alchemy_dbdma_resume, | 1028 | .resume = alchemy_dbdma_resume, |
1036 | }; | 1029 | }; |
1037 | 1030 | ||
1038 | static int __init alchemy_dbdma_sysdev_init(void) | ||
1039 | { | ||
1040 | struct alchemy_dbdma_sysdev *sdev; | ||
1041 | int ret; | ||
1042 | |||
1043 | ret = sysdev_class_register(&alchemy_dbdma_sysdev_class); | ||
1044 | if (ret) | ||
1045 | return ret; | ||
1046 | |||
1047 | sdev = kzalloc(sizeof(struct alchemy_dbdma_sysdev), GFP_KERNEL); | ||
1048 | if (!sdev) | ||
1049 | return -ENOMEM; | ||
1050 | |||
1051 | sdev->sysdev.id = -1; | ||
1052 | sdev->sysdev.cls = &alchemy_dbdma_sysdev_class; | ||
1053 | ret = sysdev_register(&sdev->sysdev); | ||
1054 | if (ret) | ||
1055 | kfree(sdev); | ||
1056 | |||
1057 | return ret; | ||
1058 | } | ||
1059 | |||
1060 | static int __init au1xxx_dbdma_init(void) | 1031 | static int __init au1xxx_dbdma_init(void) |
1061 | { | 1032 | { |
1062 | int irq_nr, ret; | 1033 | int irq_nr, ret; |
@@ -1084,11 +1055,7 @@ static int __init au1xxx_dbdma_init(void) | |||
1084 | else { | 1055 | else { |
1085 | dbdma_initialized = 1; | 1056 | dbdma_initialized = 1; |
1086 | printk(KERN_INFO "Alchemy DBDMA initialized\n"); | 1057 | printk(KERN_INFO "Alchemy DBDMA initialized\n"); |
1087 | ret = alchemy_dbdma_sysdev_init(); | 1058 | register_syscore_ops(&alchemy_dbdma_syscore_ops); |
1088 | if (ret) { | ||
1089 | printk(KERN_ERR "DBDMA PM init failed\n"); | ||
1090 | ret = 0; | ||
1091 | } | ||
1092 | } | 1059 | } |
1093 | 1060 | ||
1094 | return ret; | 1061 | return ret; |
diff --git a/arch/mips/alchemy/common/dma.c b/arch/mips/alchemy/common/dma.c index d5278877891d..347980e79a89 100644 --- a/arch/mips/alchemy/common/dma.c +++ b/arch/mips/alchemy/common/dma.c | |||
@@ -58,6 +58,9 @@ | |||
58 | * returned from request_dma. | 58 | * returned from request_dma. |
59 | */ | 59 | */ |
60 | 60 | ||
61 | /* DMA Channel register block spacing */ | ||
62 | #define DMA_CHANNEL_LEN 0x00000100 | ||
63 | |||
61 | DEFINE_SPINLOCK(au1000_dma_spin_lock); | 64 | DEFINE_SPINLOCK(au1000_dma_spin_lock); |
62 | 65 | ||
63 | struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = { | 66 | struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = { |
@@ -77,22 +80,23 @@ static const struct dma_dev { | |||
77 | unsigned int fifo_addr; | 80 | unsigned int fifo_addr; |
78 | unsigned int dma_mode; | 81 | unsigned int dma_mode; |
79 | } dma_dev_table[DMA_NUM_DEV] = { | 82 | } dma_dev_table[DMA_NUM_DEV] = { |
80 | {UART0_ADDR + UART_TX, 0}, | 83 | { AU1000_UART0_PHYS_ADDR + 0x04, DMA_DW8 }, /* UART0_TX */ |
81 | {UART0_ADDR + UART_RX, 0}, | 84 | { AU1000_UART0_PHYS_ADDR + 0x00, DMA_DW8 | DMA_DR }, /* UART0_RX */ |
82 | {0, 0}, | 85 | { 0, 0 }, /* DMA_REQ0 */ |
83 | {0, 0}, | 86 | { 0, 0 }, /* DMA_REQ1 */ |
84 | {AC97C_DATA, DMA_DW16 }, /* coherent */ | 87 | { AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 }, /* AC97 TX c */ |
85 | {AC97C_DATA, DMA_DR | DMA_DW16 }, /* coherent */ | 88 | { AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR }, /* AC97 RX c */ |
86 | {UART3_ADDR + UART_TX, DMA_DW8 | DMA_NC}, | 89 | { AU1000_UART3_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* UART3_TX */ |
87 | {UART3_ADDR + UART_RX, DMA_DR | DMA_DW8 | DMA_NC}, | 90 | { AU1000_UART3_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* UART3_RX */ |
88 | {USBD_EP0RD, DMA_DR | DMA_DW8 | DMA_NC}, | 91 | { AU1000_USBD_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* EP0RD */ |
89 | {USBD_EP0WR, DMA_DW8 | DMA_NC}, | 92 | { AU1000_USBD_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */ |
90 | {USBD_EP2WR, DMA_DW8 | DMA_NC}, | 93 | { AU1000_USBD_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */ |
91 | {USBD_EP3WR, DMA_DW8 | DMA_NC}, | 94 | { AU1000_USBD_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */ |
92 | {USBD_EP4RD, DMA_DR | DMA_DW8 | DMA_NC}, | 95 | { AU1000_USBD_PHYS_ADDR + 0x10, DMA_DW8 | DMA_NC | DMA_DR }, /* EP4RD */ |
93 | {USBD_EP5RD, DMA_DR | DMA_DW8 | DMA_NC}, | 96 | { AU1000_USBD_PHYS_ADDR + 0x14, DMA_DW8 | DMA_NC | DMA_DR }, /* EP5RD */ |
94 | {I2S_DATA, DMA_DW32 | DMA_NC}, | 97 | /* on Au1500, these 2 are DMA_REQ2/3 (GPIO208/209) instead! */ |
95 | {I2S_DATA, DMA_DR | DMA_DW32 | DMA_NC} | 98 | { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC}, /* I2S TX */ |
99 | { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC | DMA_DR}, /* I2S RX */ | ||
96 | }; | 100 | }; |
97 | 101 | ||
98 | int au1000_dma_read_proc(char *buf, char **start, off_t fpos, | 102 | int au1000_dma_read_proc(char *buf, char **start, off_t fpos, |
@@ -123,10 +127,10 @@ int au1000_dma_read_proc(char *buf, char **start, off_t fpos, | |||
123 | 127 | ||
124 | /* Device FIFO addresses and default DMA modes - 2nd bank */ | 128 | /* Device FIFO addresses and default DMA modes - 2nd bank */ |
125 | static const struct dma_dev dma_dev_table_bank2[DMA_NUM_DEV_BANK2] = { | 129 | static const struct dma_dev dma_dev_table_bank2[DMA_NUM_DEV_BANK2] = { |
126 | { SD0_XMIT_FIFO, DMA_DS | DMA_DW8 }, /* coherent */ | 130 | { AU1100_SD0_PHYS_ADDR + 0x00, DMA_DS | DMA_DW8 }, /* coherent */ |
127 | { SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 }, /* coherent */ | 131 | { AU1100_SD0_PHYS_ADDR + 0x04, DMA_DS | DMA_DW8 | DMA_DR }, /* coherent */ |
128 | { SD1_XMIT_FIFO, DMA_DS | DMA_DW8 }, /* coherent */ | 132 | { AU1100_SD1_PHYS_ADDR + 0x00, DMA_DS | DMA_DW8 }, /* coherent */ |
129 | { SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 } /* coherent */ | 133 | { AU1100_SD1_PHYS_ADDR + 0x04, DMA_DS | DMA_DW8 | DMA_DR } /* coherent */ |
130 | }; | 134 | }; |
131 | 135 | ||
132 | void dump_au1000_dma_channel(unsigned int dmanr) | 136 | void dump_au1000_dma_channel(unsigned int dmanr) |
@@ -202,7 +206,7 @@ int request_au1000_dma(int dev_id, const char *dev_str, | |||
202 | } | 206 | } |
203 | 207 | ||
204 | /* fill it in */ | 208 | /* fill it in */ |
205 | chan->io = DMA_CHANNEL_BASE + i * DMA_CHANNEL_LEN; | 209 | chan->io = KSEG1ADDR(AU1000_DMA_PHYS_ADDR) + i * DMA_CHANNEL_LEN; |
206 | chan->dev_id = dev_id; | 210 | chan->dev_id = dev_id; |
207 | chan->dev_str = dev_str; | 211 | chan->dev_str = dev_str; |
208 | chan->fifo_addr = dev->fifo_addr; | 212 | chan->fifo_addr = dev->fifo_addr; |
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c index 55dd7c888517..8b60ba0675e2 100644 --- a/arch/mips/alchemy/common/irq.c +++ b/arch/mips/alchemy/common/irq.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
31 | #include <linux/irq.h> | 31 | #include <linux/irq.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/sysdev.h> | 33 | #include <linux/syscore_ops.h> |
34 | 34 | ||
35 | #include <asm/irq_cpu.h> | 35 | #include <asm/irq_cpu.h> |
36 | #include <asm/mipsregs.h> | 36 | #include <asm/mipsregs.h> |
@@ -39,6 +39,36 @@ | |||
39 | #include <asm/mach-pb1x00/pb1000.h> | 39 | #include <asm/mach-pb1x00/pb1000.h> |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | /* Interrupt Controller register offsets */ | ||
43 | #define IC_CFG0RD 0x40 | ||
44 | #define IC_CFG0SET 0x40 | ||
45 | #define IC_CFG0CLR 0x44 | ||
46 | #define IC_CFG1RD 0x48 | ||
47 | #define IC_CFG1SET 0x48 | ||
48 | #define IC_CFG1CLR 0x4C | ||
49 | #define IC_CFG2RD 0x50 | ||
50 | #define IC_CFG2SET 0x50 | ||
51 | #define IC_CFG2CLR 0x54 | ||
52 | #define IC_REQ0INT 0x54 | ||
53 | #define IC_SRCRD 0x58 | ||
54 | #define IC_SRCSET 0x58 | ||
55 | #define IC_SRCCLR 0x5C | ||
56 | #define IC_REQ1INT 0x5C | ||
57 | #define IC_ASSIGNRD 0x60 | ||
58 | #define IC_ASSIGNSET 0x60 | ||
59 | #define IC_ASSIGNCLR 0x64 | ||
60 | #define IC_WAKERD 0x68 | ||
61 | #define IC_WAKESET 0x68 | ||
62 | #define IC_WAKECLR 0x6C | ||
63 | #define IC_MASKRD 0x70 | ||
64 | #define IC_MASKSET 0x70 | ||
65 | #define IC_MASKCLR 0x74 | ||
66 | #define IC_RISINGRD 0x78 | ||
67 | #define IC_RISINGCLR 0x78 | ||
68 | #define IC_FALLINGRD 0x7C | ||
69 | #define IC_FALLINGCLR 0x7C | ||
70 | #define IC_TESTBIT 0x80 | ||
71 | |||
42 | static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type); | 72 | static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type); |
43 | 73 | ||
44 | /* NOTE on interrupt priorities: The original writers of this code said: | 74 | /* NOTE on interrupt priorities: The original writers of this code said: |
@@ -221,89 +251,101 @@ struct au1xxx_irqmap au1200_irqmap[] __initdata = { | |||
221 | static void au1x_ic0_unmask(struct irq_data *d) | 251 | static void au1x_ic0_unmask(struct irq_data *d) |
222 | { | 252 | { |
223 | unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; | 253 | unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; |
224 | au_writel(1 << bit, IC0_MASKSET); | 254 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR); |
225 | au_writel(1 << bit, IC0_WAKESET); | 255 | |
226 | au_sync(); | 256 | __raw_writel(1 << bit, base + IC_MASKSET); |
257 | __raw_writel(1 << bit, base + IC_WAKESET); | ||
258 | wmb(); | ||
227 | } | 259 | } |
228 | 260 | ||
229 | static void au1x_ic1_unmask(struct irq_data *d) | 261 | static void au1x_ic1_unmask(struct irq_data *d) |
230 | { | 262 | { |
231 | unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; | 263 | unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; |
232 | au_writel(1 << bit, IC1_MASKSET); | 264 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR); |
233 | au_writel(1 << bit, IC1_WAKESET); | 265 | |
266 | __raw_writel(1 << bit, base + IC_MASKSET); | ||
267 | __raw_writel(1 << bit, base + IC_WAKESET); | ||
234 | 268 | ||
235 | /* very hacky. does the pb1000 cpld auto-disable this int? | 269 | /* very hacky. does the pb1000 cpld auto-disable this int? |
236 | * nowhere in the current kernel sources is it disabled. --mlau | 270 | * nowhere in the current kernel sources is it disabled. --mlau |
237 | */ | 271 | */ |
238 | #if defined(CONFIG_MIPS_PB1000) | 272 | #if defined(CONFIG_MIPS_PB1000) |
239 | if (d->irq == AU1000_GPIO15_INT) | 273 | if (d->irq == AU1000_GPIO15_INT) |
240 | au_writel(0x4000, PB1000_MDR); /* enable int */ | 274 | __raw_writel(0x4000, (void __iomem *)PB1000_MDR); /* enable int */ |
241 | #endif | 275 | #endif |
242 | au_sync(); | 276 | wmb(); |
243 | } | 277 | } |
244 | 278 | ||
245 | static void au1x_ic0_mask(struct irq_data *d) | 279 | static void au1x_ic0_mask(struct irq_data *d) |
246 | { | 280 | { |
247 | unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; | 281 | unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; |
248 | au_writel(1 << bit, IC0_MASKCLR); | 282 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR); |
249 | au_writel(1 << bit, IC0_WAKECLR); | 283 | |
250 | au_sync(); | 284 | __raw_writel(1 << bit, base + IC_MASKCLR); |
285 | __raw_writel(1 << bit, base + IC_WAKECLR); | ||
286 | wmb(); | ||
251 | } | 287 | } |
252 | 288 | ||
253 | static void au1x_ic1_mask(struct irq_data *d) | 289 | static void au1x_ic1_mask(struct irq_data *d) |
254 | { | 290 | { |
255 | unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; | 291 | unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; |
256 | au_writel(1 << bit, IC1_MASKCLR); | 292 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR); |
257 | au_writel(1 << bit, IC1_WAKECLR); | 293 | |
258 | au_sync(); | 294 | __raw_writel(1 << bit, base + IC_MASKCLR); |
295 | __raw_writel(1 << bit, base + IC_WAKECLR); | ||
296 | wmb(); | ||
259 | } | 297 | } |
260 | 298 | ||
261 | static void au1x_ic0_ack(struct irq_data *d) | 299 | static void au1x_ic0_ack(struct irq_data *d) |
262 | { | 300 | { |
263 | unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; | 301 | unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; |
302 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR); | ||
264 | 303 | ||
265 | /* | 304 | /* |
266 | * This may assume that we don't get interrupts from | 305 | * This may assume that we don't get interrupts from |
267 | * both edges at once, or if we do, that we don't care. | 306 | * both edges at once, or if we do, that we don't care. |
268 | */ | 307 | */ |
269 | au_writel(1 << bit, IC0_FALLINGCLR); | 308 | __raw_writel(1 << bit, base + IC_FALLINGCLR); |
270 | au_writel(1 << bit, IC0_RISINGCLR); | 309 | __raw_writel(1 << bit, base + IC_RISINGCLR); |
271 | au_sync(); | 310 | wmb(); |
272 | } | 311 | } |
273 | 312 | ||
274 | static void au1x_ic1_ack(struct irq_data *d) | 313 | static void au1x_ic1_ack(struct irq_data *d) |
275 | { | 314 | { |
276 | unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; | 315 | unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; |
316 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR); | ||
277 | 317 | ||
278 | /* | 318 | /* |
279 | * This may assume that we don't get interrupts from | 319 | * This may assume that we don't get interrupts from |
280 | * both edges at once, or if we do, that we don't care. | 320 | * both edges at once, or if we do, that we don't care. |
281 | */ | 321 | */ |
282 | au_writel(1 << bit, IC1_FALLINGCLR); | 322 | __raw_writel(1 << bit, base + IC_FALLINGCLR); |
283 | au_writel(1 << bit, IC1_RISINGCLR); | 323 | __raw_writel(1 << bit, base + IC_RISINGCLR); |
284 | au_sync(); | 324 | wmb(); |
285 | } | 325 | } |
286 | 326 | ||
287 | static void au1x_ic0_maskack(struct irq_data *d) | 327 | static void au1x_ic0_maskack(struct irq_data *d) |
288 | { | 328 | { |
289 | unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; | 329 | unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; |
330 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR); | ||
290 | 331 | ||
291 | au_writel(1 << bit, IC0_WAKECLR); | 332 | __raw_writel(1 << bit, base + IC_WAKECLR); |
292 | au_writel(1 << bit, IC0_MASKCLR); | 333 | __raw_writel(1 << bit, base + IC_MASKCLR); |
293 | au_writel(1 << bit, IC0_RISINGCLR); | 334 | __raw_writel(1 << bit, base + IC_RISINGCLR); |
294 | au_writel(1 << bit, IC0_FALLINGCLR); | 335 | __raw_writel(1 << bit, base + IC_FALLINGCLR); |
295 | au_sync(); | 336 | wmb(); |
296 | } | 337 | } |
297 | 338 | ||
298 | static void au1x_ic1_maskack(struct irq_data *d) | 339 | static void au1x_ic1_maskack(struct irq_data *d) |
299 | { | 340 | { |
300 | unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; | 341 | unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; |
342 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR); | ||
301 | 343 | ||
302 | au_writel(1 << bit, IC1_WAKECLR); | 344 | __raw_writel(1 << bit, base + IC_WAKECLR); |
303 | au_writel(1 << bit, IC1_MASKCLR); | 345 | __raw_writel(1 << bit, base + IC_MASKCLR); |
304 | au_writel(1 << bit, IC1_RISINGCLR); | 346 | __raw_writel(1 << bit, base + IC_RISINGCLR); |
305 | au_writel(1 << bit, IC1_FALLINGCLR); | 347 | __raw_writel(1 << bit, base + IC_FALLINGCLR); |
306 | au_sync(); | 348 | wmb(); |
307 | } | 349 | } |
308 | 350 | ||
309 | static int au1x_ic1_setwake(struct irq_data *d, unsigned int on) | 351 | static int au1x_ic1_setwake(struct irq_data *d, unsigned int on) |
@@ -318,13 +360,13 @@ static int au1x_ic1_setwake(struct irq_data *d, unsigned int on) | |||
318 | return -EINVAL; | 360 | return -EINVAL; |
319 | 361 | ||
320 | local_irq_save(flags); | 362 | local_irq_save(flags); |
321 | wakemsk = au_readl(SYS_WAKEMSK); | 363 | wakemsk = __raw_readl((void __iomem *)SYS_WAKEMSK); |
322 | if (on) | 364 | if (on) |
323 | wakemsk |= 1 << bit; | 365 | wakemsk |= 1 << bit; |
324 | else | 366 | else |
325 | wakemsk &= ~(1 << bit); | 367 | wakemsk &= ~(1 << bit); |
326 | au_writel(wakemsk, SYS_WAKEMSK); | 368 | __raw_writel(wakemsk, (void __iomem *)SYS_WAKEMSK); |
327 | au_sync(); | 369 | wmb(); |
328 | local_irq_restore(flags); | 370 | local_irq_restore(flags); |
329 | 371 | ||
330 | return 0; | 372 | return 0; |
@@ -356,81 +398,74 @@ static struct irq_chip au1x_ic1_chip = { | |||
356 | static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type) | 398 | static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type) |
357 | { | 399 | { |
358 | struct irq_chip *chip; | 400 | struct irq_chip *chip; |
359 | unsigned long icr[6]; | 401 | unsigned int bit, irq = d->irq; |
360 | unsigned int bit, ic, irq = d->irq; | ||
361 | irq_flow_handler_t handler = NULL; | 402 | irq_flow_handler_t handler = NULL; |
362 | unsigned char *name = NULL; | 403 | unsigned char *name = NULL; |
404 | void __iomem *base; | ||
363 | int ret; | 405 | int ret; |
364 | 406 | ||
365 | if (irq >= AU1000_INTC1_INT_BASE) { | 407 | if (irq >= AU1000_INTC1_INT_BASE) { |
366 | bit = irq - AU1000_INTC1_INT_BASE; | 408 | bit = irq - AU1000_INTC1_INT_BASE; |
367 | chip = &au1x_ic1_chip; | 409 | chip = &au1x_ic1_chip; |
368 | ic = 1; | 410 | base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR); |
369 | } else { | 411 | } else { |
370 | bit = irq - AU1000_INTC0_INT_BASE; | 412 | bit = irq - AU1000_INTC0_INT_BASE; |
371 | chip = &au1x_ic0_chip; | 413 | chip = &au1x_ic0_chip; |
372 | ic = 0; | 414 | base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR); |
373 | } | 415 | } |
374 | 416 | ||
375 | if (bit > 31) | 417 | if (bit > 31) |
376 | return -EINVAL; | 418 | return -EINVAL; |
377 | 419 | ||
378 | icr[0] = ic ? IC1_CFG0SET : IC0_CFG0SET; | ||
379 | icr[1] = ic ? IC1_CFG1SET : IC0_CFG1SET; | ||
380 | icr[2] = ic ? IC1_CFG2SET : IC0_CFG2SET; | ||
381 | icr[3] = ic ? IC1_CFG0CLR : IC0_CFG0CLR; | ||
382 | icr[4] = ic ? IC1_CFG1CLR : IC0_CFG1CLR; | ||
383 | icr[5] = ic ? IC1_CFG2CLR : IC0_CFG2CLR; | ||
384 | |||
385 | ret = 0; | 420 | ret = 0; |
386 | 421 | ||
387 | switch (flow_type) { /* cfgregs 2:1:0 */ | 422 | switch (flow_type) { /* cfgregs 2:1:0 */ |
388 | case IRQ_TYPE_EDGE_RISING: /* 0:0:1 */ | 423 | case IRQ_TYPE_EDGE_RISING: /* 0:0:1 */ |
389 | au_writel(1 << bit, icr[5]); | 424 | __raw_writel(1 << bit, base + IC_CFG2CLR); |
390 | au_writel(1 << bit, icr[4]); | 425 | __raw_writel(1 << bit, base + IC_CFG1CLR); |
391 | au_writel(1 << bit, icr[0]); | 426 | __raw_writel(1 << bit, base + IC_CFG0SET); |
392 | handler = handle_edge_irq; | 427 | handler = handle_edge_irq; |
393 | name = "riseedge"; | 428 | name = "riseedge"; |
394 | break; | 429 | break; |
395 | case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */ | 430 | case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */ |
396 | au_writel(1 << bit, icr[5]); | 431 | __raw_writel(1 << bit, base + IC_CFG2CLR); |
397 | au_writel(1 << bit, icr[1]); | 432 | __raw_writel(1 << bit, base + IC_CFG1SET); |
398 | au_writel(1 << bit, icr[3]); | 433 | __raw_writel(1 << bit, base + IC_CFG0CLR); |
399 | handler = handle_edge_irq; | 434 | handler = handle_edge_irq; |
400 | name = "falledge"; | 435 | name = "falledge"; |
401 | break; | 436 | break; |
402 | case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */ | 437 | case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */ |
403 | au_writel(1 << bit, icr[5]); | 438 | __raw_writel(1 << bit, base + IC_CFG2CLR); |
404 | au_writel(1 << bit, icr[1]); | 439 | __raw_writel(1 << bit, base + IC_CFG1SET); |
405 | au_writel(1 << bit, icr[0]); | 440 | __raw_writel(1 << bit, base + IC_CFG0SET); |
406 | handler = handle_edge_irq; | 441 | handler = handle_edge_irq; |
407 | name = "bothedge"; | 442 | name = "bothedge"; |
408 | break; | 443 | break; |
409 | case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */ | 444 | case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */ |
410 | au_writel(1 << bit, icr[2]); | 445 | __raw_writel(1 << bit, base + IC_CFG2SET); |
411 | au_writel(1 << bit, icr[4]); | 446 | __raw_writel(1 << bit, base + IC_CFG1CLR); |
412 | au_writel(1 << bit, icr[0]); | 447 | __raw_writel(1 << bit, base + IC_CFG0SET); |
413 | handler = handle_level_irq; | 448 | handler = handle_level_irq; |
414 | name = "hilevel"; | 449 | name = "hilevel"; |
415 | break; | 450 | break; |
416 | case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */ | 451 | case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */ |
417 | au_writel(1 << bit, icr[2]); | 452 | __raw_writel(1 << bit, base + IC_CFG2SET); |
418 | au_writel(1 << bit, icr[1]); | 453 | __raw_writel(1 << bit, base + IC_CFG1SET); |
419 | au_writel(1 << bit, icr[3]); | 454 | __raw_writel(1 << bit, base + IC_CFG0CLR); |
420 | handler = handle_level_irq; | 455 | handler = handle_level_irq; |
421 | name = "lowlevel"; | 456 | name = "lowlevel"; |
422 | break; | 457 | break; |
423 | case IRQ_TYPE_NONE: /* 0:0:0 */ | 458 | case IRQ_TYPE_NONE: /* 0:0:0 */ |
424 | au_writel(1 << bit, icr[5]); | 459 | __raw_writel(1 << bit, base + IC_CFG2CLR); |
425 | au_writel(1 << bit, icr[4]); | 460 | __raw_writel(1 << bit, base + IC_CFG1CLR); |
426 | au_writel(1 << bit, icr[3]); | 461 | __raw_writel(1 << bit, base + IC_CFG0CLR); |
427 | break; | 462 | break; |
428 | default: | 463 | default: |
429 | ret = -EINVAL; | 464 | ret = -EINVAL; |
430 | } | 465 | } |
431 | __irq_set_chip_handler_name_locked(d->irq, chip, handler, name); | 466 | __irq_set_chip_handler_name_locked(d->irq, chip, handler, name); |
432 | 467 | ||
433 | au_sync(); | 468 | wmb(); |
434 | 469 | ||
435 | return ret; | 470 | return ret; |
436 | } | 471 | } |
@@ -444,21 +479,21 @@ asmlinkage void plat_irq_dispatch(void) | |||
444 | off = MIPS_CPU_IRQ_BASE + 7; | 479 | off = MIPS_CPU_IRQ_BASE + 7; |
445 | goto handle; | 480 | goto handle; |
446 | } else if (pending & CAUSEF_IP2) { | 481 | } else if (pending & CAUSEF_IP2) { |
447 | s = IC0_REQ0INT; | 482 | s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ0INT; |
448 | off = AU1000_INTC0_INT_BASE; | 483 | off = AU1000_INTC0_INT_BASE; |
449 | } else if (pending & CAUSEF_IP3) { | 484 | } else if (pending & CAUSEF_IP3) { |
450 | s = IC0_REQ1INT; | 485 | s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ1INT; |
451 | off = AU1000_INTC0_INT_BASE; | 486 | off = AU1000_INTC0_INT_BASE; |
452 | } else if (pending & CAUSEF_IP4) { | 487 | } else if (pending & CAUSEF_IP4) { |
453 | s = IC1_REQ0INT; | 488 | s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ0INT; |
454 | off = AU1000_INTC1_INT_BASE; | 489 | off = AU1000_INTC1_INT_BASE; |
455 | } else if (pending & CAUSEF_IP5) { | 490 | } else if (pending & CAUSEF_IP5) { |
456 | s = IC1_REQ1INT; | 491 | s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ1INT; |
457 | off = AU1000_INTC1_INT_BASE; | 492 | off = AU1000_INTC1_INT_BASE; |
458 | } else | 493 | } else |
459 | goto spurious; | 494 | goto spurious; |
460 | 495 | ||
461 | s = au_readl(s); | 496 | s = __raw_readl((void __iomem *)s); |
462 | if (unlikely(!s)) { | 497 | if (unlikely(!s)) { |
463 | spurious: | 498 | spurious: |
464 | spurious_interrupt(); | 499 | spurious_interrupt(); |
@@ -469,48 +504,42 @@ handle: | |||
469 | do_IRQ(off); | 504 | do_IRQ(off); |
470 | } | 505 | } |
471 | 506 | ||
507 | |||
508 | static inline void ic_init(void __iomem *base) | ||
509 | { | ||
510 | /* initialize interrupt controller to a safe state */ | ||
511 | __raw_writel(0xffffffff, base + IC_CFG0CLR); | ||
512 | __raw_writel(0xffffffff, base + IC_CFG1CLR); | ||
513 | __raw_writel(0xffffffff, base + IC_CFG2CLR); | ||
514 | __raw_writel(0xffffffff, base + IC_MASKCLR); | ||
515 | __raw_writel(0xffffffff, base + IC_ASSIGNCLR); | ||
516 | __raw_writel(0xffffffff, base + IC_WAKECLR); | ||
517 | __raw_writel(0xffffffff, base + IC_SRCSET); | ||
518 | __raw_writel(0xffffffff, base + IC_FALLINGCLR); | ||
519 | __raw_writel(0xffffffff, base + IC_RISINGCLR); | ||
520 | __raw_writel(0x00000000, base + IC_TESTBIT); | ||
521 | wmb(); | ||
522 | } | ||
523 | |||
472 | static void __init au1000_init_irq(struct au1xxx_irqmap *map) | 524 | static void __init au1000_init_irq(struct au1xxx_irqmap *map) |
473 | { | 525 | { |
474 | unsigned int bit, irq_nr; | 526 | unsigned int bit, irq_nr; |
475 | int i; | 527 | void __iomem *base; |
476 | |||
477 | /* | ||
478 | * Initialize interrupt controllers to a safe state. | ||
479 | */ | ||
480 | au_writel(0xffffffff, IC0_CFG0CLR); | ||
481 | au_writel(0xffffffff, IC0_CFG1CLR); | ||
482 | au_writel(0xffffffff, IC0_CFG2CLR); | ||
483 | au_writel(0xffffffff, IC0_MASKCLR); | ||
484 | au_writel(0xffffffff, IC0_ASSIGNCLR); | ||
485 | au_writel(0xffffffff, IC0_WAKECLR); | ||
486 | au_writel(0xffffffff, IC0_SRCSET); | ||
487 | au_writel(0xffffffff, IC0_FALLINGCLR); | ||
488 | au_writel(0xffffffff, IC0_RISINGCLR); | ||
489 | au_writel(0x00000000, IC0_TESTBIT); | ||
490 | |||
491 | au_writel(0xffffffff, IC1_CFG0CLR); | ||
492 | au_writel(0xffffffff, IC1_CFG1CLR); | ||
493 | au_writel(0xffffffff, IC1_CFG2CLR); | ||
494 | au_writel(0xffffffff, IC1_MASKCLR); | ||
495 | au_writel(0xffffffff, IC1_ASSIGNCLR); | ||
496 | au_writel(0xffffffff, IC1_WAKECLR); | ||
497 | au_writel(0xffffffff, IC1_SRCSET); | ||
498 | au_writel(0xffffffff, IC1_FALLINGCLR); | ||
499 | au_writel(0xffffffff, IC1_RISINGCLR); | ||
500 | au_writel(0x00000000, IC1_TESTBIT); | ||
501 | 528 | ||
529 | ic_init((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR)); | ||
530 | ic_init((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR)); | ||
502 | mips_cpu_irq_init(); | 531 | mips_cpu_irq_init(); |
503 | 532 | ||
504 | /* register all 64 possible IC0+IC1 irq sources as type "none". | 533 | /* register all 64 possible IC0+IC1 irq sources as type "none". |
505 | * Use set_irq_type() to set edge/level behaviour at runtime. | 534 | * Use set_irq_type() to set edge/level behaviour at runtime. |
506 | */ | 535 | */ |
507 | for (i = AU1000_INTC0_INT_BASE; | 536 | for (irq_nr = AU1000_INTC0_INT_BASE; |
508 | (i < AU1000_INTC0_INT_BASE + 32); i++) | 537 | (irq_nr < AU1000_INTC0_INT_BASE + 32); irq_nr++) |
509 | au1x_ic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE); | 538 | au1x_ic_settype(irq_get_irq_data(irq_nr), IRQ_TYPE_NONE); |
510 | 539 | ||
511 | for (i = AU1000_INTC1_INT_BASE; | 540 | for (irq_nr = AU1000_INTC1_INT_BASE; |
512 | (i < AU1000_INTC1_INT_BASE + 32); i++) | 541 | (irq_nr < AU1000_INTC1_INT_BASE + 32); irq_nr++) |
513 | au1x_ic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE); | 542 | au1x_ic_settype(irq_get_irq_data(irq_nr), IRQ_TYPE_NONE); |
514 | 543 | ||
515 | /* | 544 | /* |
516 | * Initialize IC0, which is fixed per processor. | 545 | * Initialize IC0, which is fixed per processor. |
@@ -520,13 +549,13 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map) | |||
520 | 549 | ||
521 | if (irq_nr >= AU1000_INTC1_INT_BASE) { | 550 | if (irq_nr >= AU1000_INTC1_INT_BASE) { |
522 | bit = irq_nr - AU1000_INTC1_INT_BASE; | 551 | bit = irq_nr - AU1000_INTC1_INT_BASE; |
523 | if (map->im_request) | 552 | base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR); |
524 | au_writel(1 << bit, IC1_ASSIGNSET); | ||
525 | } else { | 553 | } else { |
526 | bit = irq_nr - AU1000_INTC0_INT_BASE; | 554 | bit = irq_nr - AU1000_INTC0_INT_BASE; |
527 | if (map->im_request) | 555 | base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR); |
528 | au_writel(1 << bit, IC0_ASSIGNSET); | ||
529 | } | 556 | } |
557 | if (map->im_request) | ||
558 | __raw_writel(1 << bit, base + IC_ASSIGNSET); | ||
530 | 559 | ||
531 | au1x_ic_settype(irq_get_irq_data(irq_nr), map->im_type); | 560 | au1x_ic_settype(irq_get_irq_data(irq_nr), map->im_type); |
532 | ++map; | 561 | ++map; |
@@ -556,90 +585,62 @@ void __init arch_init_irq(void) | |||
556 | } | 585 | } |
557 | } | 586 | } |
558 | 587 | ||
559 | struct alchemy_ic_sysdev { | ||
560 | struct sys_device sysdev; | ||
561 | void __iomem *base; | ||
562 | unsigned long pmdata[7]; | ||
563 | }; | ||
564 | 588 | ||
565 | static int alchemy_ic_suspend(struct sys_device *dev, pm_message_t state) | 589 | static unsigned long alchemy_ic_pmdata[7 * 2]; |
566 | { | ||
567 | struct alchemy_ic_sysdev *icdev = | ||
568 | container_of(dev, struct alchemy_ic_sysdev, sysdev); | ||
569 | 590 | ||
570 | icdev->pmdata[0] = __raw_readl(icdev->base + IC_CFG0RD); | 591 | static inline void alchemy_ic_suspend_one(void __iomem *base, unsigned long *d) |
571 | icdev->pmdata[1] = __raw_readl(icdev->base + IC_CFG1RD); | 592 | { |
572 | icdev->pmdata[2] = __raw_readl(icdev->base + IC_CFG2RD); | 593 | d[0] = __raw_readl(base + IC_CFG0RD); |
573 | icdev->pmdata[3] = __raw_readl(icdev->base + IC_SRCRD); | 594 | d[1] = __raw_readl(base + IC_CFG1RD); |
574 | icdev->pmdata[4] = __raw_readl(icdev->base + IC_ASSIGNRD); | 595 | d[2] = __raw_readl(base + IC_CFG2RD); |
575 | icdev->pmdata[5] = __raw_readl(icdev->base + IC_WAKERD); | 596 | d[3] = __raw_readl(base + IC_SRCRD); |
576 | icdev->pmdata[6] = __raw_readl(icdev->base + IC_MASKRD); | 597 | d[4] = __raw_readl(base + IC_ASSIGNRD); |
577 | 598 | d[5] = __raw_readl(base + IC_WAKERD); | |
578 | return 0; | 599 | d[6] = __raw_readl(base + IC_MASKRD); |
600 | ic_init(base); /* shut it up too while at it */ | ||
579 | } | 601 | } |
580 | 602 | ||
581 | static int alchemy_ic_resume(struct sys_device *dev) | 603 | static inline void alchemy_ic_resume_one(void __iomem *base, unsigned long *d) |
582 | { | 604 | { |
583 | struct alchemy_ic_sysdev *icdev = | 605 | ic_init(base); |
584 | container_of(dev, struct alchemy_ic_sysdev, sysdev); | 606 | |
585 | 607 | __raw_writel(d[0], base + IC_CFG0SET); | |
586 | __raw_writel(0xffffffff, icdev->base + IC_MASKCLR); | 608 | __raw_writel(d[1], base + IC_CFG1SET); |
587 | __raw_writel(0xffffffff, icdev->base + IC_CFG0CLR); | 609 | __raw_writel(d[2], base + IC_CFG2SET); |
588 | __raw_writel(0xffffffff, icdev->base + IC_CFG1CLR); | 610 | __raw_writel(d[3], base + IC_SRCSET); |
589 | __raw_writel(0xffffffff, icdev->base + IC_CFG2CLR); | 611 | __raw_writel(d[4], base + IC_ASSIGNSET); |
590 | __raw_writel(0xffffffff, icdev->base + IC_SRCCLR); | 612 | __raw_writel(d[5], base + IC_WAKESET); |
591 | __raw_writel(0xffffffff, icdev->base + IC_ASSIGNCLR); | ||
592 | __raw_writel(0xffffffff, icdev->base + IC_WAKECLR); | ||
593 | __raw_writel(0xffffffff, icdev->base + IC_RISINGCLR); | ||
594 | __raw_writel(0xffffffff, icdev->base + IC_FALLINGCLR); | ||
595 | __raw_writel(0x00000000, icdev->base + IC_TESTBIT); | ||
596 | wmb(); | ||
597 | __raw_writel(icdev->pmdata[0], icdev->base + IC_CFG0SET); | ||
598 | __raw_writel(icdev->pmdata[1], icdev->base + IC_CFG1SET); | ||
599 | __raw_writel(icdev->pmdata[2], icdev->base + IC_CFG2SET); | ||
600 | __raw_writel(icdev->pmdata[3], icdev->base + IC_SRCSET); | ||
601 | __raw_writel(icdev->pmdata[4], icdev->base + IC_ASSIGNSET); | ||
602 | __raw_writel(icdev->pmdata[5], icdev->base + IC_WAKESET); | ||
603 | wmb(); | 613 | wmb(); |
604 | 614 | ||
605 | __raw_writel(icdev->pmdata[6], icdev->base + IC_MASKSET); | 615 | __raw_writel(d[6], base + IC_MASKSET); |
606 | wmb(); | 616 | wmb(); |
617 | } | ||
607 | 618 | ||
619 | static int alchemy_ic_suspend(void) | ||
620 | { | ||
621 | alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR), | ||
622 | alchemy_ic_pmdata); | ||
623 | alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR), | ||
624 | &alchemy_ic_pmdata[7]); | ||
608 | return 0; | 625 | return 0; |
609 | } | 626 | } |
610 | 627 | ||
611 | static struct sysdev_class alchemy_ic_sysdev_class = { | 628 | static void alchemy_ic_resume(void) |
612 | .name = "ic", | 629 | { |
630 | alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR), | ||
631 | &alchemy_ic_pmdata[7]); | ||
632 | alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR), | ||
633 | alchemy_ic_pmdata); | ||
634 | } | ||
635 | |||
636 | static struct syscore_ops alchemy_ic_syscore_ops = { | ||
613 | .suspend = alchemy_ic_suspend, | 637 | .suspend = alchemy_ic_suspend, |
614 | .resume = alchemy_ic_resume, | 638 | .resume = alchemy_ic_resume, |
615 | }; | 639 | }; |
616 | 640 | ||
617 | static int __init alchemy_ic_sysdev_init(void) | 641 | static int __init alchemy_ic_pm_init(void) |
618 | { | 642 | { |
619 | struct alchemy_ic_sysdev *icdev; | 643 | register_syscore_ops(&alchemy_ic_syscore_ops); |
620 | unsigned long icbase[2] = { IC0_PHYS_ADDR, IC1_PHYS_ADDR }; | ||
621 | int err, i; | ||
622 | |||
623 | err = sysdev_class_register(&alchemy_ic_sysdev_class); | ||
624 | if (err) | ||
625 | return err; | ||
626 | |||
627 | for (i = 0; i < 2; i++) { | ||
628 | icdev = kzalloc(sizeof(struct alchemy_ic_sysdev), GFP_KERNEL); | ||
629 | if (!icdev) | ||
630 | return -ENOMEM; | ||
631 | |||
632 | icdev->base = ioremap(icbase[i], 0x1000); | ||
633 | |||
634 | icdev->sysdev.id = i; | ||
635 | icdev->sysdev.cls = &alchemy_ic_sysdev_class; | ||
636 | err = sysdev_register(&icdev->sysdev); | ||
637 | if (err) { | ||
638 | kfree(icdev); | ||
639 | return err; | ||
640 | } | ||
641 | } | ||
642 | |||
643 | return 0; | 644 | return 0; |
644 | } | 645 | } |
645 | device_initcall(alchemy_ic_sysdev_init); | 646 | device_initcall(alchemy_ic_pm_init); |
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index 9e7814db3d03..3b2c18b14341 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c | |||
@@ -13,9 +13,10 @@ | |||
13 | 13 | ||
14 | #include <linux/dma-mapping.h> | 14 | #include <linux/dma-mapping.h> |
15 | #include <linux/etherdevice.h> | 15 | #include <linux/etherdevice.h> |
16 | #include <linux/init.h> | ||
16 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
17 | #include <linux/serial_8250.h> | 18 | #include <linux/serial_8250.h> |
18 | #include <linux/init.h> | 19 | #include <linux/slab.h> |
19 | 20 | ||
20 | #include <asm/mach-au1x00/au1xxx.h> | 21 | #include <asm/mach-au1x00/au1xxx.h> |
21 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | 22 | #include <asm/mach-au1x00/au1xxx_dbdma.h> |
@@ -30,21 +31,12 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state, | |||
30 | #ifdef CONFIG_SERIAL_8250 | 31 | #ifdef CONFIG_SERIAL_8250 |
31 | switch (state) { | 32 | switch (state) { |
32 | case 0: | 33 | case 0: |
33 | if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) { | 34 | alchemy_uart_enable(CPHYSADDR(port->membase)); |
34 | /* power-on sequence as suggested in the databooks */ | ||
35 | __raw_writel(0, port->membase + UART_MOD_CNTRL); | ||
36 | wmb(); | ||
37 | __raw_writel(1, port->membase + UART_MOD_CNTRL); | ||
38 | wmb(); | ||
39 | } | ||
40 | __raw_writel(3, port->membase + UART_MOD_CNTRL); /* full on */ | ||
41 | wmb(); | ||
42 | serial8250_do_pm(port, state, old_state); | 35 | serial8250_do_pm(port, state, old_state); |
43 | break; | 36 | break; |
44 | case 3: /* power off */ | 37 | case 3: /* power off */ |
45 | serial8250_do_pm(port, state, old_state); | 38 | serial8250_do_pm(port, state, old_state); |
46 | __raw_writel(0, port->membase + UART_MOD_CNTRL); | 39 | alchemy_uart_disable(CPHYSADDR(port->membase)); |
47 | wmb(); | ||
48 | break; | 40 | break; |
49 | default: | 41 | default: |
50 | serial8250_do_pm(port, state, old_state); | 42 | serial8250_do_pm(port, state, old_state); |
@@ -65,38 +57,60 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state, | |||
65 | .pm = alchemy_8250_pm, \ | 57 | .pm = alchemy_8250_pm, \ |
66 | } | 58 | } |
67 | 59 | ||
68 | static struct plat_serial8250_port au1x00_uart_data[] = { | 60 | static struct plat_serial8250_port au1x00_uart_data[][4] __initdata = { |
69 | #if defined(CONFIG_SOC_AU1000) | 61 | [ALCHEMY_CPU_AU1000] = { |
70 | PORT(UART0_PHYS_ADDR, AU1000_UART0_INT), | 62 | PORT(AU1000_UART0_PHYS_ADDR, AU1000_UART0_INT), |
71 | PORT(UART1_PHYS_ADDR, AU1000_UART1_INT), | 63 | PORT(AU1000_UART1_PHYS_ADDR, AU1000_UART1_INT), |
72 | PORT(UART2_PHYS_ADDR, AU1000_UART2_INT), | 64 | PORT(AU1000_UART2_PHYS_ADDR, AU1000_UART2_INT), |
73 | PORT(UART3_PHYS_ADDR, AU1000_UART3_INT), | 65 | PORT(AU1000_UART3_PHYS_ADDR, AU1000_UART3_INT), |
74 | #elif defined(CONFIG_SOC_AU1500) | 66 | }, |
75 | PORT(UART0_PHYS_ADDR, AU1500_UART0_INT), | 67 | [ALCHEMY_CPU_AU1500] = { |
76 | PORT(UART3_PHYS_ADDR, AU1500_UART3_INT), | 68 | PORT(AU1000_UART0_PHYS_ADDR, AU1500_UART0_INT), |
77 | #elif defined(CONFIG_SOC_AU1100) | 69 | PORT(AU1000_UART3_PHYS_ADDR, AU1500_UART3_INT), |
78 | PORT(UART0_PHYS_ADDR, AU1100_UART0_INT), | 70 | }, |
79 | PORT(UART1_PHYS_ADDR, AU1100_UART1_INT), | 71 | [ALCHEMY_CPU_AU1100] = { |
80 | PORT(UART3_PHYS_ADDR, AU1100_UART3_INT), | 72 | PORT(AU1000_UART0_PHYS_ADDR, AU1100_UART0_INT), |
81 | #elif defined(CONFIG_SOC_AU1550) | 73 | PORT(AU1000_UART1_PHYS_ADDR, AU1100_UART1_INT), |
82 | PORT(UART0_PHYS_ADDR, AU1550_UART0_INT), | 74 | PORT(AU1000_UART3_PHYS_ADDR, AU1100_UART3_INT), |
83 | PORT(UART1_PHYS_ADDR, AU1550_UART1_INT), | 75 | }, |
84 | PORT(UART3_PHYS_ADDR, AU1550_UART3_INT), | 76 | [ALCHEMY_CPU_AU1550] = { |
85 | #elif defined(CONFIG_SOC_AU1200) | 77 | PORT(AU1000_UART0_PHYS_ADDR, AU1550_UART0_INT), |
86 | PORT(UART0_PHYS_ADDR, AU1200_UART0_INT), | 78 | PORT(AU1000_UART1_PHYS_ADDR, AU1550_UART1_INT), |
87 | PORT(UART1_PHYS_ADDR, AU1200_UART1_INT), | 79 | PORT(AU1000_UART3_PHYS_ADDR, AU1550_UART3_INT), |
88 | #endif | 80 | }, |
89 | { }, | 81 | [ALCHEMY_CPU_AU1200] = { |
82 | PORT(AU1000_UART0_PHYS_ADDR, AU1200_UART0_INT), | ||
83 | PORT(AU1000_UART1_PHYS_ADDR, AU1200_UART1_INT), | ||
84 | }, | ||
90 | }; | 85 | }; |
91 | 86 | ||
92 | static struct platform_device au1xx0_uart_device = { | 87 | static struct platform_device au1xx0_uart_device = { |
93 | .name = "serial8250", | 88 | .name = "serial8250", |
94 | .id = PLAT8250_DEV_AU1X00, | 89 | .id = PLAT8250_DEV_AU1X00, |
95 | .dev = { | ||
96 | .platform_data = au1x00_uart_data, | ||
97 | }, | ||
98 | }; | 90 | }; |
99 | 91 | ||
92 | static void __init alchemy_setup_uarts(int ctype) | ||
93 | { | ||
94 | unsigned int uartclk = get_au1x00_uart_baud_base() * 16; | ||
95 | int s = sizeof(struct plat_serial8250_port); | ||
96 | int c = alchemy_get_uarts(ctype); | ||
97 | struct plat_serial8250_port *ports; | ||
98 | |||
99 | ports = kzalloc(s * (c + 1), GFP_KERNEL); | ||
100 | if (!ports) { | ||
101 | printk(KERN_INFO "Alchemy: no memory for UART data\n"); | ||
102 | return; | ||
103 | } | ||
104 | memcpy(ports, au1x00_uart_data[ctype], s * c); | ||
105 | au1xx0_uart_device.dev.platform_data = ports; | ||
106 | |||
107 | /* Fill up uartclk. */ | ||
108 | for (s = 0; s < c; s++) | ||
109 | ports[s].uartclk = uartclk; | ||
110 | if (platform_device_register(&au1xx0_uart_device)) | ||
111 | printk(KERN_INFO "Alchemy: failed to register UARTs\n"); | ||
112 | } | ||
113 | |||
100 | /* OHCI (USB full speed host controller) */ | 114 | /* OHCI (USB full speed host controller) */ |
101 | static struct resource au1xxx_usb_ohci_resources[] = { | 115 | static struct resource au1xxx_usb_ohci_resources[] = { |
102 | [0] = { | 116 | [0] = { |
@@ -269,8 +283,8 @@ extern struct au1xmmc_platform_data au1xmmc_platdata[2]; | |||
269 | 283 | ||
270 | static struct resource au1200_mmc0_resources[] = { | 284 | static struct resource au1200_mmc0_resources[] = { |
271 | [0] = { | 285 | [0] = { |
272 | .start = SD0_PHYS_ADDR, | 286 | .start = AU1100_SD0_PHYS_ADDR, |
273 | .end = SD0_PHYS_ADDR + 0x7ffff, | 287 | .end = AU1100_SD0_PHYS_ADDR + 0xfff, |
274 | .flags = IORESOURCE_MEM, | 288 | .flags = IORESOURCE_MEM, |
275 | }, | 289 | }, |
276 | [1] = { | 290 | [1] = { |
@@ -305,8 +319,8 @@ static struct platform_device au1200_mmc0_device = { | |||
305 | #ifndef CONFIG_MIPS_DB1200 | 319 | #ifndef CONFIG_MIPS_DB1200 |
306 | static struct resource au1200_mmc1_resources[] = { | 320 | static struct resource au1200_mmc1_resources[] = { |
307 | [0] = { | 321 | [0] = { |
308 | .start = SD1_PHYS_ADDR, | 322 | .start = AU1100_SD1_PHYS_ADDR, |
309 | .end = SD1_PHYS_ADDR + 0x7ffff, | 323 | .end = AU1100_SD1_PHYS_ADDR + 0xfff, |
310 | .flags = IORESOURCE_MEM, | 324 | .flags = IORESOURCE_MEM, |
311 | }, | 325 | }, |
312 | [1] = { | 326 | [1] = { |
@@ -359,15 +373,16 @@ static struct platform_device pbdb_smbus_device = { | |||
359 | #endif | 373 | #endif |
360 | 374 | ||
361 | /* Macro to help defining the Ethernet MAC resources */ | 375 | /* Macro to help defining the Ethernet MAC resources */ |
376 | #define MAC_RES_COUNT 3 /* MAC regs base, MAC enable reg, MAC INT */ | ||
362 | #define MAC_RES(_base, _enable, _irq) \ | 377 | #define MAC_RES(_base, _enable, _irq) \ |
363 | { \ | 378 | { \ |
364 | .start = CPHYSADDR(_base), \ | 379 | .start = _base, \ |
365 | .end = CPHYSADDR(_base + 0xffff), \ | 380 | .end = _base + 0xffff, \ |
366 | .flags = IORESOURCE_MEM, \ | 381 | .flags = IORESOURCE_MEM, \ |
367 | }, \ | 382 | }, \ |
368 | { \ | 383 | { \ |
369 | .start = CPHYSADDR(_enable), \ | 384 | .start = _enable, \ |
370 | .end = CPHYSADDR(_enable + 0x3), \ | 385 | .end = _enable + 0x3, \ |
371 | .flags = IORESOURCE_MEM, \ | 386 | .flags = IORESOURCE_MEM, \ |
372 | }, \ | 387 | }, \ |
373 | { \ | 388 | { \ |
@@ -376,19 +391,29 @@ static struct platform_device pbdb_smbus_device = { | |||
376 | .flags = IORESOURCE_IRQ \ | 391 | .flags = IORESOURCE_IRQ \ |
377 | } | 392 | } |
378 | 393 | ||
379 | static struct resource au1xxx_eth0_resources[] = { | 394 | static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = { |
380 | #if defined(CONFIG_SOC_AU1000) | 395 | [ALCHEMY_CPU_AU1000] = { |
381 | MAC_RES(AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT), | 396 | MAC_RES(AU1000_MAC0_PHYS_ADDR, |
382 | #elif defined(CONFIG_SOC_AU1100) | 397 | AU1000_MACEN_PHYS_ADDR, |
383 | MAC_RES(AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT), | 398 | AU1000_MAC0_DMA_INT) |
384 | #elif defined(CONFIG_SOC_AU1550) | 399 | }, |
385 | MAC_RES(AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT), | 400 | [ALCHEMY_CPU_AU1500] = { |
386 | #elif defined(CONFIG_SOC_AU1500) | 401 | MAC_RES(AU1500_MAC0_PHYS_ADDR, |
387 | MAC_RES(AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT), | 402 | AU1500_MACEN_PHYS_ADDR, |
388 | #endif | 403 | AU1500_MAC0_DMA_INT) |
404 | }, | ||
405 | [ALCHEMY_CPU_AU1100] = { | ||
406 | MAC_RES(AU1000_MAC0_PHYS_ADDR, | ||
407 | AU1000_MACEN_PHYS_ADDR, | ||
408 | AU1100_MAC0_DMA_INT) | ||
409 | }, | ||
410 | [ALCHEMY_CPU_AU1550] = { | ||
411 | MAC_RES(AU1000_MAC0_PHYS_ADDR, | ||
412 | AU1000_MACEN_PHYS_ADDR, | ||
413 | AU1550_MAC0_DMA_INT) | ||
414 | }, | ||
389 | }; | 415 | }; |
390 | 416 | ||
391 | |||
392 | static struct au1000_eth_platform_data au1xxx_eth0_platform_data = { | 417 | static struct au1000_eth_platform_data au1xxx_eth0_platform_data = { |
393 | .phy1_search_mac0 = 1, | 418 | .phy1_search_mac0 = 1, |
394 | }; | 419 | }; |
@@ -396,20 +421,26 @@ static struct au1000_eth_platform_data au1xxx_eth0_platform_data = { | |||
396 | static struct platform_device au1xxx_eth0_device = { | 421 | static struct platform_device au1xxx_eth0_device = { |
397 | .name = "au1000-eth", | 422 | .name = "au1000-eth", |
398 | .id = 0, | 423 | .id = 0, |
399 | .num_resources = ARRAY_SIZE(au1xxx_eth0_resources), | 424 | .num_resources = MAC_RES_COUNT, |
400 | .resource = au1xxx_eth0_resources, | ||
401 | .dev.platform_data = &au1xxx_eth0_platform_data, | 425 | .dev.platform_data = &au1xxx_eth0_platform_data, |
402 | }; | 426 | }; |
403 | 427 | ||
404 | #ifndef CONFIG_SOC_AU1100 | 428 | static struct resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = { |
405 | static struct resource au1xxx_eth1_resources[] = { | 429 | [ALCHEMY_CPU_AU1000] = { |
406 | #if defined(CONFIG_SOC_AU1000) | 430 | MAC_RES(AU1000_MAC1_PHYS_ADDR, |
407 | MAC_RES(AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT), | 431 | AU1000_MACEN_PHYS_ADDR + 4, |
408 | #elif defined(CONFIG_SOC_AU1550) | 432 | AU1000_MAC1_DMA_INT) |
409 | MAC_RES(AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT), | 433 | }, |
410 | #elif defined(CONFIG_SOC_AU1500) | 434 | [ALCHEMY_CPU_AU1500] = { |
411 | MAC_RES(AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT), | 435 | MAC_RES(AU1500_MAC1_PHYS_ADDR, |
412 | #endif | 436 | AU1500_MACEN_PHYS_ADDR + 4, |
437 | AU1500_MAC1_DMA_INT) | ||
438 | }, | ||
439 | [ALCHEMY_CPU_AU1550] = { | ||
440 | MAC_RES(AU1000_MAC1_PHYS_ADDR, | ||
441 | AU1000_MACEN_PHYS_ADDR + 4, | ||
442 | AU1550_MAC1_DMA_INT) | ||
443 | }, | ||
413 | }; | 444 | }; |
414 | 445 | ||
415 | static struct au1000_eth_platform_data au1xxx_eth1_platform_data = { | 446 | static struct au1000_eth_platform_data au1xxx_eth1_platform_data = { |
@@ -419,11 +450,9 @@ static struct au1000_eth_platform_data au1xxx_eth1_platform_data = { | |||
419 | static struct platform_device au1xxx_eth1_device = { | 450 | static struct platform_device au1xxx_eth1_device = { |
420 | .name = "au1000-eth", | 451 | .name = "au1000-eth", |
421 | .id = 1, | 452 | .id = 1, |
422 | .num_resources = ARRAY_SIZE(au1xxx_eth1_resources), | 453 | .num_resources = MAC_RES_COUNT, |
423 | .resource = au1xxx_eth1_resources, | ||
424 | .dev.platform_data = &au1xxx_eth1_platform_data, | 454 | .dev.platform_data = &au1xxx_eth1_platform_data, |
425 | }; | 455 | }; |
426 | #endif | ||
427 | 456 | ||
428 | void __init au1xxx_override_eth_cfg(unsigned int port, | 457 | void __init au1xxx_override_eth_cfg(unsigned int port, |
429 | struct au1000_eth_platform_data *eth_data) | 458 | struct au1000_eth_platform_data *eth_data) |
@@ -434,15 +463,65 @@ void __init au1xxx_override_eth_cfg(unsigned int port, | |||
434 | if (port == 0) | 463 | if (port == 0) |
435 | memcpy(&au1xxx_eth0_platform_data, eth_data, | 464 | memcpy(&au1xxx_eth0_platform_data, eth_data, |
436 | sizeof(struct au1000_eth_platform_data)); | 465 | sizeof(struct au1000_eth_platform_data)); |
437 | #ifndef CONFIG_SOC_AU1100 | ||
438 | else | 466 | else |
439 | memcpy(&au1xxx_eth1_platform_data, eth_data, | 467 | memcpy(&au1xxx_eth1_platform_data, eth_data, |
440 | sizeof(struct au1000_eth_platform_data)); | 468 | sizeof(struct au1000_eth_platform_data)); |
441 | #endif | 469 | } |
470 | |||
471 | static void __init alchemy_setup_macs(int ctype) | ||
472 | { | ||
473 | int ret, i; | ||
474 | unsigned char ethaddr[6]; | ||
475 | struct resource *macres; | ||
476 | |||
477 | /* Handle 1st MAC */ | ||
478 | if (alchemy_get_macs(ctype) < 1) | ||
479 | return; | ||
480 | |||
481 | macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL); | ||
482 | if (!macres) { | ||
483 | printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n"); | ||
484 | return; | ||
485 | } | ||
486 | memcpy(macres, au1xxx_eth0_resources[ctype], | ||
487 | sizeof(struct resource) * MAC_RES_COUNT); | ||
488 | au1xxx_eth0_device.resource = macres; | ||
489 | |||
490 | i = prom_get_ethernet_addr(ethaddr); | ||
491 | if (!i && !is_valid_ether_addr(au1xxx_eth0_platform_data.mac)) | ||
492 | memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6); | ||
493 | |||
494 | ret = platform_device_register(&au1xxx_eth0_device); | ||
495 | if (!ret) | ||
496 | printk(KERN_INFO "Alchemy: failed to register MAC0\n"); | ||
497 | |||
498 | |||
499 | /* Handle 2nd MAC */ | ||
500 | if (alchemy_get_macs(ctype) < 2) | ||
501 | return; | ||
502 | |||
503 | macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL); | ||
504 | if (!macres) { | ||
505 | printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n"); | ||
506 | return; | ||
507 | } | ||
508 | memcpy(macres, au1xxx_eth1_resources[ctype], | ||
509 | sizeof(struct resource) * MAC_RES_COUNT); | ||
510 | au1xxx_eth1_device.resource = macres; | ||
511 | |||
512 | ethaddr[5] += 1; /* next addr for 2nd MAC */ | ||
513 | if (!i && !is_valid_ether_addr(au1xxx_eth1_platform_data.mac)) | ||
514 | memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6); | ||
515 | |||
516 | /* Register second MAC if enabled in pinfunc */ | ||
517 | if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2)) { | ||
518 | ret = platform_device_register(&au1xxx_eth1_device); | ||
519 | if (ret) | ||
520 | printk(KERN_INFO "Alchemy: failed to register MAC1\n"); | ||
521 | } | ||
442 | } | 522 | } |
443 | 523 | ||
444 | static struct platform_device *au1xxx_platform_devices[] __initdata = { | 524 | static struct platform_device *au1xxx_platform_devices[] __initdata = { |
445 | &au1xx0_uart_device, | ||
446 | &au1xxx_usb_ohci_device, | 525 | &au1xxx_usb_ohci_device, |
447 | #ifdef CONFIG_FB_AU1100 | 526 | #ifdef CONFIG_FB_AU1100 |
448 | &au1100_lcd_device, | 527 | &au1100_lcd_device, |
@@ -460,36 +539,17 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = { | |||
460 | #ifdef SMBUS_PSC_BASE | 539 | #ifdef SMBUS_PSC_BASE |
461 | &pbdb_smbus_device, | 540 | &pbdb_smbus_device, |
462 | #endif | 541 | #endif |
463 | &au1xxx_eth0_device, | ||
464 | }; | 542 | }; |
465 | 543 | ||
466 | static int __init au1xxx_platform_init(void) | 544 | static int __init au1xxx_platform_init(void) |
467 | { | 545 | { |
468 | unsigned int uartclk = get_au1x00_uart_baud_base() * 16; | 546 | int err, ctype = alchemy_get_cputype(); |
469 | int err, i; | ||
470 | unsigned char ethaddr[6]; | ||
471 | 547 | ||
472 | /* Fill up uartclk. */ | 548 | alchemy_setup_uarts(ctype); |
473 | for (i = 0; au1x00_uart_data[i].flags; i++) | 549 | alchemy_setup_macs(ctype); |
474 | au1x00_uart_data[i].uartclk = uartclk; | ||
475 | |||
476 | /* use firmware-provided mac addr if available and necessary */ | ||
477 | i = prom_get_ethernet_addr(ethaddr); | ||
478 | if (!i && !is_valid_ether_addr(au1xxx_eth0_platform_data.mac)) | ||
479 | memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6); | ||
480 | 550 | ||
481 | err = platform_add_devices(au1xxx_platform_devices, | 551 | err = platform_add_devices(au1xxx_platform_devices, |
482 | ARRAY_SIZE(au1xxx_platform_devices)); | 552 | ARRAY_SIZE(au1xxx_platform_devices)); |
483 | #ifndef CONFIG_SOC_AU1100 | ||
484 | ethaddr[5] += 1; /* next addr for 2nd MAC */ | ||
485 | if (!i && !is_valid_ether_addr(au1xxx_eth1_platform_data.mac)) | ||
486 | memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6); | ||
487 | |||
488 | /* Register second MAC if enabled in pinfunc */ | ||
489 | if (!err && !(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2)) | ||
490 | err = platform_device_register(&au1xxx_eth1_device); | ||
491 | #endif | ||
492 | |||
493 | return err; | 553 | return err; |
494 | } | 554 | } |
495 | 555 | ||
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index 561e5da2658b..1b887c868417 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c | |||
@@ -52,8 +52,6 @@ void __init plat_mem_setup(void) | |||
52 | /* this is faster than wasting cycles trying to approximate it */ | 52 | /* this is faster than wasting cycles trying to approximate it */ |
53 | preset_lpj = (est_freq >> 1) / HZ; | 53 | preset_lpj = (est_freq >> 1) / HZ; |
54 | 54 | ||
55 | board_setup(); /* board specific setup */ | ||
56 | |||
57 | if (au1xxx_cpu_needs_config_od()) | 55 | if (au1xxx_cpu_needs_config_od()) |
58 | /* Various early Au1xx0 errata corrected by this */ | 56 | /* Various early Au1xx0 errata corrected by this */ |
59 | set_c0_config(1 << 19); /* Set Config[OD] */ | 57 | set_c0_config(1 << 19); /* Set Config[OD] */ |
@@ -61,6 +59,8 @@ void __init plat_mem_setup(void) | |||
61 | /* Clear to obtain best system bus performance */ | 59 | /* Clear to obtain best system bus performance */ |
62 | clear_c0_config(1 << 19); /* Clear Config[OD] */ | 60 | clear_c0_config(1 << 19); /* Clear Config[OD] */ |
63 | 61 | ||
62 | board_setup(); /* board specific setup */ | ||
63 | |||
64 | /* IO/MEM resources. */ | 64 | /* IO/MEM resources. */ |
65 | set_io_port_base(0); | 65 | set_io_port_base(0); |
66 | ioport_resource.start = IOPORT_RESOURCE_START; | 66 | ioport_resource.start = IOPORT_RESOURCE_START; |
diff --git a/arch/mips/alchemy/devboards/db1200/setup.c b/arch/mips/alchemy/devboards/db1200/setup.c index 4a8980027ecf..1dac4f27d334 100644 --- a/arch/mips/alchemy/devboards/db1200/setup.c +++ b/arch/mips/alchemy/devboards/db1200/setup.c | |||
@@ -23,6 +23,13 @@ void __init board_setup(void) | |||
23 | unsigned long freq0, clksrc, div, pfc; | 23 | unsigned long freq0, clksrc, div, pfc; |
24 | unsigned short whoami; | 24 | unsigned short whoami; |
25 | 25 | ||
26 | /* Set Config[OD] (disable overlapping bus transaction): | ||
27 | * This gets rid of a _lot_ of spurious interrupts (especially | ||
28 | * wrt. IDE); but incurs ~10% performance hit in some | ||
29 | * cpu-bound applications. | ||
30 | */ | ||
31 | set_c0_config(1 << 19); | ||
32 | |||
26 | bcsr_init(DB1200_BCSR_PHYS_ADDR, | 33 | bcsr_init(DB1200_BCSR_PHYS_ADDR, |
27 | DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS); | 34 | DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS); |
28 | 35 | ||
diff --git a/arch/mips/alchemy/devboards/pb1000/board_setup.c b/arch/mips/alchemy/devboards/pb1000/board_setup.c index 2d85c4b5be09..e64fdcbf75d0 100644 --- a/arch/mips/alchemy/devboards/pb1000/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1000/board_setup.c | |||
@@ -65,7 +65,7 @@ void __init board_setup(void) | |||
65 | 65 | ||
66 | /* Set AUX clock to 12 MHz * 8 = 96 MHz */ | 66 | /* Set AUX clock to 12 MHz * 8 = 96 MHz */ |
67 | au_writel(8, SYS_AUXPLL); | 67 | au_writel(8, SYS_AUXPLL); |
68 | au_writel(0, SYS_PINSTATERD); | 68 | alchemy_gpio1_input_enable(); |
69 | udelay(100); | 69 | udelay(100); |
70 | 70 | ||
71 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 71 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
diff --git a/arch/mips/alchemy/devboards/pb1500/board_setup.c b/arch/mips/alchemy/devboards/pb1500/board_setup.c index 83f46215eb0c..3b4fa3206969 100644 --- a/arch/mips/alchemy/devboards/pb1500/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1500/board_setup.c | |||
@@ -56,7 +56,7 @@ void __init board_setup(void) | |||
56 | sys_clksrc = sys_freqctrl = pin_func = 0; | 56 | sys_clksrc = sys_freqctrl = pin_func = 0; |
57 | /* Set AUX clock to 12 MHz * 8 = 96 MHz */ | 57 | /* Set AUX clock to 12 MHz * 8 = 96 MHz */ |
58 | au_writel(8, SYS_AUXPLL); | 58 | au_writel(8, SYS_AUXPLL); |
59 | au_writel(0, SYS_PINSTATERD); | 59 | alchemy_gpio1_input_enable(); |
60 | udelay(100); | 60 | udelay(100); |
61 | 61 | ||
62 | /* GPIO201 is input for PCMCIA card detect */ | 62 | /* GPIO201 is input for PCMCIA card detect */ |
diff --git a/arch/mips/alchemy/devboards/prom.c b/arch/mips/alchemy/devboards/prom.c index baeb21385058..e5306b56da6d 100644 --- a/arch/mips/alchemy/devboards/prom.c +++ b/arch/mips/alchemy/devboards/prom.c | |||
@@ -62,5 +62,5 @@ void __init prom_init(void) | |||
62 | 62 | ||
63 | void prom_putchar(unsigned char c) | 63 | void prom_putchar(unsigned char c) |
64 | { | 64 | { |
65 | alchemy_uart_putchar(UART0_PHYS_ADDR, c); | 65 | alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); |
66 | } | 66 | } |
diff --git a/arch/mips/alchemy/gpr/board_setup.c b/arch/mips/alchemy/gpr/board_setup.c index ad2e3f137933..5f8f0691ed2d 100644 --- a/arch/mips/alchemy/gpr/board_setup.c +++ b/arch/mips/alchemy/gpr/board_setup.c | |||
@@ -36,9 +36,6 @@ | |||
36 | 36 | ||
37 | #include <prom.h> | 37 | #include <prom.h> |
38 | 38 | ||
39 | #define UART1_ADDR KSEG1ADDR(UART1_PHYS_ADDR) | ||
40 | #define UART3_ADDR KSEG1ADDR(UART3_PHYS_ADDR) | ||
41 | |||
42 | char irq_tab_alchemy[][5] __initdata = { | 39 | char irq_tab_alchemy[][5] __initdata = { |
43 | [0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, | 40 | [0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, |
44 | }; | 41 | }; |
@@ -67,18 +64,15 @@ static void gpr_power_off(void) | |||
67 | 64 | ||
68 | void __init board_setup(void) | 65 | void __init board_setup(void) |
69 | { | 66 | { |
70 | printk(KERN_INFO "Tarpeze ITS GPR board\n"); | 67 | printk(KERN_INFO "Trapeze ITS GPR board\n"); |
71 | 68 | ||
72 | pm_power_off = gpr_power_off; | 69 | pm_power_off = gpr_power_off; |
73 | _machine_halt = gpr_power_off; | 70 | _machine_halt = gpr_power_off; |
74 | _machine_restart = gpr_reset; | 71 | _machine_restart = gpr_reset; |
75 | 72 | ||
76 | /* Enable UART3 */ | 73 | /* Enable UART1/3 */ |
77 | au_writel(0x1, UART3_ADDR + UART_MOD_CNTRL);/* clock enable (CE) */ | 74 | alchemy_uart_enable(AU1000_UART3_PHYS_ADDR); |
78 | au_writel(0x3, UART3_ADDR + UART_MOD_CNTRL); /* CE and "enable" */ | 75 | alchemy_uart_enable(AU1000_UART1_PHYS_ADDR); |
79 | /* Enable UART1 */ | ||
80 | au_writel(0x1, UART1_ADDR + UART_MOD_CNTRL); /* clock enable (CE) */ | ||
81 | au_writel(0x3, UART1_ADDR + UART_MOD_CNTRL); /* CE and "enable" */ | ||
82 | 76 | ||
83 | /* Take away Reset of UMTS-card */ | 77 | /* Take away Reset of UMTS-card */ |
84 | alchemy_gpio_direction_output(215, 1); | 78 | alchemy_gpio_direction_output(215, 1); |
diff --git a/arch/mips/alchemy/gpr/init.c b/arch/mips/alchemy/gpr/init.c index f044f4c541d7..229aafae680c 100644 --- a/arch/mips/alchemy/gpr/init.c +++ b/arch/mips/alchemy/gpr/init.c | |||
@@ -59,5 +59,5 @@ void __init prom_init(void) | |||
59 | 59 | ||
60 | void prom_putchar(unsigned char c) | 60 | void prom_putchar(unsigned char c) |
61 | { | 61 | { |
62 | alchemy_uart_putchar(UART0_PHYS_ADDR, c); | 62 | alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); |
63 | } | 63 | } |
diff --git a/arch/mips/alchemy/mtx-1/board_setup.c b/arch/mips/alchemy/mtx-1/board_setup.c index cf436ab679ae..3ae984cf98cf 100644 --- a/arch/mips/alchemy/mtx-1/board_setup.c +++ b/arch/mips/alchemy/mtx-1/board_setup.c | |||
@@ -87,7 +87,7 @@ void __init board_setup(void) | |||
87 | au_writel(SYS_PF_NI2, SYS_PINFUNC); | 87 | au_writel(SYS_PF_NI2, SYS_PINFUNC); |
88 | 88 | ||
89 | /* Initialize GPIO */ | 89 | /* Initialize GPIO */ |
90 | au_writel(0xFFFFFFFF, SYS_TRIOUTCLR); | 90 | au_writel(~0, KSEG1ADDR(AU1000_SYS_PHYS_ADDR) + SYS_TRIOUTCLR); |
91 | alchemy_gpio_direction_output(0, 0); /* Disable M66EN (PCI 66MHz) */ | 91 | alchemy_gpio_direction_output(0, 0); /* Disable M66EN (PCI 66MHz) */ |
92 | alchemy_gpio_direction_output(3, 1); /* Disable PCI CLKRUN# */ | 92 | alchemy_gpio_direction_output(3, 1); /* Disable PCI CLKRUN# */ |
93 | alchemy_gpio_direction_output(1, 1); /* Enable EXT_IO3 */ | 93 | alchemy_gpio_direction_output(1, 1); /* Enable EXT_IO3 */ |
diff --git a/arch/mips/alchemy/mtx-1/init.c b/arch/mips/alchemy/mtx-1/init.c index f8d25575fa05..2e81cc7f3422 100644 --- a/arch/mips/alchemy/mtx-1/init.c +++ b/arch/mips/alchemy/mtx-1/init.c | |||
@@ -62,5 +62,5 @@ void __init prom_init(void) | |||
62 | 62 | ||
63 | void prom_putchar(unsigned char c) | 63 | void prom_putchar(unsigned char c) |
64 | { | 64 | { |
65 | alchemy_uart_putchar(UART0_PHYS_ADDR, c); | 65 | alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); |
66 | } | 66 | } |
diff --git a/arch/mips/alchemy/mtx-1/platform.c b/arch/mips/alchemy/mtx-1/platform.c index 956f946218c5..55628e390fd7 100644 --- a/arch/mips/alchemy/mtx-1/platform.c +++ b/arch/mips/alchemy/mtx-1/platform.c | |||
@@ -53,8 +53,8 @@ static struct platform_device mtx1_button = { | |||
53 | 53 | ||
54 | static struct resource mtx1_wdt_res[] = { | 54 | static struct resource mtx1_wdt_res[] = { |
55 | [0] = { | 55 | [0] = { |
56 | .start = 15, | 56 | .start = 215, |
57 | .end = 15, | 57 | .end = 215, |
58 | .name = "mtx1-wdt-gpio", | 58 | .name = "mtx1-wdt-gpio", |
59 | .flags = IORESOURCE_IRQ, | 59 | .flags = IORESOURCE_IRQ, |
60 | } | 60 | } |
diff --git a/arch/mips/alchemy/xxs1500/board_setup.c b/arch/mips/alchemy/xxs1500/board_setup.c index febfb0fb0896..81e57fad07ab 100644 --- a/arch/mips/alchemy/xxs1500/board_setup.c +++ b/arch/mips/alchemy/xxs1500/board_setup.c | |||
@@ -66,13 +66,10 @@ void __init board_setup(void) | |||
66 | au_writel(pin_func, SYS_PINFUNC); | 66 | au_writel(pin_func, SYS_PINFUNC); |
67 | 67 | ||
68 | /* Enable UART */ | 68 | /* Enable UART */ |
69 | au_writel(0x01, UART3_ADDR + UART_MOD_CNTRL); /* clock enable (CE) */ | 69 | alchemy_uart_enable(AU1000_UART3_PHYS_ADDR); |
70 | mdelay(10); | 70 | /* Enable DTR (MCR bit 0) = USB power up */ |
71 | au_writel(0x03, UART3_ADDR + UART_MOD_CNTRL); /* CE and "enable" */ | 71 | __raw_writel(1, (void __iomem *)KSEG1ADDR(AU1000_UART3_PHYS_ADDR + 0x18)); |
72 | mdelay(10); | 72 | wmb(); |
73 | |||
74 | /* Enable DTR = USB power up */ | ||
75 | au_writel(0x01, UART3_ADDR + UART_MCR); /* UART_MCR_DTR is 0x01??? */ | ||
76 | 73 | ||
77 | #ifdef CONFIG_PCI | 74 | #ifdef CONFIG_PCI |
78 | #if defined(__MIPSEB__) | 75 | #if defined(__MIPSEB__) |
diff --git a/arch/mips/alchemy/xxs1500/init.c b/arch/mips/alchemy/xxs1500/init.c index 34a90a4bb6f4..0ee02cfa989d 100644 --- a/arch/mips/alchemy/xxs1500/init.c +++ b/arch/mips/alchemy/xxs1500/init.c | |||
@@ -59,5 +59,5 @@ void __init prom_init(void) | |||
59 | 59 | ||
60 | void prom_putchar(unsigned char c) | 60 | void prom_putchar(unsigned char c) |
61 | { | 61 | { |
62 | alchemy_uart_putchar(UART0_PHYS_ADDR, c); | 62 | alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); |
63 | } | 63 | } |
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index e5b6615731e5..54db815bc86c 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2005 Broadcom Corporation | 4 | * Copyright (C) 2005 Broadcom Corporation |
5 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | 5 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> |
6 | * Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de> | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
@@ -23,7 +24,7 @@ | |||
23 | static char nvram_buf[NVRAM_SPACE]; | 24 | static char nvram_buf[NVRAM_SPACE]; |
24 | 25 | ||
25 | /* Probe for NVRAM header */ | 26 | /* Probe for NVRAM header */ |
26 | static void __init early_nvram_init(void) | 27 | static void early_nvram_init(void) |
27 | { | 28 | { |
28 | struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore; | 29 | struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore; |
29 | struct nvram_header *header; | 30 | struct nvram_header *header; |
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index c95f90bf734c..73b529b57433 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | 3 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> |
4 | * Copyright (C) 2006 Michael Buesch <mb@bu3sch.de> | 4 | * Copyright (C) 2006 Michael Buesch <mb@bu3sch.de> |
5 | * Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org> | 5 | * Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org> |
6 | * Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de> | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
@@ -57,10 +58,49 @@ static void bcm47xx_machine_halt(void) | |||
57 | } | 58 | } |
58 | 59 | ||
59 | #define READ_FROM_NVRAM(_outvar, name, buf) \ | 60 | #define READ_FROM_NVRAM(_outvar, name, buf) \ |
60 | if (nvram_getenv(name, buf, sizeof(buf)) >= 0)\ | 61 | if (nvram_getprefix(prefix, name, buf, sizeof(buf)) >= 0)\ |
61 | sprom->_outvar = simple_strtoul(buf, NULL, 0); | 62 | sprom->_outvar = simple_strtoul(buf, NULL, 0); |
62 | 63 | ||
63 | static void bcm47xx_fill_sprom(struct ssb_sprom *sprom) | 64 | #define READ_FROM_NVRAM2(_outvar, name1, name2, buf) \ |
65 | if (nvram_getprefix(prefix, name1, buf, sizeof(buf)) >= 0 || \ | ||
66 | nvram_getprefix(prefix, name2, buf, sizeof(buf)) >= 0)\ | ||
67 | sprom->_outvar = simple_strtoul(buf, NULL, 0); | ||
68 | |||
69 | static inline int nvram_getprefix(const char *prefix, char *name, | ||
70 | char *buf, int len) | ||
71 | { | ||
72 | if (prefix) { | ||
73 | char key[100]; | ||
74 | |||
75 | snprintf(key, sizeof(key), "%s%s", prefix, name); | ||
76 | return nvram_getenv(key, buf, len); | ||
77 | } | ||
78 | |||
79 | return nvram_getenv(name, buf, len); | ||
80 | } | ||
81 | |||
82 | static u32 nvram_getu32(const char *name, char *buf, int len) | ||
83 | { | ||
84 | int rv; | ||
85 | char key[100]; | ||
86 | u16 var0, var1; | ||
87 | |||
88 | snprintf(key, sizeof(key), "%s0", name); | ||
89 | rv = nvram_getenv(key, buf, len); | ||
90 | /* return 0 here so this looks like unset */ | ||
91 | if (rv < 0) | ||
92 | return 0; | ||
93 | var0 = simple_strtoul(buf, NULL, 0); | ||
94 | |||
95 | snprintf(key, sizeof(key), "%s1", name); | ||
96 | rv = nvram_getenv(key, buf, len); | ||
97 | if (rv < 0) | ||
98 | return 0; | ||
99 | var1 = simple_strtoul(buf, NULL, 0); | ||
100 | return var1 << 16 | var0; | ||
101 | } | ||
102 | |||
103 | static void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix) | ||
64 | { | 104 | { |
65 | char buf[100]; | 105 | char buf[100]; |
66 | u32 boardflags; | 106 | u32 boardflags; |
@@ -69,11 +109,12 @@ static void bcm47xx_fill_sprom(struct ssb_sprom *sprom) | |||
69 | 109 | ||
70 | sprom->revision = 1; /* Fallback: Old hardware does not define this. */ | 110 | sprom->revision = 1; /* Fallback: Old hardware does not define this. */ |
71 | READ_FROM_NVRAM(revision, "sromrev", buf); | 111 | READ_FROM_NVRAM(revision, "sromrev", buf); |
72 | if (nvram_getenv("il0macaddr", buf, sizeof(buf)) >= 0) | 112 | if (nvram_getprefix(prefix, "il0macaddr", buf, sizeof(buf)) >= 0 || |
113 | nvram_getprefix(prefix, "macaddr", buf, sizeof(buf)) >= 0) | ||
73 | nvram_parse_macaddr(buf, sprom->il0mac); | 114 | nvram_parse_macaddr(buf, sprom->il0mac); |
74 | if (nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0) | 115 | if (nvram_getprefix(prefix, "et0macaddr", buf, sizeof(buf)) >= 0) |
75 | nvram_parse_macaddr(buf, sprom->et0mac); | 116 | nvram_parse_macaddr(buf, sprom->et0mac); |
76 | if (nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0) | 117 | if (nvram_getprefix(prefix, "et1macaddr", buf, sizeof(buf)) >= 0) |
77 | nvram_parse_macaddr(buf, sprom->et1mac); | 118 | nvram_parse_macaddr(buf, sprom->et1mac); |
78 | READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf); | 119 | READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf); |
79 | READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf); | 120 | READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf); |
@@ -95,20 +136,36 @@ static void bcm47xx_fill_sprom(struct ssb_sprom *sprom) | |||
95 | READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf); | 136 | READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf); |
96 | READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf); | 137 | READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf); |
97 | READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf); | 138 | READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf); |
98 | READ_FROM_NVRAM(gpio0, "wl0gpio0", buf); | 139 | READ_FROM_NVRAM2(gpio0, "ledbh0", "wl0gpio0", buf); |
99 | READ_FROM_NVRAM(gpio1, "wl0gpio1", buf); | 140 | READ_FROM_NVRAM2(gpio1, "ledbh1", "wl0gpio1", buf); |
100 | READ_FROM_NVRAM(gpio2, "wl0gpio2", buf); | 141 | READ_FROM_NVRAM2(gpio2, "ledbh2", "wl0gpio2", buf); |
101 | READ_FROM_NVRAM(gpio3, "wl0gpio3", buf); | 142 | READ_FROM_NVRAM2(gpio3, "ledbh3", "wl0gpio3", buf); |
102 | READ_FROM_NVRAM(maxpwr_bg, "pa0maxpwr", buf); | 143 | READ_FROM_NVRAM2(maxpwr_bg, "maxp2ga0", "pa0maxpwr", buf); |
103 | READ_FROM_NVRAM(maxpwr_al, "pa1lomaxpwr", buf); | 144 | READ_FROM_NVRAM2(maxpwr_al, "maxp5gla0", "pa1lomaxpwr", buf); |
104 | READ_FROM_NVRAM(maxpwr_a, "pa1maxpwr", buf); | 145 | READ_FROM_NVRAM2(maxpwr_a, "maxp5ga0", "pa1maxpwr", buf); |
105 | READ_FROM_NVRAM(maxpwr_ah, "pa1himaxpwr", buf); | 146 | READ_FROM_NVRAM2(maxpwr_ah, "maxp5gha0", "pa1himaxpwr", buf); |
106 | READ_FROM_NVRAM(itssi_a, "pa1itssit", buf); | 147 | READ_FROM_NVRAM2(itssi_bg, "itt5ga0", "pa0itssit", buf); |
107 | READ_FROM_NVRAM(itssi_bg, "pa0itssit", buf); | 148 | READ_FROM_NVRAM2(itssi_a, "itt2ga0", "pa1itssit", buf); |
108 | READ_FROM_NVRAM(tri2g, "tri2g", buf); | 149 | READ_FROM_NVRAM(tri2g, "tri2g", buf); |
109 | READ_FROM_NVRAM(tri5gl, "tri5gl", buf); | 150 | READ_FROM_NVRAM(tri5gl, "tri5gl", buf); |
110 | READ_FROM_NVRAM(tri5g, "tri5g", buf); | 151 | READ_FROM_NVRAM(tri5g, "tri5g", buf); |
111 | READ_FROM_NVRAM(tri5gh, "tri5gh", buf); | 152 | READ_FROM_NVRAM(tri5gh, "tri5gh", buf); |
153 | READ_FROM_NVRAM(txpid2g[0], "txpid2ga0", buf); | ||
154 | READ_FROM_NVRAM(txpid2g[1], "txpid2ga1", buf); | ||
155 | READ_FROM_NVRAM(txpid2g[2], "txpid2ga2", buf); | ||
156 | READ_FROM_NVRAM(txpid2g[3], "txpid2ga3", buf); | ||
157 | READ_FROM_NVRAM(txpid5g[0], "txpid5ga0", buf); | ||
158 | READ_FROM_NVRAM(txpid5g[1], "txpid5ga1", buf); | ||
159 | READ_FROM_NVRAM(txpid5g[2], "txpid5ga2", buf); | ||
160 | READ_FROM_NVRAM(txpid5g[3], "txpid5ga3", buf); | ||
161 | READ_FROM_NVRAM(txpid5gl[0], "txpid5gla0", buf); | ||
162 | READ_FROM_NVRAM(txpid5gl[1], "txpid5gla1", buf); | ||
163 | READ_FROM_NVRAM(txpid5gl[2], "txpid5gla2", buf); | ||
164 | READ_FROM_NVRAM(txpid5gl[3], "txpid5gla3", buf); | ||
165 | READ_FROM_NVRAM(txpid5gh[0], "txpid5gha0", buf); | ||
166 | READ_FROM_NVRAM(txpid5gh[1], "txpid5gha1", buf); | ||
167 | READ_FROM_NVRAM(txpid5gh[2], "txpid5gha2", buf); | ||
168 | READ_FROM_NVRAM(txpid5gh[3], "txpid5gha3", buf); | ||
112 | READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf); | 169 | READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf); |
113 | READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf); | 170 | READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf); |
114 | READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf); | 171 | READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf); |
@@ -120,19 +177,27 @@ static void bcm47xx_fill_sprom(struct ssb_sprom *sprom) | |||
120 | READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf); | 177 | READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf); |
121 | READ_FROM_NVRAM(bxa5g, "bxa5g", buf); | 178 | READ_FROM_NVRAM(bxa5g, "bxa5g", buf); |
122 | READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf); | 179 | READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf); |
123 | READ_FROM_NVRAM(ofdm2gpo, "ofdm2gpo", buf); | ||
124 | READ_FROM_NVRAM(ofdm5glpo, "ofdm5glpo", buf); | ||
125 | READ_FROM_NVRAM(ofdm5gpo, "ofdm5gpo", buf); | ||
126 | READ_FROM_NVRAM(ofdm5ghpo, "ofdm5ghpo", buf); | ||
127 | 180 | ||
128 | if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0) { | 181 | sprom->ofdm2gpo = nvram_getu32("ofdm2gpo", buf, sizeof(buf)); |
182 | sprom->ofdm5glpo = nvram_getu32("ofdm5glpo", buf, sizeof(buf)); | ||
183 | sprom->ofdm5gpo = nvram_getu32("ofdm5gpo", buf, sizeof(buf)); | ||
184 | sprom->ofdm5ghpo = nvram_getu32("ofdm5ghpo", buf, sizeof(buf)); | ||
185 | |||
186 | READ_FROM_NVRAM(antenna_gain.ghz24.a0, "ag0", buf); | ||
187 | READ_FROM_NVRAM(antenna_gain.ghz24.a1, "ag1", buf); | ||
188 | READ_FROM_NVRAM(antenna_gain.ghz24.a2, "ag2", buf); | ||
189 | READ_FROM_NVRAM(antenna_gain.ghz24.a3, "ag3", buf); | ||
190 | memcpy(&sprom->antenna_gain.ghz5, &sprom->antenna_gain.ghz24, | ||
191 | sizeof(sprom->antenna_gain.ghz5)); | ||
192 | |||
193 | if (nvram_getprefix(prefix, "boardflags", buf, sizeof(buf)) >= 0) { | ||
129 | boardflags = simple_strtoul(buf, NULL, 0); | 194 | boardflags = simple_strtoul(buf, NULL, 0); |
130 | if (boardflags) { | 195 | if (boardflags) { |
131 | sprom->boardflags_lo = (boardflags & 0x0000FFFFU); | 196 | sprom->boardflags_lo = (boardflags & 0x0000FFFFU); |
132 | sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16; | 197 | sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16; |
133 | } | 198 | } |
134 | } | 199 | } |
135 | if (nvram_getenv("boardflags2", buf, sizeof(buf)) >= 0) { | 200 | if (nvram_getprefix(prefix, "boardflags2", buf, sizeof(buf)) >= 0) { |
136 | boardflags = simple_strtoul(buf, NULL, 0); | 201 | boardflags = simple_strtoul(buf, NULL, 0); |
137 | if (boardflags) { | 202 | if (boardflags) { |
138 | sprom->boardflags2_lo = (boardflags & 0x0000FFFFU); | 203 | sprom->boardflags2_lo = (boardflags & 0x0000FFFFU); |
@@ -141,6 +206,22 @@ static void bcm47xx_fill_sprom(struct ssb_sprom *sprom) | |||
141 | } | 206 | } |
142 | } | 207 | } |
143 | 208 | ||
209 | int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out) | ||
210 | { | ||
211 | char prefix[10]; | ||
212 | |||
213 | if (bus->bustype == SSB_BUSTYPE_PCI) { | ||
214 | snprintf(prefix, sizeof(prefix), "pci/%u/%u/", | ||
215 | bus->host_pci->bus->number + 1, | ||
216 | PCI_SLOT(bus->host_pci->devfn)); | ||
217 | bcm47xx_fill_sprom(out, prefix); | ||
218 | return 0; | ||
219 | } else { | ||
220 | printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n"); | ||
221 | return -EINVAL; | ||
222 | } | ||
223 | } | ||
224 | |||
144 | static int bcm47xx_get_invariants(struct ssb_bus *bus, | 225 | static int bcm47xx_get_invariants(struct ssb_bus *bus, |
145 | struct ssb_init_invariants *iv) | 226 | struct ssb_init_invariants *iv) |
146 | { | 227 | { |
@@ -158,7 +239,7 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus, | |||
158 | if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0) | 239 | if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0) |
159 | iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0); | 240 | iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0); |
160 | 241 | ||
161 | bcm47xx_fill_sprom(&iv->sprom); | 242 | bcm47xx_fill_sprom(&iv->sprom, NULL); |
162 | 243 | ||
163 | if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0) | 244 | if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0) |
164 | iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10); | 245 | iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10); |
@@ -172,6 +253,11 @@ void __init plat_mem_setup(void) | |||
172 | char buf[100]; | 253 | char buf[100]; |
173 | struct ssb_mipscore *mcore; | 254 | struct ssb_mipscore *mcore; |
174 | 255 | ||
256 | err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom); | ||
257 | if (err) | ||
258 | printk(KERN_WARNING "bcm47xx: someone else already registered" | ||
259 | " a ssb SPROM callback handler (err %d)\n", err); | ||
260 | |||
175 | err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, | 261 | err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, |
176 | bcm47xx_get_invariants); | 262 | bcm47xx_get_invariants); |
177 | if (err) | 263 | if (err) |
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index 8dba8cfb752f..40b223b603be 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c | |||
@@ -643,6 +643,17 @@ static struct ssb_sprom bcm63xx_sprom = { | |||
643 | .boardflags_lo = 0x2848, | 643 | .boardflags_lo = 0x2848, |
644 | .boardflags_hi = 0x0000, | 644 | .boardflags_hi = 0x0000, |
645 | }; | 645 | }; |
646 | |||
647 | int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out) | ||
648 | { | ||
649 | if (bus->bustype == SSB_BUSTYPE_PCI) { | ||
650 | memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom)); | ||
651 | return 0; | ||
652 | } else { | ||
653 | printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n"); | ||
654 | return -EINVAL; | ||
655 | } | ||
656 | } | ||
646 | #endif | 657 | #endif |
647 | 658 | ||
648 | /* | 659 | /* |
@@ -793,8 +804,9 @@ void __init board_prom_init(void) | |||
793 | if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { | 804 | if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { |
794 | memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); | 805 | memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); |
795 | memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); | 806 | memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); |
796 | if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0) | 807 | if (ssb_arch_register_fallback_sprom( |
797 | printk(KERN_ERR "failed to register fallback SPROM\n"); | 808 | &bcm63xx_get_fallback_sprom) < 0) |
809 | printk(KERN_ERR PFX "failed to register fallback SPROM\n"); | ||
798 | } | 810 | } |
799 | #endif | 811 | #endif |
800 | } | 812 | } |
diff --git a/arch/mips/boot/compressed/uart-alchemy.c b/arch/mips/boot/compressed/uart-alchemy.c index 1bff22fa089b..eb063e6dead9 100644 --- a/arch/mips/boot/compressed/uart-alchemy.c +++ b/arch/mips/boot/compressed/uart-alchemy.c | |||
@@ -3,5 +3,5 @@ | |||
3 | void putc(char c) | 3 | void putc(char c) |
4 | { | 4 | { |
5 | /* all current (Jan. 2010) in-kernel boards */ | 5 | /* all current (Jan. 2010) in-kernel boards */ |
6 | alchemy_uart_putchar(UART0_PHYS_ADDR, c); | 6 | alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); |
7 | } | 7 | } |
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 0707fae3f0ee..2d9028f1474c 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c | |||
@@ -288,7 +288,6 @@ void octeon_user_io_init(void) | |||
288 | union octeon_cvmemctl cvmmemctl; | 288 | union octeon_cvmemctl cvmmemctl; |
289 | union cvmx_iob_fau_timeout fau_timeout; | 289 | union cvmx_iob_fau_timeout fau_timeout; |
290 | union cvmx_pow_nw_tim nm_tim; | 290 | union cvmx_pow_nw_tim nm_tim; |
291 | uint64_t cvmctl; | ||
292 | 291 | ||
293 | /* Get the current settings for CP0_CVMMEMCTL_REG */ | 292 | /* Get the current settings for CP0_CVMMEMCTL_REG */ |
294 | cvmmemctl.u64 = read_c0_cvmmemctl(); | 293 | cvmmemctl.u64 = read_c0_cvmmemctl(); |
@@ -392,12 +391,6 @@ void octeon_user_io_init(void) | |||
392 | CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE, | 391 | CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE, |
393 | CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128); | 392 | CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128); |
394 | 393 | ||
395 | /* Move the performance counter interrupts to IRQ 6 */ | ||
396 | cvmctl = read_c0_cvmctl(); | ||
397 | cvmctl &= ~(7 << 7); | ||
398 | cvmctl |= 6 << 7; | ||
399 | write_c0_cvmctl(cvmctl); | ||
400 | |||
401 | /* Set a default for the hardware timeouts */ | 394 | /* Set a default for the hardware timeouts */ |
402 | fau_timeout.u64 = 0; | 395 | fau_timeout.u64 = 0; |
403 | fau_timeout.s.tout_val = 0xfff; | 396 | fau_timeout.s.tout_val = 0xfff; |
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index ba78b21cc8d0..716fae6f941a 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c | |||
@@ -37,7 +37,7 @@ static irqreturn_t mailbox_interrupt(int irq, void *dev_id) | |||
37 | uint64_t action; | 37 | uint64_t action; |
38 | 38 | ||
39 | /* Load the mailbox register to figure out what we're supposed to do */ | 39 | /* Load the mailbox register to figure out what we're supposed to do */ |
40 | action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(coreid)); | 40 | action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(coreid)) & 0xffff; |
41 | 41 | ||
42 | /* Clear the mailbox to clear the interrupt */ | 42 | /* Clear the mailbox to clear the interrupt */ |
43 | cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), action); | 43 | cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), action); |
@@ -200,16 +200,15 @@ void octeon_prepare_cpus(unsigned int max_cpus) | |||
200 | if (labi->labi_signature != LABI_SIGNATURE) | 200 | if (labi->labi_signature != LABI_SIGNATURE) |
201 | panic("The bootloader version on this board is incorrect."); | 201 | panic("The bootloader version on this board is incorrect."); |
202 | #endif | 202 | #endif |
203 | 203 | /* | |
204 | cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffffffff); | 204 | * Only the low order mailbox bits are used for IPIs, leave |
205 | * the other bits alone. | ||
206 | */ | ||
207 | cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffff); | ||
205 | if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED, | 208 | if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED, |
206 | "mailbox0", mailbox_interrupt)) { | 209 | "SMP-IPI", mailbox_interrupt)) { |
207 | panic("Cannot request_irq(OCTEON_IRQ_MBOX0)\n"); | 210 | panic("Cannot request_irq(OCTEON_IRQ_MBOX0)\n"); |
208 | } | 211 | } |
209 | if (request_irq(OCTEON_IRQ_MBOX1, mailbox_interrupt, IRQF_DISABLED, | ||
210 | "mailbox1", mailbox_interrupt)) { | ||
211 | panic("Cannot request_irq(OCTEON_IRQ_MBOX1)\n"); | ||
212 | } | ||
213 | } | 212 | } |
214 | 213 | ||
215 | /** | 214 | /** |
diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig index 167c1d07b809..b6acd2f256b6 100644 --- a/arch/mips/configs/lemote2f_defconfig +++ b/arch/mips/configs/lemote2f_defconfig | |||
@@ -86,8 +86,8 @@ CONFIG_NET_SCHED=y | |||
86 | CONFIG_NET_EMATCH=y | 86 | CONFIG_NET_EMATCH=y |
87 | CONFIG_NET_CLS_ACT=y | 87 | CONFIG_NET_CLS_ACT=y |
88 | CONFIG_BT=m | 88 | CONFIG_BT=m |
89 | CONFIG_BT_L2CAP=m | 89 | CONFIG_BT_L2CAP=y |
90 | CONFIG_BT_SCO=m | 90 | CONFIG_BT_SCO=y |
91 | CONFIG_BT_RFCOMM=m | 91 | CONFIG_BT_RFCOMM=m |
92 | CONFIG_BT_RFCOMM_TTY=y | 92 | CONFIG_BT_RFCOMM_TTY=y |
93 | CONFIG_BT_BNEP=m | 93 | CONFIG_BT_BNEP=m |
@@ -329,7 +329,7 @@ CONFIG_USB_LED=m | |||
329 | CONFIG_USB_GADGET=m | 329 | CONFIG_USB_GADGET=m |
330 | CONFIG_USB_GADGET_M66592=y | 330 | CONFIG_USB_GADGET_M66592=y |
331 | CONFIG_MMC=m | 331 | CONFIG_MMC=m |
332 | CONFIG_LEDS_CLASS=m | 332 | CONFIG_LEDS_CLASS=y |
333 | CONFIG_STAGING=y | 333 | CONFIG_STAGING=y |
334 | # CONFIG_STAGING_EXCLUDE_BUILD is not set | 334 | # CONFIG_STAGING_EXCLUDE_BUILD is not set |
335 | CONFIG_FB_SM7XX=y | 335 | CONFIG_FB_SM7XX=y |
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 7270f3183bda..5527abbb7dea 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig | |||
@@ -374,7 +374,7 @@ CONFIG_FB_CIRRUS=y | |||
374 | # CONFIG_VGA_CONSOLE is not set | 374 | # CONFIG_VGA_CONSOLE is not set |
375 | CONFIG_FRAMEBUFFER_CONSOLE=y | 375 | CONFIG_FRAMEBUFFER_CONSOLE=y |
376 | CONFIG_HID=m | 376 | CONFIG_HID=m |
377 | CONFIG_LEDS_CLASS=m | 377 | CONFIG_LEDS_CLASS=y |
378 | CONFIG_LEDS_TRIGGER_TIMER=m | 378 | CONFIG_LEDS_TRIGGER_TIMER=m |
379 | CONFIG_LEDS_TRIGGER_IDE_DISK=y | 379 | CONFIG_LEDS_TRIGGER_IDE_DISK=y |
380 | CONFIG_LEDS_TRIGGER_HEARTBEAT=m | 380 | CONFIG_LEDS_TRIGGER_HEARTBEAT=m |
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index a97a42c6b2c8..37862b2ce363 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig | |||
@@ -225,8 +225,8 @@ CONFIG_TOSHIBA_FIR=m | |||
225 | CONFIG_VLSI_FIR=m | 225 | CONFIG_VLSI_FIR=m |
226 | CONFIG_MCS_FIR=m | 226 | CONFIG_MCS_FIR=m |
227 | CONFIG_BT=m | 227 | CONFIG_BT=m |
228 | CONFIG_BT_L2CAP=m | 228 | CONFIG_BT_L2CAP=y |
229 | CONFIG_BT_SCO=m | 229 | CONFIG_BT_SCO=y |
230 | CONFIG_BT_RFCOMM=m | 230 | CONFIG_BT_RFCOMM=m |
231 | CONFIG_BT_RFCOMM_TTY=y | 231 | CONFIG_BT_RFCOMM_TTY=y |
232 | CONFIG_BT_BNEP=m | 232 | CONFIG_BT_BNEP=m |
diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig new file mode 100644 index 000000000000..e4b399fdaa61 --- /dev/null +++ b/arch/mips/configs/nlm_xlr_defconfig | |||
@@ -0,0 +1,574 @@ | |||
1 | CONFIG_NLM_XLR_BOARD=y | ||
2 | CONFIG_HIGHMEM=y | ||
3 | CONFIG_KSM=y | ||
4 | CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 | ||
5 | CONFIG_SMP=y | ||
6 | CONFIG_NO_HZ=y | ||
7 | CONFIG_HIGH_RES_TIMERS=y | ||
8 | CONFIG_PREEMPT_VOLUNTARY=y | ||
9 | CONFIG_KEXEC=y | ||
10 | CONFIG_EXPERIMENTAL=y | ||
11 | CONFIG_CROSS_COMPILE="mips64-unknown-linux-gnu-" | ||
12 | # CONFIG_LOCALVERSION_AUTO is not set | ||
13 | CONFIG_SYSVIPC=y | ||
14 | CONFIG_POSIX_MQUEUE=y | ||
15 | CONFIG_BSD_PROCESS_ACCT=y | ||
16 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
17 | CONFIG_TASKSTATS=y | ||
18 | CONFIG_TASK_DELAY_ACCT=y | ||
19 | CONFIG_TASK_XACCT=y | ||
20 | CONFIG_TASK_IO_ACCOUNTING=y | ||
21 | CONFIG_AUDIT=y | ||
22 | CONFIG_NAMESPACES=y | ||
23 | CONFIG_SCHED_AUTOGROUP=y | ||
24 | CONFIG_BLK_DEV_INITRD=y | ||
25 | CONFIG_INITRAMFS_SOURCE="usr/dev_file_list usr/rootfs" | ||
26 | CONFIG_RD_BZIP2=y | ||
27 | CONFIG_RD_LZMA=y | ||
28 | CONFIG_INITRAMFS_COMPRESSION_GZIP=y | ||
29 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
30 | CONFIG_EXPERT=y | ||
31 | CONFIG_KALLSYMS_ALL=y | ||
32 | # CONFIG_ELF_CORE is not set | ||
33 | # CONFIG_PCSPKR_PLATFORM is not set | ||
34 | # CONFIG_PERF_EVENTS is not set | ||
35 | # CONFIG_COMPAT_BRK is not set | ||
36 | CONFIG_PROFILING=y | ||
37 | CONFIG_MODULES=y | ||
38 | CONFIG_MODULE_UNLOAD=y | ||
39 | CONFIG_MODVERSIONS=y | ||
40 | CONFIG_MODULE_SRCVERSION_ALL=y | ||
41 | CONFIG_BLK_DEV_INTEGRITY=y | ||
42 | CONFIG_BINFMT_MISC=m | ||
43 | CONFIG_PM_RUNTIME=y | ||
44 | CONFIG_PM_DEBUG=y | ||
45 | CONFIG_PACKET=y | ||
46 | CONFIG_UNIX=y | ||
47 | CONFIG_XFRM_USER=m | ||
48 | CONFIG_NET_KEY=m | ||
49 | CONFIG_INET=y | ||
50 | CONFIG_IP_MULTICAST=y | ||
51 | CONFIG_IP_ADVANCED_ROUTER=y | ||
52 | CONFIG_IP_MULTIPLE_TABLES=y | ||
53 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
54 | CONFIG_IP_ROUTE_VERBOSE=y | ||
55 | CONFIG_NET_IPIP=m | ||
56 | CONFIG_IP_MROUTE=y | ||
57 | CONFIG_IP_PIMSM_V1=y | ||
58 | CONFIG_IP_PIMSM_V2=y | ||
59 | CONFIG_SYN_COOKIES=y | ||
60 | CONFIG_INET_AH=m | ||
61 | CONFIG_INET_ESP=m | ||
62 | CONFIG_INET_IPCOMP=m | ||
63 | CONFIG_INET_XFRM_MODE_TRANSPORT=m | ||
64 | CONFIG_INET_XFRM_MODE_TUNNEL=m | ||
65 | CONFIG_INET_XFRM_MODE_BEET=m | ||
66 | CONFIG_TCP_CONG_ADVANCED=y | ||
67 | CONFIG_TCP_CONG_HSTCP=m | ||
68 | CONFIG_TCP_CONG_HYBLA=m | ||
69 | CONFIG_TCP_CONG_SCALABLE=m | ||
70 | CONFIG_TCP_CONG_LP=m | ||
71 | CONFIG_TCP_CONG_VENO=m | ||
72 | CONFIG_TCP_CONG_YEAH=m | ||
73 | CONFIG_TCP_CONG_ILLINOIS=m | ||
74 | CONFIG_TCP_MD5SIG=y | ||
75 | CONFIG_IPV6=y | ||
76 | CONFIG_IPV6_PRIVACY=y | ||
77 | CONFIG_INET6_AH=m | ||
78 | CONFIG_INET6_ESP=m | ||
79 | CONFIG_INET6_IPCOMP=m | ||
80 | CONFIG_INET6_XFRM_MODE_TRANSPORT=m | ||
81 | CONFIG_INET6_XFRM_MODE_TUNNEL=m | ||
82 | CONFIG_INET6_XFRM_MODE_BEET=m | ||
83 | CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m | ||
84 | CONFIG_IPV6_SIT=m | ||
85 | CONFIG_IPV6_TUNNEL=m | ||
86 | CONFIG_IPV6_MULTIPLE_TABLES=y | ||
87 | CONFIG_NETLABEL=y | ||
88 | CONFIG_NETFILTER=y | ||
89 | CONFIG_NF_CONNTRACK=m | ||
90 | CONFIG_NF_CONNTRACK_SECMARK=y | ||
91 | CONFIG_NF_CONNTRACK_EVENTS=y | ||
92 | CONFIG_NF_CT_PROTO_UDPLITE=m | ||
93 | CONFIG_NF_CONNTRACK_AMANDA=m | ||
94 | CONFIG_NF_CONNTRACK_FTP=m | ||
95 | CONFIG_NF_CONNTRACK_H323=m | ||
96 | CONFIG_NF_CONNTRACK_IRC=m | ||
97 | CONFIG_NF_CONNTRACK_NETBIOS_NS=m | ||
98 | CONFIG_NF_CONNTRACK_PPTP=m | ||
99 | CONFIG_NF_CONNTRACK_SANE=m | ||
100 | CONFIG_NF_CONNTRACK_SIP=m | ||
101 | CONFIG_NF_CONNTRACK_TFTP=m | ||
102 | CONFIG_NF_CT_NETLINK=m | ||
103 | CONFIG_NETFILTER_TPROXY=m | ||
104 | CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m | ||
105 | CONFIG_NETFILTER_XT_TARGET_CONNMARK=m | ||
106 | CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m | ||
107 | CONFIG_NETFILTER_XT_TARGET_DSCP=m | ||
108 | CONFIG_NETFILTER_XT_TARGET_MARK=m | ||
109 | CONFIG_NETFILTER_XT_TARGET_NFLOG=m | ||
110 | CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m | ||
111 | CONFIG_NETFILTER_XT_TARGET_NOTRACK=m | ||
112 | CONFIG_NETFILTER_XT_TARGET_TPROXY=m | ||
113 | CONFIG_NETFILTER_XT_TARGET_TRACE=m | ||
114 | CONFIG_NETFILTER_XT_TARGET_SECMARK=m | ||
115 | CONFIG_NETFILTER_XT_TARGET_TCPMSS=m | ||
116 | CONFIG_NETFILTER_XT_MATCH_CLUSTER=m | ||
117 | CONFIG_NETFILTER_XT_MATCH_COMMENT=m | ||
118 | CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m | ||
119 | CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m | ||
120 | CONFIG_NETFILTER_XT_MATCH_CONNMARK=m | ||
121 | CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m | ||
122 | CONFIG_NETFILTER_XT_MATCH_DSCP=m | ||
123 | CONFIG_NETFILTER_XT_MATCH_ESP=m | ||
124 | CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m | ||
125 | CONFIG_NETFILTER_XT_MATCH_HELPER=m | ||
126 | CONFIG_NETFILTER_XT_MATCH_IPRANGE=m | ||
127 | CONFIG_NETFILTER_XT_MATCH_LENGTH=m | ||
128 | CONFIG_NETFILTER_XT_MATCH_LIMIT=m | ||
129 | CONFIG_NETFILTER_XT_MATCH_MAC=m | ||
130 | CONFIG_NETFILTER_XT_MATCH_MARK=m | ||
131 | CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m | ||
132 | CONFIG_NETFILTER_XT_MATCH_OSF=m | ||
133 | CONFIG_NETFILTER_XT_MATCH_OWNER=m | ||
134 | CONFIG_NETFILTER_XT_MATCH_POLICY=m | ||
135 | CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m | ||
136 | CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m | ||
137 | CONFIG_NETFILTER_XT_MATCH_QUOTA=m | ||
138 | CONFIG_NETFILTER_XT_MATCH_RATEEST=m | ||
139 | CONFIG_NETFILTER_XT_MATCH_REALM=m | ||
140 | CONFIG_NETFILTER_XT_MATCH_RECENT=m | ||
141 | CONFIG_NETFILTER_XT_MATCH_SOCKET=m | ||
142 | CONFIG_NETFILTER_XT_MATCH_STATE=m | ||
143 | CONFIG_NETFILTER_XT_MATCH_STATISTIC=m | ||
144 | CONFIG_NETFILTER_XT_MATCH_STRING=m | ||
145 | CONFIG_NETFILTER_XT_MATCH_TCPMSS=m | ||
146 | CONFIG_NETFILTER_XT_MATCH_TIME=m | ||
147 | CONFIG_NETFILTER_XT_MATCH_U32=m | ||
148 | CONFIG_IP_VS=m | ||
149 | CONFIG_IP_VS_IPV6=y | ||
150 | CONFIG_IP_VS_PROTO_TCP=y | ||
151 | CONFIG_IP_VS_PROTO_UDP=y | ||
152 | CONFIG_IP_VS_PROTO_ESP=y | ||
153 | CONFIG_IP_VS_PROTO_AH=y | ||
154 | CONFIG_IP_VS_RR=m | ||
155 | CONFIG_IP_VS_WRR=m | ||
156 | CONFIG_IP_VS_LC=m | ||
157 | CONFIG_IP_VS_WLC=m | ||
158 | CONFIG_IP_VS_LBLC=m | ||
159 | CONFIG_IP_VS_LBLCR=m | ||
160 | CONFIG_IP_VS_DH=m | ||
161 | CONFIG_IP_VS_SH=m | ||
162 | CONFIG_IP_VS_SED=m | ||
163 | CONFIG_IP_VS_NQ=m | ||
164 | CONFIG_IP_VS_FTP=m | ||
165 | CONFIG_NF_CONNTRACK_IPV4=m | ||
166 | CONFIG_IP_NF_QUEUE=m | ||
167 | CONFIG_IP_NF_IPTABLES=m | ||
168 | CONFIG_IP_NF_MATCH_AH=m | ||
169 | CONFIG_IP_NF_MATCH_ECN=m | ||
170 | CONFIG_IP_NF_MATCH_TTL=m | ||
171 | CONFIG_IP_NF_FILTER=m | ||
172 | CONFIG_IP_NF_TARGET_REJECT=m | ||
173 | CONFIG_IP_NF_TARGET_LOG=m | ||
174 | CONFIG_IP_NF_TARGET_ULOG=m | ||
175 | CONFIG_NF_NAT=m | ||
176 | CONFIG_IP_NF_TARGET_MASQUERADE=m | ||
177 | CONFIG_IP_NF_TARGET_NETMAP=m | ||
178 | CONFIG_IP_NF_TARGET_REDIRECT=m | ||
179 | CONFIG_IP_NF_MANGLE=m | ||
180 | CONFIG_IP_NF_TARGET_CLUSTERIP=m | ||
181 | CONFIG_IP_NF_TARGET_ECN=m | ||
182 | CONFIG_IP_NF_TARGET_TTL=m | ||
183 | CONFIG_IP_NF_RAW=m | ||
184 | CONFIG_IP_NF_SECURITY=m | ||
185 | CONFIG_IP_NF_ARPTABLES=m | ||
186 | CONFIG_IP_NF_ARPFILTER=m | ||
187 | CONFIG_IP_NF_ARP_MANGLE=m | ||
188 | CONFIG_NF_CONNTRACK_IPV6=m | ||
189 | CONFIG_IP6_NF_QUEUE=m | ||
190 | CONFIG_IP6_NF_IPTABLES=m | ||
191 | CONFIG_IP6_NF_MATCH_AH=m | ||
192 | CONFIG_IP6_NF_MATCH_EUI64=m | ||
193 | CONFIG_IP6_NF_MATCH_FRAG=m | ||
194 | CONFIG_IP6_NF_MATCH_OPTS=m | ||
195 | CONFIG_IP6_NF_MATCH_HL=m | ||
196 | CONFIG_IP6_NF_MATCH_IPV6HEADER=m | ||
197 | CONFIG_IP6_NF_MATCH_MH=m | ||
198 | CONFIG_IP6_NF_MATCH_RT=m | ||
199 | CONFIG_IP6_NF_TARGET_HL=m | ||
200 | CONFIG_IP6_NF_TARGET_LOG=m | ||
201 | CONFIG_IP6_NF_FILTER=m | ||
202 | CONFIG_IP6_NF_TARGET_REJECT=m | ||
203 | CONFIG_IP6_NF_MANGLE=m | ||
204 | CONFIG_IP6_NF_RAW=m | ||
205 | CONFIG_IP6_NF_SECURITY=m | ||
206 | CONFIG_DECNET_NF_GRABULATOR=m | ||
207 | CONFIG_BRIDGE_NF_EBTABLES=m | ||
208 | CONFIG_BRIDGE_EBT_BROUTE=m | ||
209 | CONFIG_BRIDGE_EBT_T_FILTER=m | ||
210 | CONFIG_BRIDGE_EBT_T_NAT=m | ||
211 | CONFIG_BRIDGE_EBT_802_3=m | ||
212 | CONFIG_BRIDGE_EBT_AMONG=m | ||
213 | CONFIG_BRIDGE_EBT_ARP=m | ||
214 | CONFIG_BRIDGE_EBT_IP=m | ||
215 | CONFIG_BRIDGE_EBT_IP6=m | ||
216 | CONFIG_BRIDGE_EBT_LIMIT=m | ||
217 | CONFIG_BRIDGE_EBT_MARK=m | ||
218 | CONFIG_BRIDGE_EBT_PKTTYPE=m | ||
219 | CONFIG_BRIDGE_EBT_STP=m | ||
220 | CONFIG_BRIDGE_EBT_VLAN=m | ||
221 | CONFIG_BRIDGE_EBT_ARPREPLY=m | ||
222 | CONFIG_BRIDGE_EBT_DNAT=m | ||
223 | CONFIG_BRIDGE_EBT_MARK_T=m | ||
224 | CONFIG_BRIDGE_EBT_REDIRECT=m | ||
225 | CONFIG_BRIDGE_EBT_SNAT=m | ||
226 | CONFIG_BRIDGE_EBT_LOG=m | ||
227 | CONFIG_BRIDGE_EBT_ULOG=m | ||
228 | CONFIG_BRIDGE_EBT_NFLOG=m | ||
229 | CONFIG_IP_DCCP=m | ||
230 | CONFIG_RDS=m | ||
231 | CONFIG_RDS_TCP=m | ||
232 | CONFIG_TIPC=m | ||
233 | CONFIG_ATM=m | ||
234 | CONFIG_ATM_CLIP=m | ||
235 | CONFIG_ATM_LANE=m | ||
236 | CONFIG_ATM_MPOA=m | ||
237 | CONFIG_ATM_BR2684=m | ||
238 | CONFIG_BRIDGE=m | ||
239 | CONFIG_VLAN_8021Q=m | ||
240 | CONFIG_VLAN_8021Q_GVRP=y | ||
241 | CONFIG_DECNET=m | ||
242 | CONFIG_LLC2=m | ||
243 | CONFIG_IPX=m | ||
244 | CONFIG_ATALK=m | ||
245 | CONFIG_DEV_APPLETALK=m | ||
246 | CONFIG_IPDDP=m | ||
247 | CONFIG_IPDDP_ENCAP=y | ||
248 | CONFIG_IPDDP_DECAP=y | ||
249 | CONFIG_X25=m | ||
250 | CONFIG_LAPB=m | ||
251 | CONFIG_ECONET=m | ||
252 | CONFIG_ECONET_AUNUDP=y | ||
253 | CONFIG_ECONET_NATIVE=y | ||
254 | CONFIG_WAN_ROUTER=m | ||
255 | CONFIG_PHONET=m | ||
256 | CONFIG_IEEE802154=m | ||
257 | CONFIG_NET_SCHED=y | ||
258 | CONFIG_NET_SCH_CBQ=m | ||
259 | CONFIG_NET_SCH_HTB=m | ||
260 | CONFIG_NET_SCH_HFSC=m | ||
261 | CONFIG_NET_SCH_ATM=m | ||
262 | CONFIG_NET_SCH_PRIO=m | ||
263 | CONFIG_NET_SCH_MULTIQ=m | ||
264 | CONFIG_NET_SCH_RED=m | ||
265 | CONFIG_NET_SCH_SFQ=m | ||
266 | CONFIG_NET_SCH_TEQL=m | ||
267 | CONFIG_NET_SCH_TBF=m | ||
268 | CONFIG_NET_SCH_GRED=m | ||
269 | CONFIG_NET_SCH_DSMARK=m | ||
270 | CONFIG_NET_SCH_NETEM=m | ||
271 | CONFIG_NET_SCH_DRR=m | ||
272 | CONFIG_NET_SCH_INGRESS=m | ||
273 | CONFIG_NET_CLS_BASIC=m | ||
274 | CONFIG_NET_CLS_TCINDEX=m | ||
275 | CONFIG_NET_CLS_ROUTE4=m | ||
276 | CONFIG_NET_CLS_FW=m | ||
277 | CONFIG_NET_CLS_U32=m | ||
278 | CONFIG_CLS_U32_MARK=y | ||
279 | CONFIG_NET_CLS_RSVP=m | ||
280 | CONFIG_NET_CLS_RSVP6=m | ||
281 | CONFIG_NET_CLS_FLOW=m | ||
282 | CONFIG_NET_EMATCH=y | ||
283 | CONFIG_NET_EMATCH_CMP=m | ||
284 | CONFIG_NET_EMATCH_NBYTE=m | ||
285 | CONFIG_NET_EMATCH_U32=m | ||
286 | CONFIG_NET_EMATCH_META=m | ||
287 | CONFIG_NET_EMATCH_TEXT=m | ||
288 | CONFIG_NET_CLS_ACT=y | ||
289 | CONFIG_NET_ACT_POLICE=m | ||
290 | CONFIG_NET_ACT_GACT=m | ||
291 | CONFIG_GACT_PROB=y | ||
292 | CONFIG_NET_ACT_MIRRED=m | ||
293 | CONFIG_NET_ACT_IPT=m | ||
294 | CONFIG_NET_ACT_NAT=m | ||
295 | CONFIG_NET_ACT_PEDIT=m | ||
296 | CONFIG_NET_ACT_SIMP=m | ||
297 | CONFIG_NET_ACT_SKBEDIT=m | ||
298 | CONFIG_DCB=y | ||
299 | CONFIG_NET_PKTGEN=m | ||
300 | # CONFIG_WIRELESS is not set | ||
301 | CONFIG_DEVTMPFS=y | ||
302 | CONFIG_DEVTMPFS_MOUNT=y | ||
303 | # CONFIG_STANDALONE is not set | ||
304 | CONFIG_CONNECTOR=y | ||
305 | CONFIG_MTD=m | ||
306 | CONFIG_BLK_DEV_LOOP=y | ||
307 | CONFIG_BLK_DEV_CRYPTOLOOP=m | ||
308 | CONFIG_BLK_DEV_NBD=m | ||
309 | CONFIG_BLK_DEV_OSD=m | ||
310 | CONFIG_BLK_DEV_RAM=y | ||
311 | CONFIG_BLK_DEV_RAM_SIZE=65536 | ||
312 | CONFIG_CDROM_PKTCDVD=y | ||
313 | CONFIG_MISC_DEVICES=y | ||
314 | CONFIG_RAID_ATTRS=m | ||
315 | CONFIG_SCSI=y | ||
316 | CONFIG_SCSI_TGT=m | ||
317 | CONFIG_BLK_DEV_SD=y | ||
318 | CONFIG_CHR_DEV_ST=m | ||
319 | CONFIG_CHR_DEV_OSST=m | ||
320 | CONFIG_BLK_DEV_SR=y | ||
321 | CONFIG_CHR_DEV_SG=y | ||
322 | CONFIG_CHR_DEV_SCH=m | ||
323 | CONFIG_SCSI_MULTI_LUN=y | ||
324 | CONFIG_SCSI_CONSTANTS=y | ||
325 | CONFIG_SCSI_LOGGING=y | ||
326 | CONFIG_SCSI_SCAN_ASYNC=y | ||
327 | CONFIG_SCSI_SPI_ATTRS=m | ||
328 | CONFIG_SCSI_FC_TGT_ATTRS=y | ||
329 | CONFIG_SCSI_SAS_LIBSAS=m | ||
330 | CONFIG_SCSI_SRP_ATTRS=m | ||
331 | CONFIG_SCSI_SRP_TGT_ATTRS=y | ||
332 | CONFIG_ISCSI_TCP=m | ||
333 | CONFIG_LIBFCOE=m | ||
334 | CONFIG_SCSI_DEBUG=m | ||
335 | CONFIG_SCSI_DH=y | ||
336 | CONFIG_SCSI_DH_RDAC=m | ||
337 | CONFIG_SCSI_DH_HP_SW=m | ||
338 | CONFIG_SCSI_DH_EMC=m | ||
339 | CONFIG_SCSI_DH_ALUA=m | ||
340 | CONFIG_SCSI_OSD_INITIATOR=m | ||
341 | CONFIG_SCSI_OSD_ULD=m | ||
342 | # CONFIG_INPUT_MOUSEDEV is not set | ||
343 | CONFIG_INPUT_EVDEV=y | ||
344 | CONFIG_INPUT_EVBUG=m | ||
345 | # CONFIG_INPUT_KEYBOARD is not set | ||
346 | # CONFIG_INPUT_MOUSE is not set | ||
347 | # CONFIG_SERIO_I8042 is not set | ||
348 | CONFIG_SERIO_SERPORT=m | ||
349 | CONFIG_SERIO_LIBPS2=y | ||
350 | CONFIG_SERIO_RAW=m | ||
351 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
352 | CONFIG_DEVPTS_MULTIPLE_INSTANCES=y | ||
353 | CONFIG_LEGACY_PTY_COUNT=0 | ||
354 | CONFIG_SERIAL_NONSTANDARD=y | ||
355 | CONFIG_N_HDLC=m | ||
356 | # CONFIG_DEVKMEM is not set | ||
357 | CONFIG_STALDRV=y | ||
358 | CONFIG_SERIAL_8250=y | ||
359 | CONFIG_SERIAL_8250_CONSOLE=y | ||
360 | CONFIG_SERIAL_8250_NR_UARTS=48 | ||
361 | CONFIG_SERIAL_8250_EXTENDED=y | ||
362 | CONFIG_SERIAL_8250_MANY_PORTS=y | ||
363 | CONFIG_SERIAL_8250_SHARE_IRQ=y | ||
364 | CONFIG_SERIAL_8250_RSA=y | ||
365 | CONFIG_HW_RANDOM=y | ||
366 | CONFIG_HW_RANDOM_TIMERIOMEM=m | ||
367 | CONFIG_RAW_DRIVER=m | ||
368 | # CONFIG_HWMON is not set | ||
369 | # CONFIG_VGA_CONSOLE is not set | ||
370 | # CONFIG_HID_SUPPORT is not set | ||
371 | # CONFIG_USB_SUPPORT is not set | ||
372 | CONFIG_UIO=y | ||
373 | CONFIG_UIO_PDRV=m | ||
374 | CONFIG_UIO_PDRV_GENIRQ=m | ||
375 | CONFIG_EXT2_FS=y | ||
376 | CONFIG_EXT2_FS_XATTR=y | ||
377 | CONFIG_EXT2_FS_POSIX_ACL=y | ||
378 | CONFIG_EXT2_FS_SECURITY=y | ||
379 | CONFIG_EXT3_FS=y | ||
380 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
381 | CONFIG_EXT3_FS_SECURITY=y | ||
382 | CONFIG_EXT4_FS=y | ||
383 | CONFIG_EXT4_FS_POSIX_ACL=y | ||
384 | CONFIG_EXT4_FS_SECURITY=y | ||
385 | CONFIG_GFS2_FS=m | ||
386 | CONFIG_GFS2_FS_LOCKING_DLM=y | ||
387 | CONFIG_OCFS2_FS=m | ||
388 | CONFIG_BTRFS_FS=m | ||
389 | CONFIG_BTRFS_FS_POSIX_ACL=y | ||
390 | CONFIG_NILFS2_FS=m | ||
391 | CONFIG_QUOTA_NETLINK_INTERFACE=y | ||
392 | # CONFIG_PRINT_QUOTA_WARNING is not set | ||
393 | CONFIG_QFMT_V1=m | ||
394 | CONFIG_QFMT_V2=m | ||
395 | CONFIG_AUTOFS4_FS=m | ||
396 | CONFIG_FUSE_FS=y | ||
397 | CONFIG_CUSE=m | ||
398 | CONFIG_FSCACHE=m | ||
399 | CONFIG_FSCACHE_STATS=y | ||
400 | CONFIG_FSCACHE_HISTOGRAM=y | ||
401 | CONFIG_CACHEFILES=m | ||
402 | CONFIG_ISO9660_FS=m | ||
403 | CONFIG_JOLIET=y | ||
404 | CONFIG_ZISOFS=y | ||
405 | CONFIG_UDF_FS=m | ||
406 | CONFIG_MSDOS_FS=m | ||
407 | CONFIG_VFAT_FS=m | ||
408 | CONFIG_NTFS_FS=m | ||
409 | CONFIG_PROC_KCORE=y | ||
410 | CONFIG_TMPFS=y | ||
411 | CONFIG_TMPFS_POSIX_ACL=y | ||
412 | CONFIG_CONFIGFS_FS=y | ||
413 | CONFIG_ADFS_FS=m | ||
414 | CONFIG_AFFS_FS=m | ||
415 | CONFIG_ECRYPT_FS=y | ||
416 | CONFIG_HFS_FS=m | ||
417 | CONFIG_HFSPLUS_FS=m | ||
418 | CONFIG_BEFS_FS=m | ||
419 | CONFIG_BFS_FS=m | ||
420 | CONFIG_EFS_FS=m | ||
421 | CONFIG_CRAMFS=m | ||
422 | CONFIG_SQUASHFS=m | ||
423 | CONFIG_VXFS_FS=m | ||
424 | CONFIG_MINIX_FS=m | ||
425 | CONFIG_OMFS_FS=m | ||
426 | CONFIG_HPFS_FS=m | ||
427 | CONFIG_QNX4FS_FS=m | ||
428 | CONFIG_ROMFS_FS=m | ||
429 | CONFIG_SYSV_FS=m | ||
430 | CONFIG_UFS_FS=m | ||
431 | CONFIG_EXOFS_FS=m | ||
432 | CONFIG_NFS_FS=m | ||
433 | CONFIG_NFS_V3=y | ||
434 | CONFIG_NFS_V3_ACL=y | ||
435 | CONFIG_NFS_V4=y | ||
436 | CONFIG_NFS_FSCACHE=y | ||
437 | CONFIG_NFSD=m | ||
438 | CONFIG_NFSD_V3_ACL=y | ||
439 | CONFIG_NFSD_V4=y | ||
440 | CONFIG_CIFS=m | ||
441 | CONFIG_CIFS_WEAK_PW_HASH=y | ||
442 | CONFIG_CIFS_UPCALL=y | ||
443 | CONFIG_CIFS_XATTR=y | ||
444 | CONFIG_CIFS_POSIX=y | ||
445 | CONFIG_CIFS_DFS_UPCALL=y | ||
446 | CONFIG_CIFS_EXPERIMENTAL=y | ||
447 | CONFIG_NCP_FS=m | ||
448 | CONFIG_NCPFS_PACKET_SIGNING=y | ||
449 | CONFIG_NCPFS_IOCTL_LOCKING=y | ||
450 | CONFIG_NCPFS_STRONG=y | ||
451 | CONFIG_NCPFS_NFS_NS=y | ||
452 | CONFIG_NCPFS_OS2_NS=y | ||
453 | CONFIG_NCPFS_NLS=y | ||
454 | CONFIG_NCPFS_EXTRAS=y | ||
455 | CONFIG_CODA_FS=m | ||
456 | CONFIG_AFS_FS=m | ||
457 | CONFIG_PARTITION_ADVANCED=y | ||
458 | CONFIG_ACORN_PARTITION=y | ||
459 | CONFIG_ACORN_PARTITION_ICS=y | ||
460 | CONFIG_ACORN_PARTITION_RISCIX=y | ||
461 | CONFIG_OSF_PARTITION=y | ||
462 | CONFIG_AMIGA_PARTITION=y | ||
463 | CONFIG_ATARI_PARTITION=y | ||
464 | CONFIG_MAC_PARTITION=y | ||
465 | CONFIG_BSD_DISKLABEL=y | ||
466 | CONFIG_MINIX_SUBPARTITION=y | ||
467 | CONFIG_SOLARIS_X86_PARTITION=y | ||
468 | CONFIG_UNIXWARE_DISKLABEL=y | ||
469 | CONFIG_LDM_PARTITION=y | ||
470 | CONFIG_SGI_PARTITION=y | ||
471 | CONFIG_ULTRIX_PARTITION=y | ||
472 | CONFIG_SUN_PARTITION=y | ||
473 | CONFIG_KARMA_PARTITION=y | ||
474 | CONFIG_EFI_PARTITION=y | ||
475 | CONFIG_SYSV68_PARTITION=y | ||
476 | CONFIG_NLS=y | ||
477 | CONFIG_NLS_DEFAULT="cp437" | ||
478 | CONFIG_NLS_CODEPAGE_437=m | ||
479 | CONFIG_NLS_CODEPAGE_737=m | ||
480 | CONFIG_NLS_CODEPAGE_775=m | ||
481 | CONFIG_NLS_CODEPAGE_850=m | ||
482 | CONFIG_NLS_CODEPAGE_852=m | ||
483 | CONFIG_NLS_CODEPAGE_855=m | ||
484 | CONFIG_NLS_CODEPAGE_857=m | ||
485 | CONFIG_NLS_CODEPAGE_860=m | ||
486 | CONFIG_NLS_CODEPAGE_861=m | ||
487 | CONFIG_NLS_CODEPAGE_862=m | ||
488 | CONFIG_NLS_CODEPAGE_863=m | ||
489 | CONFIG_NLS_CODEPAGE_864=m | ||
490 | CONFIG_NLS_CODEPAGE_865=m | ||
491 | CONFIG_NLS_CODEPAGE_866=m | ||
492 | CONFIG_NLS_CODEPAGE_869=m | ||
493 | CONFIG_NLS_CODEPAGE_936=m | ||
494 | CONFIG_NLS_CODEPAGE_950=m | ||
495 | CONFIG_NLS_CODEPAGE_932=m | ||
496 | CONFIG_NLS_CODEPAGE_949=m | ||
497 | CONFIG_NLS_CODEPAGE_874=m | ||
498 | CONFIG_NLS_ISO8859_8=m | ||
499 | CONFIG_NLS_CODEPAGE_1250=m | ||
500 | CONFIG_NLS_CODEPAGE_1251=m | ||
501 | CONFIG_NLS_ASCII=m | ||
502 | CONFIG_NLS_ISO8859_1=m | ||
503 | CONFIG_NLS_ISO8859_2=m | ||
504 | CONFIG_NLS_ISO8859_3=m | ||
505 | CONFIG_NLS_ISO8859_4=m | ||
506 | CONFIG_NLS_ISO8859_5=m | ||
507 | CONFIG_NLS_ISO8859_6=m | ||
508 | CONFIG_NLS_ISO8859_7=m | ||
509 | CONFIG_NLS_ISO8859_9=m | ||
510 | CONFIG_NLS_ISO8859_13=m | ||
511 | CONFIG_NLS_ISO8859_14=m | ||
512 | CONFIG_NLS_ISO8859_15=m | ||
513 | CONFIG_NLS_KOI8_R=m | ||
514 | CONFIG_NLS_KOI8_U=m | ||
515 | CONFIG_PRINTK_TIME=y | ||
516 | # CONFIG_ENABLE_WARN_DEPRECATED is not set | ||
517 | # CONFIG_ENABLE_MUST_CHECK is not set | ||
518 | CONFIG_UNUSED_SYMBOLS=y | ||
519 | CONFIG_DEBUG_KERNEL=y | ||
520 | CONFIG_DETECT_HUNG_TASK=y | ||
521 | CONFIG_SCHEDSTATS=y | ||
522 | CONFIG_TIMER_STATS=y | ||
523 | CONFIG_DEBUG_INFO=y | ||
524 | CONFIG_DEBUG_MEMORY_INIT=y | ||
525 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
526 | CONFIG_SCHED_TRACER=y | ||
527 | CONFIG_BLK_DEV_IO_TRACE=y | ||
528 | CONFIG_KGDB=y | ||
529 | CONFIG_SECURITY=y | ||
530 | CONFIG_SECURITY_NETWORK=y | ||
531 | CONFIG_LSM_MMAP_MIN_ADDR=0 | ||
532 | CONFIG_SECURITY_SELINUX=y | ||
533 | CONFIG_SECURITY_SELINUX_BOOTPARAM=y | ||
534 | CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 | ||
535 | CONFIG_SECURITY_SELINUX_DISABLE=y | ||
536 | CONFIG_SECURITY_SMACK=y | ||
537 | CONFIG_SECURITY_TOMOYO=y | ||
538 | CONFIG_CRYPTO_NULL=m | ||
539 | CONFIG_CRYPTO_CRYPTD=m | ||
540 | CONFIG_CRYPTO_TEST=m | ||
541 | CONFIG_CRYPTO_CCM=m | ||
542 | CONFIG_CRYPTO_GCM=m | ||
543 | CONFIG_CRYPTO_CTS=m | ||
544 | CONFIG_CRYPTO_LRW=m | ||
545 | CONFIG_CRYPTO_PCBC=m | ||
546 | CONFIG_CRYPTO_XTS=m | ||
547 | CONFIG_CRYPTO_HMAC=y | ||
548 | CONFIG_CRYPTO_XCBC=m | ||
549 | CONFIG_CRYPTO_VMAC=m | ||
550 | CONFIG_CRYPTO_MICHAEL_MIC=m | ||
551 | CONFIG_CRYPTO_RMD128=m | ||
552 | CONFIG_CRYPTO_RMD160=m | ||
553 | CONFIG_CRYPTO_RMD256=m | ||
554 | CONFIG_CRYPTO_RMD320=m | ||
555 | CONFIG_CRYPTO_SHA256=m | ||
556 | CONFIG_CRYPTO_SHA512=m | ||
557 | CONFIG_CRYPTO_TGR192=m | ||
558 | CONFIG_CRYPTO_WP512=m | ||
559 | CONFIG_CRYPTO_ANUBIS=m | ||
560 | CONFIG_CRYPTO_BLOWFISH=m | ||
561 | CONFIG_CRYPTO_CAMELLIA=m | ||
562 | CONFIG_CRYPTO_CAST5=m | ||
563 | CONFIG_CRYPTO_CAST6=m | ||
564 | CONFIG_CRYPTO_FCRYPT=m | ||
565 | CONFIG_CRYPTO_KHAZAD=m | ||
566 | CONFIG_CRYPTO_SALSA20=m | ||
567 | CONFIG_CRYPTO_SEED=m | ||
568 | CONFIG_CRYPTO_SERPENT=m | ||
569 | CONFIG_CRYPTO_TEA=m | ||
570 | CONFIG_CRYPTO_TWOFISH=m | ||
571 | CONFIG_CRYPTO_ZLIB=m | ||
572 | CONFIG_CRYPTO_LZO=m | ||
573 | CONFIG_CRC_CCITT=m | ||
574 | CONFIG_CRC7=m | ||
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 86877539c6e8..34c0d3cb116f 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #define PRID_COMP_TOSHIBA 0x070000 | 33 | #define PRID_COMP_TOSHIBA 0x070000 |
34 | #define PRID_COMP_LSI 0x080000 | 34 | #define PRID_COMP_LSI 0x080000 |
35 | #define PRID_COMP_LEXRA 0x0b0000 | 35 | #define PRID_COMP_LEXRA 0x0b0000 |
36 | #define PRID_COMP_NETLOGIC 0x0c0000 | ||
36 | #define PRID_COMP_CAVIUM 0x0d0000 | 37 | #define PRID_COMP_CAVIUM 0x0d0000 |
37 | #define PRID_COMP_INGENIC 0xd00000 | 38 | #define PRID_COMP_INGENIC 0xd00000 |
38 | 39 | ||
@@ -142,6 +143,31 @@ | |||
142 | #define PRID_IMP_JZRISC 0x0200 | 143 | #define PRID_IMP_JZRISC 0x0200 |
143 | 144 | ||
144 | /* | 145 | /* |
146 | * These are the PRID's for when 23:16 == PRID_COMP_NETLOGIC | ||
147 | */ | ||
148 | #define PRID_IMP_NETLOGIC_XLR732 0x0000 | ||
149 | #define PRID_IMP_NETLOGIC_XLR716 0x0200 | ||
150 | #define PRID_IMP_NETLOGIC_XLR532 0x0900 | ||
151 | #define PRID_IMP_NETLOGIC_XLR308 0x0600 | ||
152 | #define PRID_IMP_NETLOGIC_XLR532C 0x0800 | ||
153 | #define PRID_IMP_NETLOGIC_XLR516C 0x0a00 | ||
154 | #define PRID_IMP_NETLOGIC_XLR508C 0x0b00 | ||
155 | #define PRID_IMP_NETLOGIC_XLR308C 0x0f00 | ||
156 | #define PRID_IMP_NETLOGIC_XLS608 0x8000 | ||
157 | #define PRID_IMP_NETLOGIC_XLS408 0x8800 | ||
158 | #define PRID_IMP_NETLOGIC_XLS404 0x8c00 | ||
159 | #define PRID_IMP_NETLOGIC_XLS208 0x8e00 | ||
160 | #define PRID_IMP_NETLOGIC_XLS204 0x8f00 | ||
161 | #define PRID_IMP_NETLOGIC_XLS108 0xce00 | ||
162 | #define PRID_IMP_NETLOGIC_XLS104 0xcf00 | ||
163 | #define PRID_IMP_NETLOGIC_XLS616B 0x4000 | ||
164 | #define PRID_IMP_NETLOGIC_XLS608B 0x4a00 | ||
165 | #define PRID_IMP_NETLOGIC_XLS416B 0x4400 | ||
166 | #define PRID_IMP_NETLOGIC_XLS412B 0x4c00 | ||
167 | #define PRID_IMP_NETLOGIC_XLS408B 0x4e00 | ||
168 | #define PRID_IMP_NETLOGIC_XLS404B 0x4f00 | ||
169 | |||
170 | /* | ||
145 | * Definitions for 7:0 on legacy processors | 171 | * Definitions for 7:0 on legacy processors |
146 | */ | 172 | */ |
147 | 173 | ||
@@ -234,6 +260,7 @@ enum cpu_type_enum { | |||
234 | */ | 260 | */ |
235 | CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2, | 261 | CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2, |
236 | CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2, | 262 | CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2, |
263 | CPU_XLR, | ||
237 | 264 | ||
238 | CPU_LAST | 265 | CPU_LAST |
239 | }; | 266 | }; |
diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h index a6976619160a..f260ebed713b 100644 --- a/arch/mips/include/asm/mach-au1x00/au1000.h +++ b/arch/mips/include/asm/mach-au1x00/au1000.h | |||
@@ -161,6 +161,45 @@ static inline int alchemy_get_cputype(void) | |||
161 | return ALCHEMY_CPU_UNKNOWN; | 161 | return ALCHEMY_CPU_UNKNOWN; |
162 | } | 162 | } |
163 | 163 | ||
164 | /* return number of uarts on a given cputype */ | ||
165 | static inline int alchemy_get_uarts(int type) | ||
166 | { | ||
167 | switch (type) { | ||
168 | case ALCHEMY_CPU_AU1000: | ||
169 | return 4; | ||
170 | case ALCHEMY_CPU_AU1500: | ||
171 | case ALCHEMY_CPU_AU1200: | ||
172 | return 2; | ||
173 | case ALCHEMY_CPU_AU1100: | ||
174 | case ALCHEMY_CPU_AU1550: | ||
175 | return 3; | ||
176 | } | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | /* enable an UART block if it isn't already */ | ||
181 | static inline void alchemy_uart_enable(u32 uart_phys) | ||
182 | { | ||
183 | void __iomem *addr = (void __iomem *)KSEG1ADDR(uart_phys); | ||
184 | |||
185 | /* reset, enable clock, deassert reset */ | ||
186 | if ((__raw_readl(addr + 0x100) & 3) != 3) { | ||
187 | __raw_writel(0, addr + 0x100); | ||
188 | wmb(); | ||
189 | __raw_writel(1, addr + 0x100); | ||
190 | wmb(); | ||
191 | } | ||
192 | __raw_writel(3, addr + 0x100); | ||
193 | wmb(); | ||
194 | } | ||
195 | |||
196 | static inline void alchemy_uart_disable(u32 uart_phys) | ||
197 | { | ||
198 | void __iomem *addr = (void __iomem *)KSEG1ADDR(uart_phys); | ||
199 | __raw_writel(0, addr + 0x100); /* UART_MOD_CNTRL */ | ||
200 | wmb(); | ||
201 | } | ||
202 | |||
164 | static inline void alchemy_uart_putchar(u32 uart_phys, u8 c) | 203 | static inline void alchemy_uart_putchar(u32 uart_phys, u8 c) |
165 | { | 204 | { |
166 | void __iomem *base = (void __iomem *)KSEG1ADDR(uart_phys); | 205 | void __iomem *base = (void __iomem *)KSEG1ADDR(uart_phys); |
@@ -180,6 +219,20 @@ static inline void alchemy_uart_putchar(u32 uart_phys, u8 c) | |||
180 | wmb(); | 219 | wmb(); |
181 | } | 220 | } |
182 | 221 | ||
222 | /* return number of ethernet MACs on a given cputype */ | ||
223 | static inline int alchemy_get_macs(int type) | ||
224 | { | ||
225 | switch (type) { | ||
226 | case ALCHEMY_CPU_AU1000: | ||
227 | case ALCHEMY_CPU_AU1500: | ||
228 | case ALCHEMY_CPU_AU1550: | ||
229 | return 2; | ||
230 | case ALCHEMY_CPU_AU1100: | ||
231 | return 1; | ||
232 | } | ||
233 | return 0; | ||
234 | } | ||
235 | |||
183 | /* arch/mips/au1000/common/clocks.c */ | 236 | /* arch/mips/au1000/common/clocks.c */ |
184 | extern void set_au1x00_speed(unsigned int new_freq); | 237 | extern void set_au1x00_speed(unsigned int new_freq); |
185 | extern unsigned int get_au1x00_speed(void); | 238 | extern unsigned int get_au1x00_speed(void); |
@@ -630,38 +683,42 @@ enum soc_au1200_ints { | |||
630 | 683 | ||
631 | /* | 684 | /* |
632 | * Physical base addresses for integrated peripherals | 685 | * Physical base addresses for integrated peripherals |
686 | * 0..au1000 1..au1500 2..au1100 3..au1550 4..au1200 | ||
633 | */ | 687 | */ |
634 | 688 | ||
689 | #define AU1000_AC97_PHYS_ADDR 0x10000000 /* 012 */ | ||
690 | #define AU1000_USBD_PHYS_ADDR 0x10200000 /* 0123 */ | ||
691 | #define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */ | ||
692 | #define AU1000_MAC0_PHYS_ADDR 0x10500000 /* 023 */ | ||
693 | #define AU1000_MAC1_PHYS_ADDR 0x10510000 /* 023 */ | ||
694 | #define AU1000_MACEN_PHYS_ADDR 0x10520000 /* 023 */ | ||
695 | #define AU1100_SD0_PHYS_ADDR 0x10600000 /* 24 */ | ||
696 | #define AU1100_SD1_PHYS_ADDR 0x10680000 /* 24 */ | ||
697 | #define AU1000_I2S_PHYS_ADDR 0x11000000 /* 02 */ | ||
698 | #define AU1500_MAC0_PHYS_ADDR 0x11500000 /* 1 */ | ||
699 | #define AU1500_MAC1_PHYS_ADDR 0x11510000 /* 1 */ | ||
700 | #define AU1500_MACEN_PHYS_ADDR 0x11520000 /* 1 */ | ||
701 | #define AU1000_UART0_PHYS_ADDR 0x11100000 /* 01234 */ | ||
702 | #define AU1000_UART1_PHYS_ADDR 0x11200000 /* 0234 */ | ||
703 | #define AU1000_UART2_PHYS_ADDR 0x11300000 /* 0 */ | ||
704 | #define AU1000_UART3_PHYS_ADDR 0x11400000 /* 0123 */ | ||
705 | #define AU1500_GPIO2_PHYS_ADDR 0x11700000 /* 1234 */ | ||
706 | #define AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */ | ||
707 | #define AU1000_SYS_PHYS_ADDR 0x11900000 /* 01234 */ | ||
708 | #define AU1000_DMA_PHYS_ADDR 0x14002000 /* 012 */ | ||
709 | #define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 34 */ | ||
710 | #define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 34 */ | ||
711 | #define AU1000_MACDMA0_PHYS_ADDR 0x14004000 /* 0123 */ | ||
712 | #define AU1000_MACDMA1_PHYS_ADDR 0x14004200 /* 0123 */ | ||
713 | |||
714 | |||
635 | #ifdef CONFIG_SOC_AU1000 | 715 | #ifdef CONFIG_SOC_AU1000 |
636 | #define MEM_PHYS_ADDR 0x14000000 | 716 | #define MEM_PHYS_ADDR 0x14000000 |
637 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | 717 | #define STATIC_MEM_PHYS_ADDR 0x14001000 |
638 | #define DMA0_PHYS_ADDR 0x14002000 | ||
639 | #define DMA1_PHYS_ADDR 0x14002100 | ||
640 | #define DMA2_PHYS_ADDR 0x14002200 | ||
641 | #define DMA3_PHYS_ADDR 0x14002300 | ||
642 | #define DMA4_PHYS_ADDR 0x14002400 | ||
643 | #define DMA5_PHYS_ADDR 0x14002500 | ||
644 | #define DMA6_PHYS_ADDR 0x14002600 | ||
645 | #define DMA7_PHYS_ADDR 0x14002700 | ||
646 | #define IC0_PHYS_ADDR 0x10400000 | ||
647 | #define IC1_PHYS_ADDR 0x11800000 | ||
648 | #define AC97_PHYS_ADDR 0x10000000 | ||
649 | #define USBH_PHYS_ADDR 0x10100000 | 718 | #define USBH_PHYS_ADDR 0x10100000 |
650 | #define USBD_PHYS_ADDR 0x10200000 | ||
651 | #define IRDA_PHYS_ADDR 0x10300000 | 719 | #define IRDA_PHYS_ADDR 0x10300000 |
652 | #define MAC0_PHYS_ADDR 0x10500000 | ||
653 | #define MAC1_PHYS_ADDR 0x10510000 | ||
654 | #define MACEN_PHYS_ADDR 0x10520000 | ||
655 | #define MACDMA0_PHYS_ADDR 0x14004000 | ||
656 | #define MACDMA1_PHYS_ADDR 0x14004200 | ||
657 | #define I2S_PHYS_ADDR 0x11000000 | ||
658 | #define UART0_PHYS_ADDR 0x11100000 | ||
659 | #define UART1_PHYS_ADDR 0x11200000 | ||
660 | #define UART2_PHYS_ADDR 0x11300000 | ||
661 | #define UART3_PHYS_ADDR 0x11400000 | ||
662 | #define SSI0_PHYS_ADDR 0x11600000 | 720 | #define SSI0_PHYS_ADDR 0x11600000 |
663 | #define SSI1_PHYS_ADDR 0x11680000 | 721 | #define SSI1_PHYS_ADDR 0x11680000 |
664 | #define SYS_PHYS_ADDR 0x11900000 | ||
665 | #define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL | 722 | #define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL |
666 | #define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL | 723 | #define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL |
667 | #define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL | 724 | #define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL |
@@ -672,30 +729,8 @@ enum soc_au1200_ints { | |||
672 | #ifdef CONFIG_SOC_AU1500 | 729 | #ifdef CONFIG_SOC_AU1500 |
673 | #define MEM_PHYS_ADDR 0x14000000 | 730 | #define MEM_PHYS_ADDR 0x14000000 |
674 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | 731 | #define STATIC_MEM_PHYS_ADDR 0x14001000 |
675 | #define DMA0_PHYS_ADDR 0x14002000 | ||
676 | #define DMA1_PHYS_ADDR 0x14002100 | ||
677 | #define DMA2_PHYS_ADDR 0x14002200 | ||
678 | #define DMA3_PHYS_ADDR 0x14002300 | ||
679 | #define DMA4_PHYS_ADDR 0x14002400 | ||
680 | #define DMA5_PHYS_ADDR 0x14002500 | ||
681 | #define DMA6_PHYS_ADDR 0x14002600 | ||
682 | #define DMA7_PHYS_ADDR 0x14002700 | ||
683 | #define IC0_PHYS_ADDR 0x10400000 | ||
684 | #define IC1_PHYS_ADDR 0x11800000 | ||
685 | #define AC97_PHYS_ADDR 0x10000000 | ||
686 | #define USBH_PHYS_ADDR 0x10100000 | 732 | #define USBH_PHYS_ADDR 0x10100000 |
687 | #define USBD_PHYS_ADDR 0x10200000 | ||
688 | #define PCI_PHYS_ADDR 0x14005000 | 733 | #define PCI_PHYS_ADDR 0x14005000 |
689 | #define MAC0_PHYS_ADDR 0x11500000 | ||
690 | #define MAC1_PHYS_ADDR 0x11510000 | ||
691 | #define MACEN_PHYS_ADDR 0x11520000 | ||
692 | #define MACDMA0_PHYS_ADDR 0x14004000 | ||
693 | #define MACDMA1_PHYS_ADDR 0x14004200 | ||
694 | #define I2S_PHYS_ADDR 0x11000000 | ||
695 | #define UART0_PHYS_ADDR 0x11100000 | ||
696 | #define UART3_PHYS_ADDR 0x11400000 | ||
697 | #define GPIO2_PHYS_ADDR 0x11700000 | ||
698 | #define SYS_PHYS_ADDR 0x11900000 | ||
699 | #define PCI_MEM_PHYS_ADDR 0x400000000ULL | 734 | #define PCI_MEM_PHYS_ADDR 0x400000000ULL |
700 | #define PCI_IO_PHYS_ADDR 0x500000000ULL | 735 | #define PCI_IO_PHYS_ADDR 0x500000000ULL |
701 | #define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL | 736 | #define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL |
@@ -710,34 +745,10 @@ enum soc_au1200_ints { | |||
710 | #ifdef CONFIG_SOC_AU1100 | 745 | #ifdef CONFIG_SOC_AU1100 |
711 | #define MEM_PHYS_ADDR 0x14000000 | 746 | #define MEM_PHYS_ADDR 0x14000000 |
712 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | 747 | #define STATIC_MEM_PHYS_ADDR 0x14001000 |
713 | #define DMA0_PHYS_ADDR 0x14002000 | ||
714 | #define DMA1_PHYS_ADDR 0x14002100 | ||
715 | #define DMA2_PHYS_ADDR 0x14002200 | ||
716 | #define DMA3_PHYS_ADDR 0x14002300 | ||
717 | #define DMA4_PHYS_ADDR 0x14002400 | ||
718 | #define DMA5_PHYS_ADDR 0x14002500 | ||
719 | #define DMA6_PHYS_ADDR 0x14002600 | ||
720 | #define DMA7_PHYS_ADDR 0x14002700 | ||
721 | #define IC0_PHYS_ADDR 0x10400000 | ||
722 | #define SD0_PHYS_ADDR 0x10600000 | ||
723 | #define SD1_PHYS_ADDR 0x10680000 | ||
724 | #define IC1_PHYS_ADDR 0x11800000 | ||
725 | #define AC97_PHYS_ADDR 0x10000000 | ||
726 | #define USBH_PHYS_ADDR 0x10100000 | 748 | #define USBH_PHYS_ADDR 0x10100000 |
727 | #define USBD_PHYS_ADDR 0x10200000 | ||
728 | #define IRDA_PHYS_ADDR 0x10300000 | 749 | #define IRDA_PHYS_ADDR 0x10300000 |
729 | #define MAC0_PHYS_ADDR 0x10500000 | ||
730 | #define MACEN_PHYS_ADDR 0x10520000 | ||
731 | #define MACDMA0_PHYS_ADDR 0x14004000 | ||
732 | #define MACDMA1_PHYS_ADDR 0x14004200 | ||
733 | #define I2S_PHYS_ADDR 0x11000000 | ||
734 | #define UART0_PHYS_ADDR 0x11100000 | ||
735 | #define UART1_PHYS_ADDR 0x11200000 | ||
736 | #define UART3_PHYS_ADDR 0x11400000 | ||
737 | #define SSI0_PHYS_ADDR 0x11600000 | 750 | #define SSI0_PHYS_ADDR 0x11600000 |
738 | #define SSI1_PHYS_ADDR 0x11680000 | 751 | #define SSI1_PHYS_ADDR 0x11680000 |
739 | #define GPIO2_PHYS_ADDR 0x11700000 | ||
740 | #define SYS_PHYS_ADDR 0x11900000 | ||
741 | #define LCD_PHYS_ADDR 0x15000000 | 752 | #define LCD_PHYS_ADDR 0x15000000 |
742 | #define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL | 753 | #define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL |
743 | #define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL | 754 | #define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL |
@@ -749,22 +760,8 @@ enum soc_au1200_ints { | |||
749 | #ifdef CONFIG_SOC_AU1550 | 760 | #ifdef CONFIG_SOC_AU1550 |
750 | #define MEM_PHYS_ADDR 0x14000000 | 761 | #define MEM_PHYS_ADDR 0x14000000 |
751 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | 762 | #define STATIC_MEM_PHYS_ADDR 0x14001000 |
752 | #define IC0_PHYS_ADDR 0x10400000 | ||
753 | #define IC1_PHYS_ADDR 0x11800000 | ||
754 | #define USBH_PHYS_ADDR 0x14020000 | 763 | #define USBH_PHYS_ADDR 0x14020000 |
755 | #define USBD_PHYS_ADDR 0x10200000 | ||
756 | #define PCI_PHYS_ADDR 0x14005000 | 764 | #define PCI_PHYS_ADDR 0x14005000 |
757 | #define MAC0_PHYS_ADDR 0x10500000 | ||
758 | #define MAC1_PHYS_ADDR 0x10510000 | ||
759 | #define MACEN_PHYS_ADDR 0x10520000 | ||
760 | #define MACDMA0_PHYS_ADDR 0x14004000 | ||
761 | #define MACDMA1_PHYS_ADDR 0x14004200 | ||
762 | #define UART0_PHYS_ADDR 0x11100000 | ||
763 | #define UART1_PHYS_ADDR 0x11200000 | ||
764 | #define UART3_PHYS_ADDR 0x11400000 | ||
765 | #define GPIO2_PHYS_ADDR 0x11700000 | ||
766 | #define SYS_PHYS_ADDR 0x11900000 | ||
767 | #define DDMA_PHYS_ADDR 0x14002000 | ||
768 | #define PE_PHYS_ADDR 0x14008000 | 765 | #define PE_PHYS_ADDR 0x14008000 |
769 | #define PSC0_PHYS_ADDR 0x11A00000 | 766 | #define PSC0_PHYS_ADDR 0x11A00000 |
770 | #define PSC1_PHYS_ADDR 0x11B00000 | 767 | #define PSC1_PHYS_ADDR 0x11B00000 |
@@ -786,19 +783,10 @@ enum soc_au1200_ints { | |||
786 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | 783 | #define STATIC_MEM_PHYS_ADDR 0x14001000 |
787 | #define AES_PHYS_ADDR 0x10300000 | 784 | #define AES_PHYS_ADDR 0x10300000 |
788 | #define CIM_PHYS_ADDR 0x14004000 | 785 | #define CIM_PHYS_ADDR 0x14004000 |
789 | #define IC0_PHYS_ADDR 0x10400000 | ||
790 | #define IC1_PHYS_ADDR 0x11800000 | ||
791 | #define USBM_PHYS_ADDR 0x14020000 | 786 | #define USBM_PHYS_ADDR 0x14020000 |
792 | #define USBH_PHYS_ADDR 0x14020100 | 787 | #define USBH_PHYS_ADDR 0x14020100 |
793 | #define UART0_PHYS_ADDR 0x11100000 | ||
794 | #define UART1_PHYS_ADDR 0x11200000 | ||
795 | #define GPIO2_PHYS_ADDR 0x11700000 | ||
796 | #define SYS_PHYS_ADDR 0x11900000 | ||
797 | #define DDMA_PHYS_ADDR 0x14002000 | ||
798 | #define PSC0_PHYS_ADDR 0x11A00000 | 788 | #define PSC0_PHYS_ADDR 0x11A00000 |
799 | #define PSC1_PHYS_ADDR 0x11B00000 | 789 | #define PSC1_PHYS_ADDR 0x11B00000 |
800 | #define SD0_PHYS_ADDR 0x10600000 | ||
801 | #define SD1_PHYS_ADDR 0x10680000 | ||
802 | #define LCD_PHYS_ADDR 0x15000000 | 790 | #define LCD_PHYS_ADDR 0x15000000 |
803 | #define SWCNT_PHYS_ADDR 0x1110010C | 791 | #define SWCNT_PHYS_ADDR 0x1110010C |
804 | #define MAEFE_PHYS_ADDR 0x14012000 | 792 | #define MAEFE_PHYS_ADDR 0x14012000 |
@@ -835,183 +823,43 @@ enum soc_au1200_ints { | |||
835 | #endif | 823 | #endif |
836 | 824 | ||
837 | 825 | ||
838 | /* Interrupt Controller register offsets */ | ||
839 | #define IC_CFG0RD 0x40 | ||
840 | #define IC_CFG0SET 0x40 | ||
841 | #define IC_CFG0CLR 0x44 | ||
842 | #define IC_CFG1RD 0x48 | ||
843 | #define IC_CFG1SET 0x48 | ||
844 | #define IC_CFG1CLR 0x4C | ||
845 | #define IC_CFG2RD 0x50 | ||
846 | #define IC_CFG2SET 0x50 | ||
847 | #define IC_CFG2CLR 0x54 | ||
848 | #define IC_REQ0INT 0x54 | ||
849 | #define IC_SRCRD 0x58 | ||
850 | #define IC_SRCSET 0x58 | ||
851 | #define IC_SRCCLR 0x5C | ||
852 | #define IC_REQ1INT 0x5C | ||
853 | #define IC_ASSIGNRD 0x60 | ||
854 | #define IC_ASSIGNSET 0x60 | ||
855 | #define IC_ASSIGNCLR 0x64 | ||
856 | #define IC_WAKERD 0x68 | ||
857 | #define IC_WAKESET 0x68 | ||
858 | #define IC_WAKECLR 0x6C | ||
859 | #define IC_MASKRD 0x70 | ||
860 | #define IC_MASKSET 0x70 | ||
861 | #define IC_MASKCLR 0x74 | ||
862 | #define IC_RISINGRD 0x78 | ||
863 | #define IC_RISINGCLR 0x78 | ||
864 | #define IC_FALLINGRD 0x7C | ||
865 | #define IC_FALLINGCLR 0x7C | ||
866 | #define IC_TESTBIT 0x80 | ||
867 | |||
868 | |||
869 | /* Interrupt Controller 0 */ | ||
870 | #define IC0_CFG0RD 0xB0400040 | ||
871 | #define IC0_CFG0SET 0xB0400040 | ||
872 | #define IC0_CFG0CLR 0xB0400044 | ||
873 | |||
874 | #define IC0_CFG1RD 0xB0400048 | ||
875 | #define IC0_CFG1SET 0xB0400048 | ||
876 | #define IC0_CFG1CLR 0xB040004C | ||
877 | |||
878 | #define IC0_CFG2RD 0xB0400050 | ||
879 | #define IC0_CFG2SET 0xB0400050 | ||
880 | #define IC0_CFG2CLR 0xB0400054 | ||
881 | |||
882 | #define IC0_REQ0INT 0xB0400054 | ||
883 | #define IC0_SRCRD 0xB0400058 | ||
884 | #define IC0_SRCSET 0xB0400058 | ||
885 | #define IC0_SRCCLR 0xB040005C | ||
886 | #define IC0_REQ1INT 0xB040005C | ||
887 | |||
888 | #define IC0_ASSIGNRD 0xB0400060 | ||
889 | #define IC0_ASSIGNSET 0xB0400060 | ||
890 | #define IC0_ASSIGNCLR 0xB0400064 | ||
891 | |||
892 | #define IC0_WAKERD 0xB0400068 | ||
893 | #define IC0_WAKESET 0xB0400068 | ||
894 | #define IC0_WAKECLR 0xB040006C | ||
895 | |||
896 | #define IC0_MASKRD 0xB0400070 | ||
897 | #define IC0_MASKSET 0xB0400070 | ||
898 | #define IC0_MASKCLR 0xB0400074 | ||
899 | |||
900 | #define IC0_RISINGRD 0xB0400078 | ||
901 | #define IC0_RISINGCLR 0xB0400078 | ||
902 | #define IC0_FALLINGRD 0xB040007C | ||
903 | #define IC0_FALLINGCLR 0xB040007C | ||
904 | |||
905 | #define IC0_TESTBIT 0xB0400080 | ||
906 | |||
907 | /* Interrupt Controller 1 */ | ||
908 | #define IC1_CFG0RD 0xB1800040 | ||
909 | #define IC1_CFG0SET 0xB1800040 | ||
910 | #define IC1_CFG0CLR 0xB1800044 | ||
911 | |||
912 | #define IC1_CFG1RD 0xB1800048 | ||
913 | #define IC1_CFG1SET 0xB1800048 | ||
914 | #define IC1_CFG1CLR 0xB180004C | ||
915 | |||
916 | #define IC1_CFG2RD 0xB1800050 | ||
917 | #define IC1_CFG2SET 0xB1800050 | ||
918 | #define IC1_CFG2CLR 0xB1800054 | ||
919 | |||
920 | #define IC1_REQ0INT 0xB1800054 | ||
921 | #define IC1_SRCRD 0xB1800058 | ||
922 | #define IC1_SRCSET 0xB1800058 | ||
923 | #define IC1_SRCCLR 0xB180005C | ||
924 | #define IC1_REQ1INT 0xB180005C | ||
925 | |||
926 | #define IC1_ASSIGNRD 0xB1800060 | ||
927 | #define IC1_ASSIGNSET 0xB1800060 | ||
928 | #define IC1_ASSIGNCLR 0xB1800064 | ||
929 | |||
930 | #define IC1_WAKERD 0xB1800068 | ||
931 | #define IC1_WAKESET 0xB1800068 | ||
932 | #define IC1_WAKECLR 0xB180006C | ||
933 | |||
934 | #define IC1_MASKRD 0xB1800070 | ||
935 | #define IC1_MASKSET 0xB1800070 | ||
936 | #define IC1_MASKCLR 0xB1800074 | ||
937 | |||
938 | #define IC1_RISINGRD 0xB1800078 | ||
939 | #define IC1_RISINGCLR 0xB1800078 | ||
940 | #define IC1_FALLINGRD 0xB180007C | ||
941 | #define IC1_FALLINGCLR 0xB180007C | ||
942 | |||
943 | #define IC1_TESTBIT 0xB1800080 | ||
944 | 826 | ||
945 | 827 | ||
946 | /* Au1000 */ | 828 | /* Au1000 */ |
947 | #ifdef CONFIG_SOC_AU1000 | 829 | #ifdef CONFIG_SOC_AU1000 |
948 | 830 | ||
949 | #define UART0_ADDR 0xB1100000 | ||
950 | #define UART3_ADDR 0xB1400000 | ||
951 | |||
952 | #define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */ | 831 | #define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */ |
953 | #define USB_HOST_CONFIG 0xB017FFFC | 832 | #define USB_HOST_CONFIG 0xB017FFFC |
954 | #define FOR_PLATFORM_C_USB_HOST_INT AU1000_USB_HOST_INT | 833 | #define FOR_PLATFORM_C_USB_HOST_INT AU1000_USB_HOST_INT |
955 | |||
956 | #define AU1000_ETH0_BASE 0xB0500000 | ||
957 | #define AU1000_ETH1_BASE 0xB0510000 | ||
958 | #define AU1000_MAC0_ENABLE 0xB0520000 | ||
959 | #define AU1000_MAC1_ENABLE 0xB0520004 | ||
960 | #define NUM_ETH_INTERFACES 2 | ||
961 | #endif /* CONFIG_SOC_AU1000 */ | 834 | #endif /* CONFIG_SOC_AU1000 */ |
962 | 835 | ||
963 | /* Au1500 */ | 836 | /* Au1500 */ |
964 | #ifdef CONFIG_SOC_AU1500 | 837 | #ifdef CONFIG_SOC_AU1500 |
965 | 838 | ||
966 | #define UART0_ADDR 0xB1100000 | ||
967 | #define UART3_ADDR 0xB1400000 | ||
968 | |||
969 | #define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */ | 839 | #define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */ |
970 | #define USB_HOST_CONFIG 0xB017fffc | 840 | #define USB_HOST_CONFIG 0xB017fffc |
971 | #define FOR_PLATFORM_C_USB_HOST_INT AU1500_USB_HOST_INT | 841 | #define FOR_PLATFORM_C_USB_HOST_INT AU1500_USB_HOST_INT |
972 | |||
973 | #define AU1500_ETH0_BASE 0xB1500000 | ||
974 | #define AU1500_ETH1_BASE 0xB1510000 | ||
975 | #define AU1500_MAC0_ENABLE 0xB1520000 | ||
976 | #define AU1500_MAC1_ENABLE 0xB1520004 | ||
977 | #define NUM_ETH_INTERFACES 2 | ||
978 | #endif /* CONFIG_SOC_AU1500 */ | 842 | #endif /* CONFIG_SOC_AU1500 */ |
979 | 843 | ||
980 | /* Au1100 */ | 844 | /* Au1100 */ |
981 | #ifdef CONFIG_SOC_AU1100 | 845 | #ifdef CONFIG_SOC_AU1100 |
982 | 846 | ||
983 | #define UART0_ADDR 0xB1100000 | ||
984 | #define UART3_ADDR 0xB1400000 | ||
985 | |||
986 | #define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */ | 847 | #define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */ |
987 | #define USB_HOST_CONFIG 0xB017FFFC | 848 | #define USB_HOST_CONFIG 0xB017FFFC |
988 | #define FOR_PLATFORM_C_USB_HOST_INT AU1100_USB_HOST_INT | 849 | #define FOR_PLATFORM_C_USB_HOST_INT AU1100_USB_HOST_INT |
989 | |||
990 | #define AU1100_ETH0_BASE 0xB0500000 | ||
991 | #define AU1100_MAC0_ENABLE 0xB0520000 | ||
992 | #define NUM_ETH_INTERFACES 1 | ||
993 | #endif /* CONFIG_SOC_AU1100 */ | 850 | #endif /* CONFIG_SOC_AU1100 */ |
994 | 851 | ||
995 | #ifdef CONFIG_SOC_AU1550 | 852 | #ifdef CONFIG_SOC_AU1550 |
996 | #define UART0_ADDR 0xB1100000 | ||
997 | 853 | ||
998 | #define USB_OHCI_BASE 0x14020000 /* phys addr for ioremap */ | 854 | #define USB_OHCI_BASE 0x14020000 /* phys addr for ioremap */ |
999 | #define USB_OHCI_LEN 0x00060000 | 855 | #define USB_OHCI_LEN 0x00060000 |
1000 | #define USB_HOST_CONFIG 0xB4027ffc | 856 | #define USB_HOST_CONFIG 0xB4027ffc |
1001 | #define FOR_PLATFORM_C_USB_HOST_INT AU1550_USB_HOST_INT | 857 | #define FOR_PLATFORM_C_USB_HOST_INT AU1550_USB_HOST_INT |
1002 | |||
1003 | #define AU1550_ETH0_BASE 0xB0500000 | ||
1004 | #define AU1550_ETH1_BASE 0xB0510000 | ||
1005 | #define AU1550_MAC0_ENABLE 0xB0520000 | ||
1006 | #define AU1550_MAC1_ENABLE 0xB0520004 | ||
1007 | #define NUM_ETH_INTERFACES 2 | ||
1008 | #endif /* CONFIG_SOC_AU1550 */ | 858 | #endif /* CONFIG_SOC_AU1550 */ |
1009 | 859 | ||
1010 | 860 | ||
1011 | #ifdef CONFIG_SOC_AU1200 | 861 | #ifdef CONFIG_SOC_AU1200 |
1012 | 862 | ||
1013 | #define UART0_ADDR 0xB1100000 | ||
1014 | |||
1015 | #define USB_UOC_BASE 0x14020020 | 863 | #define USB_UOC_BASE 0x14020020 |
1016 | #define USB_UOC_LEN 0x20 | 864 | #define USB_UOC_LEN 0x20 |
1017 | #define USB_OHCI_BASE 0x14020100 | 865 | #define USB_OHCI_BASE 0x14020100 |
@@ -1504,22 +1352,6 @@ enum soc_au1200_ints { | |||
1504 | #define SYS_PINFUNC_S1B (1 << 2) | 1352 | #define SYS_PINFUNC_S1B (1 << 2) |
1505 | #endif | 1353 | #endif |
1506 | 1354 | ||
1507 | #define SYS_TRIOUTRD 0xB1900100 | ||
1508 | #define SYS_TRIOUTCLR 0xB1900100 | ||
1509 | #define SYS_OUTPUTRD 0xB1900108 | ||
1510 | #define SYS_OUTPUTSET 0xB1900108 | ||
1511 | #define SYS_OUTPUTCLR 0xB190010C | ||
1512 | #define SYS_PINSTATERD 0xB1900110 | ||
1513 | #define SYS_PININPUTEN 0xB1900110 | ||
1514 | |||
1515 | /* GPIO2, Au1500, Au1550 only */ | ||
1516 | #define GPIO2_BASE 0xB1700000 | ||
1517 | #define GPIO2_DIR (GPIO2_BASE + 0) | ||
1518 | #define GPIO2_OUTPUT (GPIO2_BASE + 8) | ||
1519 | #define GPIO2_PINSTATE (GPIO2_BASE + 0xC) | ||
1520 | #define GPIO2_INTENABLE (GPIO2_BASE + 0x10) | ||
1521 | #define GPIO2_ENABLE (GPIO2_BASE + 0x14) | ||
1522 | |||
1523 | /* Power Management */ | 1355 | /* Power Management */ |
1524 | #define SYS_SCRATCH0 0xB1900018 | 1356 | #define SYS_SCRATCH0 0xB1900018 |
1525 | #define SYS_SCRATCH1 0xB190001C | 1357 | #define SYS_SCRATCH1 0xB190001C |
@@ -1635,12 +1467,6 @@ enum soc_au1200_ints { | |||
1635 | # define AC97C_RS (1 << 1) | 1467 | # define AC97C_RS (1 << 1) |
1636 | # define AC97C_CE (1 << 0) | 1468 | # define AC97C_CE (1 << 0) |
1637 | 1469 | ||
1638 | /* Secure Digital (SD) Controller */ | ||
1639 | #define SD0_XMIT_FIFO 0xB0600000 | ||
1640 | #define SD0_RECV_FIFO 0xB0600004 | ||
1641 | #define SD1_XMIT_FIFO 0xB0680000 | ||
1642 | #define SD1_RECV_FIFO 0xB0680004 | ||
1643 | |||
1644 | #if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550) | 1470 | #if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550) |
1645 | /* Au1500 PCI Controller */ | 1471 | /* Au1500 PCI Controller */ |
1646 | #define Au1500_CFG_BASE 0xB4005000 /* virtual, KSEG1 addr */ | 1472 | #define Au1500_CFG_BASE 0xB4005000 /* virtual, KSEG1 addr */ |
diff --git a/arch/mips/include/asm/mach-au1x00/au1000_dma.h b/arch/mips/include/asm/mach-au1x00/au1000_dma.h index c333b4e1cd44..59f5b55b2200 100644 --- a/arch/mips/include/asm/mach-au1x00/au1000_dma.h +++ b/arch/mips/include/asm/mach-au1x00/au1000_dma.h | |||
@@ -37,10 +37,6 @@ | |||
37 | 37 | ||
38 | #define NUM_AU1000_DMA_CHANNELS 8 | 38 | #define NUM_AU1000_DMA_CHANNELS 8 |
39 | 39 | ||
40 | /* DMA Channel Base Addresses */ | ||
41 | #define DMA_CHANNEL_BASE 0xB4002000 | ||
42 | #define DMA_CHANNEL_LEN 0x00000100 | ||
43 | |||
44 | /* DMA Channel Register Offsets */ | 40 | /* DMA Channel Register Offsets */ |
45 | #define DMA_MODE_SET 0x00000000 | 41 | #define DMA_MODE_SET 0x00000000 |
46 | #define DMA_MODE_READ DMA_MODE_SET | 42 | #define DMA_MODE_READ DMA_MODE_SET |
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h index c8a553a36ba4..2fdacfe85e23 100644 --- a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h +++ b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h | |||
@@ -37,14 +37,6 @@ | |||
37 | 37 | ||
38 | #ifndef _LANGUAGE_ASSEMBLY | 38 | #ifndef _LANGUAGE_ASSEMBLY |
39 | 39 | ||
40 | /* | ||
41 | * The DMA base addresses. | ||
42 | * The channels are every 256 bytes (0x0100) from the channel 0 base. | ||
43 | * Interrupt status/enable is bits 15:0 for channels 15 to zero. | ||
44 | */ | ||
45 | #define DDMA_GLOBAL_BASE 0xb4003000 | ||
46 | #define DDMA_CHANNEL_BASE 0xb4002000 | ||
47 | |||
48 | typedef volatile struct dbdma_global { | 40 | typedef volatile struct dbdma_global { |
49 | u32 ddma_config; | 41 | u32 ddma_config; |
50 | u32 ddma_intstat; | 42 | u32 ddma_intstat; |
diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h index 62d2f136d941..1f41a522906d 100644 --- a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h +++ b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h | |||
@@ -24,6 +24,23 @@ | |||
24 | 24 | ||
25 | #define MAKE_IRQ(intc, off) (AU1000_INTC##intc##_INT_BASE + (off)) | 25 | #define MAKE_IRQ(intc, off) (AU1000_INTC##intc##_INT_BASE + (off)) |
26 | 26 | ||
27 | /* GPIO1 registers within SYS_ area */ | ||
28 | #define SYS_TRIOUTRD 0x100 | ||
29 | #define SYS_TRIOUTCLR 0x100 | ||
30 | #define SYS_OUTPUTRD 0x108 | ||
31 | #define SYS_OUTPUTSET 0x108 | ||
32 | #define SYS_OUTPUTCLR 0x10C | ||
33 | #define SYS_PINSTATERD 0x110 | ||
34 | #define SYS_PININPUTEN 0x110 | ||
35 | |||
36 | /* register offsets within GPIO2 block */ | ||
37 | #define GPIO2_DIR 0x00 | ||
38 | #define GPIO2_OUTPUT 0x08 | ||
39 | #define GPIO2_PINSTATE 0x0C | ||
40 | #define GPIO2_INTENABLE 0x10 | ||
41 | #define GPIO2_ENABLE 0x14 | ||
42 | |||
43 | struct gpio; | ||
27 | 44 | ||
28 | static inline int au1000_gpio1_to_irq(int gpio) | 45 | static inline int au1000_gpio1_to_irq(int gpio) |
29 | { | 46 | { |
@@ -200,23 +217,26 @@ static inline int au1200_irq_to_gpio(int irq) | |||
200 | */ | 217 | */ |
201 | static inline void alchemy_gpio1_set_value(int gpio, int v) | 218 | static inline void alchemy_gpio1_set_value(int gpio, int v) |
202 | { | 219 | { |
220 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); | ||
203 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); | 221 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); |
204 | unsigned long r = v ? SYS_OUTPUTSET : SYS_OUTPUTCLR; | 222 | unsigned long r = v ? SYS_OUTPUTSET : SYS_OUTPUTCLR; |
205 | au_writel(mask, r); | 223 | __raw_writel(mask, base + r); |
206 | au_sync(); | 224 | wmb(); |
207 | } | 225 | } |
208 | 226 | ||
209 | static inline int alchemy_gpio1_get_value(int gpio) | 227 | static inline int alchemy_gpio1_get_value(int gpio) |
210 | { | 228 | { |
229 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); | ||
211 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); | 230 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); |
212 | return au_readl(SYS_PINSTATERD) & mask; | 231 | return __raw_readl(base + SYS_PINSTATERD) & mask; |
213 | } | 232 | } |
214 | 233 | ||
215 | static inline int alchemy_gpio1_direction_input(int gpio) | 234 | static inline int alchemy_gpio1_direction_input(int gpio) |
216 | { | 235 | { |
236 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); | ||
217 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); | 237 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); |
218 | au_writel(mask, SYS_TRIOUTCLR); | 238 | __raw_writel(mask, base + SYS_TRIOUTCLR); |
219 | au_sync(); | 239 | wmb(); |
220 | return 0; | 240 | return 0; |
221 | } | 241 | } |
222 | 242 | ||
@@ -257,27 +277,31 @@ static inline int alchemy_gpio1_to_irq(int gpio) | |||
257 | */ | 277 | */ |
258 | static inline void __alchemy_gpio2_mod_dir(int gpio, int to_out) | 278 | static inline void __alchemy_gpio2_mod_dir(int gpio, int to_out) |
259 | { | 279 | { |
280 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); | ||
260 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO2_BASE); | 281 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO2_BASE); |
261 | unsigned long d = au_readl(GPIO2_DIR); | 282 | unsigned long d = __raw_readl(base + GPIO2_DIR); |
283 | |||
262 | if (to_out) | 284 | if (to_out) |
263 | d |= mask; | 285 | d |= mask; |
264 | else | 286 | else |
265 | d &= ~mask; | 287 | d &= ~mask; |
266 | au_writel(d, GPIO2_DIR); | 288 | __raw_writel(d, base + GPIO2_DIR); |
267 | au_sync(); | 289 | wmb(); |
268 | } | 290 | } |
269 | 291 | ||
270 | static inline void alchemy_gpio2_set_value(int gpio, int v) | 292 | static inline void alchemy_gpio2_set_value(int gpio, int v) |
271 | { | 293 | { |
294 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); | ||
272 | unsigned long mask; | 295 | unsigned long mask; |
273 | mask = ((v) ? 0x00010001 : 0x00010000) << (gpio - ALCHEMY_GPIO2_BASE); | 296 | mask = ((v) ? 0x00010001 : 0x00010000) << (gpio - ALCHEMY_GPIO2_BASE); |
274 | au_writel(mask, GPIO2_OUTPUT); | 297 | __raw_writel(mask, base + GPIO2_OUTPUT); |
275 | au_sync(); | 298 | wmb(); |
276 | } | 299 | } |
277 | 300 | ||
278 | static inline int alchemy_gpio2_get_value(int gpio) | 301 | static inline int alchemy_gpio2_get_value(int gpio) |
279 | { | 302 | { |
280 | return au_readl(GPIO2_PINSTATE) & (1 << (gpio - ALCHEMY_GPIO2_BASE)); | 303 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
304 | return __raw_readl(base + GPIO2_PINSTATE) & (1 << (gpio - ALCHEMY_GPIO2_BASE)); | ||
281 | } | 305 | } |
282 | 306 | ||
283 | static inline int alchemy_gpio2_direction_input(int gpio) | 307 | static inline int alchemy_gpio2_direction_input(int gpio) |
@@ -329,21 +353,23 @@ static inline int alchemy_gpio2_to_irq(int gpio) | |||
329 | */ | 353 | */ |
330 | static inline void alchemy_gpio1_input_enable(void) | 354 | static inline void alchemy_gpio1_input_enable(void) |
331 | { | 355 | { |
332 | au_writel(0, SYS_PININPUTEN); /* the write op is key */ | 356 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); |
333 | au_sync(); | 357 | __raw_writel(0, base + SYS_PININPUTEN); /* the write op is key */ |
358 | wmb(); | ||
334 | } | 359 | } |
335 | 360 | ||
336 | /* GPIO2 shared interrupts and control */ | 361 | /* GPIO2 shared interrupts and control */ |
337 | 362 | ||
338 | static inline void __alchemy_gpio2_mod_int(int gpio2, int en) | 363 | static inline void __alchemy_gpio2_mod_int(int gpio2, int en) |
339 | { | 364 | { |
340 | unsigned long r = au_readl(GPIO2_INTENABLE); | 365 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
366 | unsigned long r = __raw_readl(base + GPIO2_INTENABLE); | ||
341 | if (en) | 367 | if (en) |
342 | r |= 1 << gpio2; | 368 | r |= 1 << gpio2; |
343 | else | 369 | else |
344 | r &= ~(1 << gpio2); | 370 | r &= ~(1 << gpio2); |
345 | au_writel(r, GPIO2_INTENABLE); | 371 | __raw_writel(r, base + GPIO2_INTENABLE); |
346 | au_sync(); | 372 | wmb(); |
347 | } | 373 | } |
348 | 374 | ||
349 | /** | 375 | /** |
@@ -418,10 +444,11 @@ static inline void alchemy_gpio2_disable_int(int gpio2) | |||
418 | */ | 444 | */ |
419 | static inline void alchemy_gpio2_enable(void) | 445 | static inline void alchemy_gpio2_enable(void) |
420 | { | 446 | { |
421 | au_writel(3, GPIO2_ENABLE); /* reset, clock enabled */ | 447 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
422 | au_sync(); | 448 | __raw_writel(3, base + GPIO2_ENABLE); /* reset, clock enabled */ |
423 | au_writel(1, GPIO2_ENABLE); /* clock enabled */ | 449 | wmb(); |
424 | au_sync(); | 450 | __raw_writel(1, base + GPIO2_ENABLE); /* clock enabled */ |
451 | wmb(); | ||
425 | } | 452 | } |
426 | 453 | ||
427 | /** | 454 | /** |
@@ -431,8 +458,9 @@ static inline void alchemy_gpio2_enable(void) | |||
431 | */ | 458 | */ |
432 | static inline void alchemy_gpio2_disable(void) | 459 | static inline void alchemy_gpio2_disable(void) |
433 | { | 460 | { |
434 | au_writel(2, GPIO2_ENABLE); /* reset, clock disabled */ | 461 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
435 | au_sync(); | 462 | __raw_writel(2, base + GPIO2_ENABLE); /* reset, clock disabled */ |
463 | wmb(); | ||
436 | } | 464 | } |
437 | 465 | ||
438 | /**********************************************************************/ | 466 | /**********************************************************************/ |
@@ -556,6 +584,16 @@ static inline void gpio_set_value(int gpio, int v) | |||
556 | alchemy_gpio_set_value(gpio, v); | 584 | alchemy_gpio_set_value(gpio, v); |
557 | } | 585 | } |
558 | 586 | ||
587 | static inline int gpio_get_value_cansleep(unsigned gpio) | ||
588 | { | ||
589 | return gpio_get_value(gpio); | ||
590 | } | ||
591 | |||
592 | static inline void gpio_set_value_cansleep(unsigned gpio, int value) | ||
593 | { | ||
594 | gpio_set_value(gpio, value); | ||
595 | } | ||
596 | |||
559 | static inline int gpio_is_valid(int gpio) | 597 | static inline int gpio_is_valid(int gpio) |
560 | { | 598 | { |
561 | return alchemy_gpio_is_valid(gpio); | 599 | return alchemy_gpio_is_valid(gpio); |
@@ -581,10 +619,50 @@ static inline int gpio_request(unsigned gpio, const char *label) | |||
581 | return 0; | 619 | return 0; |
582 | } | 620 | } |
583 | 621 | ||
622 | static inline int gpio_request_one(unsigned gpio, | ||
623 | unsigned long flags, const char *label) | ||
624 | { | ||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | static inline int gpio_request_array(struct gpio *array, size_t num) | ||
629 | { | ||
630 | return 0; | ||
631 | } | ||
632 | |||
584 | static inline void gpio_free(unsigned gpio) | 633 | static inline void gpio_free(unsigned gpio) |
585 | { | 634 | { |
586 | } | 635 | } |
587 | 636 | ||
637 | static inline void gpio_free_array(struct gpio *array, size_t num) | ||
638 | { | ||
639 | } | ||
640 | |||
641 | static inline int gpio_set_debounce(unsigned gpio, unsigned debounce) | ||
642 | { | ||
643 | return -ENOSYS; | ||
644 | } | ||
645 | |||
646 | static inline int gpio_export(unsigned gpio, bool direction_may_change) | ||
647 | { | ||
648 | return -ENOSYS; | ||
649 | } | ||
650 | |||
651 | static inline int gpio_export_link(struct device *dev, const char *name, | ||
652 | unsigned gpio) | ||
653 | { | ||
654 | return -ENOSYS; | ||
655 | } | ||
656 | |||
657 | static inline int gpio_sysfs_set_active_low(unsigned gpio, int value) | ||
658 | { | ||
659 | return -ENOSYS; | ||
660 | } | ||
661 | |||
662 | static inline void gpio_unexport(unsigned gpio) | ||
663 | { | ||
664 | } | ||
665 | |||
588 | #endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */ | 666 | #endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */ |
589 | 667 | ||
590 | 668 | ||
diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/nvram.h index 9759588ba3cf..184d5ecb5f51 100644 --- a/arch/mips/include/asm/mach-bcm47xx/nvram.h +++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h | |||
@@ -39,8 +39,16 @@ extern int nvram_getenv(char *name, char *val, size_t val_len); | |||
39 | 39 | ||
40 | static inline void nvram_parse_macaddr(char *buf, u8 *macaddr) | 40 | static inline void nvram_parse_macaddr(char *buf, u8 *macaddr) |
41 | { | 41 | { |
42 | sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], &macaddr[1], | 42 | if (strchr(buf, ':')) |
43 | &macaddr[2], &macaddr[3], &macaddr[4], &macaddr[5]); | 43 | sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], |
44 | &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], | ||
45 | &macaddr[5]); | ||
46 | else if (strchr(buf, '-')) | ||
47 | sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0], | ||
48 | &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], | ||
49 | &macaddr[5]); | ||
50 | else | ||
51 | printk(KERN_WARNING "Can not parse mac address: %s\n", buf); | ||
44 | } | 52 | } |
45 | 53 | ||
46 | #endif | 54 | #endif |
diff --git a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h index 0b2b5eb22e9b..dedef7d2b01f 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h +++ b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h | |||
@@ -63,6 +63,11 @@ | |||
63 | # CN30XX Disable instruction prefetching | 63 | # CN30XX Disable instruction prefetching |
64 | or v0, v0, 0x2000 | 64 | or v0, v0, 0x2000 |
65 | skip: | 65 | skip: |
66 | # First clear off CvmCtl[IPPCI] bit and move the performance | ||
67 | # counters interrupt to IRQ 6 | ||
68 | li v1, ~(7 << 7) | ||
69 | and v0, v0, v1 | ||
70 | ori v0, v0, (6 << 7) | ||
66 | # Write the cavium control register | 71 | # Write the cavium control register |
67 | dmtc0 v0, CP0_CVMCTL_REG | 72 | dmtc0 v0, CP0_CVMCTL_REG |
68 | sync | 73 | sync |
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h new file mode 100644 index 000000000000..ce2f02929d22 --- /dev/null +++ b/arch/mips/include/asm/mach-lantiq/lantiq.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | #ifndef _LANTIQ_H__ | ||
9 | #define _LANTIQ_H__ | ||
10 | |||
11 | #include <linux/irq.h> | ||
12 | |||
13 | /* generic reg access functions */ | ||
14 | #define ltq_r32(reg) __raw_readl(reg) | ||
15 | #define ltq_w32(val, reg) __raw_writel(val, reg) | ||
16 | #define ltq_w32_mask(clear, set, reg) \ | ||
17 | ltq_w32((ltq_r32(reg) & ~(clear)) | (set), reg) | ||
18 | #define ltq_r8(reg) __raw_readb(reg) | ||
19 | #define ltq_w8(val, reg) __raw_writeb(val, reg) | ||
20 | |||
21 | /* register access macros for EBU and CGU */ | ||
22 | #define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y)) | ||
23 | #define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x)) | ||
24 | #define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y)) | ||
25 | #define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x)) | ||
26 | |||
27 | extern __iomem void *ltq_ebu_membase; | ||
28 | extern __iomem void *ltq_cgu_membase; | ||
29 | |||
30 | extern unsigned int ltq_get_cpu_ver(void); | ||
31 | extern unsigned int ltq_get_soc_type(void); | ||
32 | |||
33 | /* clock speeds */ | ||
34 | #define CLOCK_60M 60000000 | ||
35 | #define CLOCK_83M 83333333 | ||
36 | #define CLOCK_111M 111111111 | ||
37 | #define CLOCK_133M 133333333 | ||
38 | #define CLOCK_167M 166666667 | ||
39 | #define CLOCK_200M 200000000 | ||
40 | #define CLOCK_266M 266666666 | ||
41 | #define CLOCK_333M 333333333 | ||
42 | #define CLOCK_400M 400000000 | ||
43 | |||
44 | /* spinlock all ebu i/o */ | ||
45 | extern spinlock_t ebu_lock; | ||
46 | |||
47 | /* some irq helpers */ | ||
48 | extern void ltq_disable_irq(struct irq_data *data); | ||
49 | extern void ltq_mask_and_ack_irq(struct irq_data *data); | ||
50 | extern void ltq_enable_irq(struct irq_data *data); | ||
51 | |||
52 | /* find out what caused the last cpu reset */ | ||
53 | extern int ltq_reset_cause(void); | ||
54 | #define LTQ_RST_CAUSE_WDTRST 0x20 | ||
55 | |||
56 | #define IOPORT_RESOURCE_START 0x10000000 | ||
57 | #define IOPORT_RESOURCE_END 0xffffffff | ||
58 | #define IOMEM_RESOURCE_START 0x10000000 | ||
59 | #define IOMEM_RESOURCE_END 0xffffffff | ||
60 | #define LTQ_FLASH_START 0x10000000 | ||
61 | #define LTQ_FLASH_MAX 0x04000000 | ||
62 | |||
63 | #endif | ||
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h new file mode 100644 index 000000000000..a305f1d0259e --- /dev/null +++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LANTIQ_PLATFORM_H__ | ||
10 | #define _LANTIQ_PLATFORM_H__ | ||
11 | |||
12 | #include <linux/mtd/partitions.h> | ||
13 | #include <linux/socket.h> | ||
14 | |||
15 | /* struct used to pass info to the pci core */ | ||
16 | enum { | ||
17 | PCI_CLOCK_INT = 0, | ||
18 | PCI_CLOCK_EXT | ||
19 | }; | ||
20 | |||
21 | #define PCI_EXIN0 0x0001 | ||
22 | #define PCI_EXIN1 0x0002 | ||
23 | #define PCI_EXIN2 0x0004 | ||
24 | #define PCI_EXIN3 0x0008 | ||
25 | #define PCI_EXIN4 0x0010 | ||
26 | #define PCI_EXIN5 0x0020 | ||
27 | #define PCI_EXIN_MAX 6 | ||
28 | |||
29 | #define PCI_GNT1 0x0040 | ||
30 | #define PCI_GNT2 0x0080 | ||
31 | #define PCI_GNT3 0x0100 | ||
32 | #define PCI_GNT4 0x0200 | ||
33 | |||
34 | #define PCI_REQ1 0x0400 | ||
35 | #define PCI_REQ2 0x0800 | ||
36 | #define PCI_REQ3 0x1000 | ||
37 | #define PCI_REQ4 0x2000 | ||
38 | #define PCI_REQ_SHIFT 10 | ||
39 | #define PCI_REQ_MASK 0xf | ||
40 | |||
41 | struct ltq_pci_data { | ||
42 | int clock; | ||
43 | int gpio; | ||
44 | int irq[16]; | ||
45 | }; | ||
46 | |||
47 | /* struct used to pass info to network drivers */ | ||
48 | struct ltq_eth_data { | ||
49 | struct sockaddr mac; | ||
50 | int mii_mode; | ||
51 | }; | ||
52 | |||
53 | #endif | ||
diff --git a/arch/mips/include/asm/mach-lantiq/war.h b/arch/mips/include/asm/mach-lantiq/war.h new file mode 100644 index 000000000000..01b08ef368d1 --- /dev/null +++ b/arch/mips/include/asm/mach-lantiq/war.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | */ | ||
7 | #ifndef __ASM_MIPS_MACH_LANTIQ_WAR_H | ||
8 | #define __ASM_MIPS_MACH_LANTIQ_WAR_H | ||
9 | |||
10 | #define R4600_V1_INDEX_ICACHEOP_WAR 0 | ||
11 | #define R4600_V1_HIT_CACHEOP_WAR 0 | ||
12 | #define R4600_V2_HIT_CACHEOP_WAR 0 | ||
13 | #define R5432_CP0_INTERRUPT_WAR 0 | ||
14 | #define BCM1250_M3_WAR 0 | ||
15 | #define SIBYTE_1956_WAR 0 | ||
16 | #define MIPS4K_ICACHE_REFILL_WAR 0 | ||
17 | #define MIPS_CACHE_SYNC_WAR 0 | ||
18 | #define TX49XX_ICACHE_INDEX_INV_WAR 0 | ||
19 | #define RM9000_CDEX_SMP_WAR 0 | ||
20 | #define ICACHE_REFILLS_WORKAROUND_WAR 0 | ||
21 | #define R10000_LLSC_WAR 0 | ||
22 | #define MIPS34K_MISSED_ITLB_WAR 0 | ||
23 | |||
24 | #endif | ||
diff --git a/arch/mips/include/asm/mach-lantiq/xway/irq.h b/arch/mips/include/asm/mach-lantiq/xway/irq.h new file mode 100644 index 000000000000..a1471d2dd0d2 --- /dev/null +++ b/arch/mips/include/asm/mach-lantiq/xway/irq.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef __LANTIQ_IRQ_H | ||
10 | #define __LANTIQ_IRQ_H | ||
11 | |||
12 | #include <lantiq_irq.h> | ||
13 | |||
14 | #define NR_IRQS 256 | ||
15 | |||
16 | #include_next <irq.h> | ||
17 | |||
18 | #endif | ||
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h new file mode 100644 index 000000000000..b4465a888e20 --- /dev/null +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LANTIQ_XWAY_IRQ_H__ | ||
10 | #define _LANTIQ_XWAY_IRQ_H__ | ||
11 | |||
12 | #define INT_NUM_IRQ0 8 | ||
13 | #define INT_NUM_IM0_IRL0 (INT_NUM_IRQ0 + 0) | ||
14 | #define INT_NUM_IM1_IRL0 (INT_NUM_IRQ0 + 32) | ||
15 | #define INT_NUM_IM2_IRL0 (INT_NUM_IRQ0 + 64) | ||
16 | #define INT_NUM_IM3_IRL0 (INT_NUM_IRQ0 + 96) | ||
17 | #define INT_NUM_IM4_IRL0 (INT_NUM_IRQ0 + 128) | ||
18 | #define INT_NUM_IM_OFFSET (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0) | ||
19 | |||
20 | #define LTQ_ASC_TIR(x) (INT_NUM_IM3_IRL0 + (x * 8)) | ||
21 | #define LTQ_ASC_RIR(x) (INT_NUM_IM3_IRL0 + (x * 8) + 1) | ||
22 | #define LTQ_ASC_EIR(x) (INT_NUM_IM3_IRL0 + (x * 8) + 2) | ||
23 | |||
24 | #define LTQ_ASC_ASE_TIR INT_NUM_IM2_IRL0 | ||
25 | #define LTQ_ASC_ASE_RIR (INT_NUM_IM2_IRL0 + 2) | ||
26 | #define LTQ_ASC_ASE_EIR (INT_NUM_IM2_IRL0 + 3) | ||
27 | |||
28 | #define LTQ_SSC_TIR (INT_NUM_IM0_IRL0 + 15) | ||
29 | #define LTQ_SSC_RIR (INT_NUM_IM0_IRL0 + 14) | ||
30 | #define LTQ_SSC_EIR (INT_NUM_IM0_IRL0 + 16) | ||
31 | |||
32 | #define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21) | ||
33 | #define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23) | ||
34 | |||
35 | #define LTQ_TIMER6_INT (INT_NUM_IM1_IRL0 + 23) | ||
36 | #define LTQ_USB_INT (INT_NUM_IM1_IRL0 + 22) | ||
37 | #define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23) | ||
38 | |||
39 | #define MIPS_CPU_TIMER_IRQ 7 | ||
40 | |||
41 | #define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0) | ||
42 | #define LTQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1) | ||
43 | #define LTQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2) | ||
44 | #define LTQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3) | ||
45 | #define LTQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4) | ||
46 | #define LTQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5) | ||
47 | #define LTQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6) | ||
48 | #define LTQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7) | ||
49 | #define LTQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8) | ||
50 | #define LTQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9) | ||
51 | #define LTQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10) | ||
52 | #define LTQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11) | ||
53 | #define LTQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25) | ||
54 | #define LTQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26) | ||
55 | #define LTQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27) | ||
56 | #define LTQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28) | ||
57 | #define LTQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29) | ||
58 | #define LTQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30) | ||
59 | #define LTQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16) | ||
60 | #define LTQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21) | ||
61 | |||
62 | #define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24) | ||
63 | |||
64 | #define INT_NUM_IM4_IRL14 (INT_NUM_IM4_IRL0 + 14) | ||
65 | |||
66 | #endif | ||
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h new file mode 100644 index 000000000000..8a3c6be669d2 --- /dev/null +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h | |||
@@ -0,0 +1,141 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LTQ_XWAY_H__ | ||
10 | #define _LTQ_XWAY_H__ | ||
11 | |||
12 | #ifdef CONFIG_SOC_TYPE_XWAY | ||
13 | |||
14 | #include <lantiq.h> | ||
15 | |||
16 | /* Chip IDs */ | ||
17 | #define SOC_ID_DANUBE1 0x129 | ||
18 | #define SOC_ID_DANUBE2 0x12B | ||
19 | #define SOC_ID_TWINPASS 0x12D | ||
20 | #define SOC_ID_AMAZON_SE 0x152 | ||
21 | #define SOC_ID_ARX188 0x16C | ||
22 | #define SOC_ID_ARX168 0x16D | ||
23 | #define SOC_ID_ARX182 0x16F | ||
24 | |||
25 | /* SoC Types */ | ||
26 | #define SOC_TYPE_DANUBE 0x01 | ||
27 | #define SOC_TYPE_TWINPASS 0x02 | ||
28 | #define SOC_TYPE_AR9 0x03 | ||
29 | #define SOC_TYPE_VR9 0x04 | ||
30 | #define SOC_TYPE_AMAZON_SE 0x05 | ||
31 | |||
32 | /* ASC0/1 - serial port */ | ||
33 | #define LTQ_ASC0_BASE_ADDR 0x1E100400 | ||
34 | #define LTQ_ASC1_BASE_ADDR 0x1E100C00 | ||
35 | #define LTQ_ASC_SIZE 0x400 | ||
36 | |||
37 | /* RCU - reset control unit */ | ||
38 | #define LTQ_RCU_BASE_ADDR 0x1F203000 | ||
39 | #define LTQ_RCU_SIZE 0x1000 | ||
40 | |||
41 | /* GPTU - general purpose timer unit */ | ||
42 | #define LTQ_GPTU_BASE_ADDR 0x18000300 | ||
43 | #define LTQ_GPTU_SIZE 0x100 | ||
44 | |||
45 | /* EBU - external bus unit */ | ||
46 | #define LTQ_EBU_GPIO_START 0x14000000 | ||
47 | #define LTQ_EBU_GPIO_SIZE 0x1000 | ||
48 | |||
49 | #define LTQ_EBU_BASE_ADDR 0x1E105300 | ||
50 | #define LTQ_EBU_SIZE 0x100 | ||
51 | |||
52 | #define LTQ_EBU_BUSCON0 0x0060 | ||
53 | #define LTQ_EBU_PCC_CON 0x0090 | ||
54 | #define LTQ_EBU_PCC_IEN 0x00A4 | ||
55 | #define LTQ_EBU_PCC_ISTAT 0x00A0 | ||
56 | #define LTQ_EBU_BUSCON1 0x0064 | ||
57 | #define LTQ_EBU_ADDRSEL1 0x0024 | ||
58 | #define EBU_WRDIS 0x80000000 | ||
59 | |||
60 | /* CGU - clock generation unit */ | ||
61 | #define LTQ_CGU_BASE_ADDR 0x1F103000 | ||
62 | #define LTQ_CGU_SIZE 0x1000 | ||
63 | |||
64 | /* ICU - interrupt control unit */ | ||
65 | #define LTQ_ICU_BASE_ADDR 0x1F880200 | ||
66 | #define LTQ_ICU_SIZE 0x100 | ||
67 | |||
68 | /* EIU - external interrupt unit */ | ||
69 | #define LTQ_EIU_BASE_ADDR 0x1F101000 | ||
70 | #define LTQ_EIU_SIZE 0x1000 | ||
71 | |||
72 | /* PMU - power management unit */ | ||
73 | #define LTQ_PMU_BASE_ADDR 0x1F102000 | ||
74 | #define LTQ_PMU_SIZE 0x1000 | ||
75 | |||
76 | #define PMU_DMA 0x0020 | ||
77 | #define PMU_USB 0x8041 | ||
78 | #define PMU_LED 0x0800 | ||
79 | #define PMU_GPT 0x1000 | ||
80 | #define PMU_PPE 0x2000 | ||
81 | #define PMU_FPI 0x4000 | ||
82 | #define PMU_SWITCH 0x10000000 | ||
83 | |||
84 | /* ETOP - ethernet */ | ||
85 | #define LTQ_ETOP_BASE_ADDR 0x1E180000 | ||
86 | #define LTQ_ETOP_SIZE 0x40000 | ||
87 | |||
88 | /* DMA */ | ||
89 | #define LTQ_DMA_BASE_ADDR 0x1E104100 | ||
90 | #define LTQ_DMA_SIZE 0x800 | ||
91 | |||
92 | /* PCI */ | ||
93 | #define PCI_CR_BASE_ADDR 0x1E105400 | ||
94 | #define PCI_CR_SIZE 0x400 | ||
95 | |||
96 | /* WDT */ | ||
97 | #define LTQ_WDT_BASE_ADDR 0x1F8803F0 | ||
98 | #define LTQ_WDT_SIZE 0x10 | ||
99 | |||
100 | /* STP - serial to parallel conversion unit */ | ||
101 | #define LTQ_STP_BASE_ADDR 0x1E100BB0 | ||
102 | #define LTQ_STP_SIZE 0x40 | ||
103 | |||
104 | /* GPIO */ | ||
105 | #define LTQ_GPIO0_BASE_ADDR 0x1E100B10 | ||
106 | #define LTQ_GPIO1_BASE_ADDR 0x1E100B40 | ||
107 | #define LTQ_GPIO2_BASE_ADDR 0x1E100B70 | ||
108 | #define LTQ_GPIO_SIZE 0x30 | ||
109 | |||
110 | /* SSC */ | ||
111 | #define LTQ_SSC_BASE_ADDR 0x1e100800 | ||
112 | #define LTQ_SSC_SIZE 0x100 | ||
113 | |||
114 | /* MEI - dsl core */ | ||
115 | #define LTQ_MEI_BASE_ADDR 0x1E116000 | ||
116 | |||
117 | /* DEU - data encryption unit */ | ||
118 | #define LTQ_DEU_BASE_ADDR 0x1E103100 | ||
119 | |||
120 | /* MPS - multi processor unit (voice) */ | ||
121 | #define LTQ_MPS_BASE_ADDR (KSEG1 + 0x1F107000) | ||
122 | #define LTQ_MPS_CHIPID ((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344)) | ||
123 | |||
124 | /* request a non-gpio and set the PIO config */ | ||
125 | extern int ltq_gpio_request(unsigned int pin, unsigned int alt0, | ||
126 | unsigned int alt1, unsigned int dir, const char *name); | ||
127 | extern void ltq_pmu_enable(unsigned int module); | ||
128 | extern void ltq_pmu_disable(unsigned int module); | ||
129 | |||
130 | static inline int ltq_is_ar9(void) | ||
131 | { | ||
132 | return (ltq_get_soc_type() == SOC_TYPE_AR9); | ||
133 | } | ||
134 | |||
135 | static inline int ltq_is_vr9(void) | ||
136 | { | ||
137 | return (ltq_get_soc_type() == SOC_TYPE_VR9); | ||
138 | } | ||
139 | |||
140 | #endif /* CONFIG_SOC_TYPE_XWAY */ | ||
141 | #endif /* _LTQ_XWAY_H__ */ | ||
diff --git a/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h b/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h new file mode 100644 index 000000000000..872943a4b90e --- /dev/null +++ b/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * You should have received a copy of the GNU General Public License | ||
12 | * along with this program; if not, write to the Free Software | ||
13 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
14 | * | ||
15 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | ||
16 | */ | ||
17 | |||
18 | #ifndef LTQ_DMA_H__ | ||
19 | #define LTQ_DMA_H__ | ||
20 | |||
21 | #define LTQ_DESC_SIZE 0x08 /* each descriptor is 64bit */ | ||
22 | #define LTQ_DESC_NUM 0x40 /* 64 descriptors / channel */ | ||
23 | |||
24 | #define LTQ_DMA_OWN BIT(31) /* owner bit */ | ||
25 | #define LTQ_DMA_C BIT(30) /* complete bit */ | ||
26 | #define LTQ_DMA_SOP BIT(29) /* start of packet */ | ||
27 | #define LTQ_DMA_EOP BIT(28) /* end of packet */ | ||
28 | #define LTQ_DMA_TX_OFFSET(x) ((x & 0x1f) << 23) /* data bytes offset */ | ||
29 | #define LTQ_DMA_RX_OFFSET(x) ((x & 0x7) << 23) /* data bytes offset */ | ||
30 | #define LTQ_DMA_SIZE_MASK (0xffff) /* the size field is 16 bit */ | ||
31 | |||
32 | struct ltq_dma_desc { | ||
33 | u32 ctl; | ||
34 | u32 addr; | ||
35 | }; | ||
36 | |||
37 | struct ltq_dma_channel { | ||
38 | int nr; /* the channel number */ | ||
39 | int irq; /* the mapped irq */ | ||
40 | int desc; /* the current descriptor */ | ||
41 | struct ltq_dma_desc *desc_base; /* the descriptor base */ | ||
42 | int phys; /* physical addr */ | ||
43 | }; | ||
44 | |||
45 | enum { | ||
46 | DMA_PORT_ETOP = 0, | ||
47 | DMA_PORT_DEU, | ||
48 | }; | ||
49 | |||
50 | extern void ltq_dma_enable_irq(struct ltq_dma_channel *ch); | ||
51 | extern void ltq_dma_disable_irq(struct ltq_dma_channel *ch); | ||
52 | extern void ltq_dma_ack_irq(struct ltq_dma_channel *ch); | ||
53 | extern void ltq_dma_open(struct ltq_dma_channel *ch); | ||
54 | extern void ltq_dma_close(struct ltq_dma_channel *ch); | ||
55 | extern void ltq_dma_alloc_tx(struct ltq_dma_channel *ch); | ||
56 | extern void ltq_dma_alloc_rx(struct ltq_dma_channel *ch); | ||
57 | extern void ltq_dma_free(struct ltq_dma_channel *ch); | ||
58 | extern void ltq_dma_init_port(int p); | ||
59 | |||
60 | #endif | ||
diff --git a/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h b/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h new file mode 100644 index 000000000000..3b728275b9b0 --- /dev/null +++ b/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2011 Netlogic Microsystems | ||
7 | * Copyright (C) 2003 Ralf Baechle | ||
8 | */ | ||
9 | #ifndef __ASM_MACH_NETLOGIC_CPU_FEATURE_OVERRIDES_H | ||
10 | #define __ASM_MACH_NETLOGIC_CPU_FEATURE_OVERRIDES_H | ||
11 | |||
12 | #define cpu_has_4kex 1 | ||
13 | #define cpu_has_4k_cache 1 | ||
14 | #define cpu_has_watch 1 | ||
15 | #define cpu_has_mips16 0 | ||
16 | #define cpu_has_counter 1 | ||
17 | #define cpu_has_divec 1 | ||
18 | #define cpu_has_vce 0 | ||
19 | #define cpu_has_cache_cdex_p 0 | ||
20 | #define cpu_has_cache_cdex_s 0 | ||
21 | #define cpu_has_prefetch 1 | ||
22 | #define cpu_has_mcheck 1 | ||
23 | #define cpu_has_ejtag 1 | ||
24 | |||
25 | #define cpu_has_llsc 1 | ||
26 | #define cpu_has_vtag_icache 0 | ||
27 | #define cpu_has_dc_aliases 0 | ||
28 | #define cpu_has_ic_fills_f_dc 0 | ||
29 | #define cpu_has_dsp 0 | ||
30 | #define cpu_has_mipsmt 0 | ||
31 | #define cpu_has_userlocal 0 | ||
32 | #define cpu_icache_snoops_remote_store 0 | ||
33 | |||
34 | #define cpu_has_nofpuex 0 | ||
35 | #define cpu_has_64bits 1 | ||
36 | |||
37 | #define cpu_has_mips32r1 1 | ||
38 | #define cpu_has_mips32r2 0 | ||
39 | #define cpu_has_mips64r1 1 | ||
40 | #define cpu_has_mips64r2 0 | ||
41 | |||
42 | #define cpu_has_inclusive_pcaches 0 | ||
43 | |||
44 | #define cpu_dcache_line_size() 32 | ||
45 | #define cpu_icache_line_size() 32 | ||
46 | |||
47 | #endif /* __ASM_MACH_NETLOGIC_CPU_FEATURE_OVERRIDES_H */ | ||
diff --git a/arch/mips/include/asm/mach-netlogic/irq.h b/arch/mips/include/asm/mach-netlogic/irq.h new file mode 100644 index 000000000000..b5902458e7c1 --- /dev/null +++ b/arch/mips/include/asm/mach-netlogic/irq.h | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2011 Netlogic Microsystems. | ||
7 | */ | ||
8 | #ifndef __ASM_NETLOGIC_IRQ_H | ||
9 | #define __ASM_NETLOGIC_IRQ_H | ||
10 | |||
11 | #define NR_IRQS 64 | ||
12 | #define MIPS_CPU_IRQ_BASE 0 | ||
13 | |||
14 | #endif /* __ASM_NETLOGIC_IRQ_H */ | ||
diff --git a/arch/mips/include/asm/mach-netlogic/war.h b/arch/mips/include/asm/mach-netlogic/war.h new file mode 100644 index 000000000000..22da89327352 --- /dev/null +++ b/arch/mips/include/asm/mach-netlogic/war.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2011 Netlogic Microsystems. | ||
7 | * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> | ||
8 | */ | ||
9 | #ifndef __ASM_MIPS_MACH_NLM_WAR_H | ||
10 | #define __ASM_MIPS_MACH_NLM_WAR_H | ||
11 | |||
12 | #define R4600_V1_INDEX_ICACHEOP_WAR 0 | ||
13 | #define R4600_V1_HIT_CACHEOP_WAR 0 | ||
14 | #define R4600_V2_HIT_CACHEOP_WAR 0 | ||
15 | #define R5432_CP0_INTERRUPT_WAR 0 | ||
16 | #define BCM1250_M3_WAR 0 | ||
17 | #define SIBYTE_1956_WAR 0 | ||
18 | #define MIPS4K_ICACHE_REFILL_WAR 0 | ||
19 | #define MIPS_CACHE_SYNC_WAR 0 | ||
20 | #define TX49XX_ICACHE_INDEX_INV_WAR 0 | ||
21 | #define RM9000_CDEX_SMP_WAR 0 | ||
22 | #define ICACHE_REFILLS_WORKAROUND_WAR 0 | ||
23 | #define R10000_LLSC_WAR 0 | ||
24 | #define MIPS34K_MISSED_ITLB_WAR 0 | ||
25 | |||
26 | #endif /* __ASM_MIPS_MACH_NLM_WAR_H */ | ||
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h index d94085a3eafb..bc01a02cacd8 100644 --- a/arch/mips/include/asm/module.h +++ b/arch/mips/include/asm/module.h | |||
@@ -118,6 +118,8 @@ search_module_dbetables(unsigned long addr) | |||
118 | #define MODULE_PROC_FAMILY "LOONGSON2 " | 118 | #define MODULE_PROC_FAMILY "LOONGSON2 " |
119 | #elif defined CONFIG_CPU_CAVIUM_OCTEON | 119 | #elif defined CONFIG_CPU_CAVIUM_OCTEON |
120 | #define MODULE_PROC_FAMILY "OCTEON " | 120 | #define MODULE_PROC_FAMILY "OCTEON " |
121 | #elif defined CONFIG_CPU_XLR | ||
122 | #define MODULE_PROC_FAMILY "XLR " | ||
121 | #else | 123 | #else |
122 | #error MODULE_PROC_FAMILY undefined for your processor configuration | 124 | #error MODULE_PROC_FAMILY undefined for your processor configuration |
123 | #endif | 125 | #endif |
diff --git a/arch/mips/include/asm/netlogic/interrupt.h b/arch/mips/include/asm/netlogic/interrupt.h new file mode 100644 index 000000000000..a85aadb6cfd7 --- /dev/null +++ b/arch/mips/include/asm/netlogic/interrupt.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the NetLogic | ||
9 | * license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in | ||
19 | * the documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR | ||
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #ifndef _ASM_NLM_INTERRUPT_H | ||
36 | #define _ASM_NLM_INTERRUPT_H | ||
37 | |||
38 | /* Defines for the IRQ numbers */ | ||
39 | |||
40 | #define IRQ_IPI_SMP_FUNCTION 3 | ||
41 | #define IRQ_IPI_SMP_RESCHEDULE 4 | ||
42 | #define IRQ_MSGRING 6 | ||
43 | #define IRQ_TIMER 7 | ||
44 | |||
45 | #endif | ||
diff --git a/arch/mips/include/asm/netlogic/mips-extns.h b/arch/mips/include/asm/netlogic/mips-extns.h new file mode 100644 index 000000000000..8c53d0ba4bf2 --- /dev/null +++ b/arch/mips/include/asm/netlogic/mips-extns.h | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the NetLogic | ||
9 | * license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in | ||
19 | * the documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR | ||
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #ifndef _ASM_NLM_MIPS_EXTS_H | ||
36 | #define _ASM_NLM_MIPS_EXTS_H | ||
37 | |||
38 | /* | ||
39 | * XLR and XLP interrupt request and interrupt mask registers | ||
40 | */ | ||
41 | #define read_c0_eirr() __read_64bit_c0_register($9, 6) | ||
42 | #define read_c0_eimr() __read_64bit_c0_register($9, 7) | ||
43 | #define write_c0_eirr(val) __write_64bit_c0_register($9, 6, val) | ||
44 | |||
45 | /* | ||
46 | * Writing EIMR in 32 bit is a special case, the lower 8 bit of the | ||
47 | * EIMR is shadowed in the status register, so we cannot save and | ||
48 | * restore status register for split read. | ||
49 | */ | ||
50 | #define write_c0_eimr(val) \ | ||
51 | do { \ | ||
52 | if (sizeof(unsigned long) == 4) { \ | ||
53 | unsigned long __flags; \ | ||
54 | \ | ||
55 | local_irq_save(__flags); \ | ||
56 | __asm__ __volatile__( \ | ||
57 | ".set\tmips64\n\t" \ | ||
58 | "dsll\t%L0, %L0, 32\n\t" \ | ||
59 | "dsrl\t%L0, %L0, 32\n\t" \ | ||
60 | "dsll\t%M0, %M0, 32\n\t" \ | ||
61 | "or\t%L0, %L0, %M0\n\t" \ | ||
62 | "dmtc0\t%L0, $9, 7\n\t" \ | ||
63 | ".set\tmips0" \ | ||
64 | : : "r" (val)); \ | ||
65 | __flags = (__flags & 0xffff00ff) | (((val) & 0xff) << 8);\ | ||
66 | local_irq_restore(__flags); \ | ||
67 | } else \ | ||
68 | __write_64bit_c0_register($9, 7, (val)); \ | ||
69 | } while (0) | ||
70 | |||
71 | static inline int hard_smp_processor_id(void) | ||
72 | { | ||
73 | return __read_32bit_c0_register($15, 1) & 0x3ff; | ||
74 | } | ||
75 | |||
76 | #endif /*_ASM_NLM_MIPS_EXTS_H */ | ||
diff --git a/arch/mips/include/asm/netlogic/psb-bootinfo.h b/arch/mips/include/asm/netlogic/psb-bootinfo.h new file mode 100644 index 000000000000..6878307f0ee6 --- /dev/null +++ b/arch/mips/include/asm/netlogic/psb-bootinfo.h | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the NetLogic | ||
9 | * license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in | ||
19 | * the documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR | ||
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #ifndef _ASM_NETLOGIC_BOOTINFO_H | ||
36 | #define _ASM_NETLOGIC_BOOTINFO_H | ||
37 | |||
38 | struct psb_info { | ||
39 | uint64_t boot_level; | ||
40 | uint64_t io_base; | ||
41 | uint64_t output_device; | ||
42 | uint64_t uart_print; | ||
43 | uint64_t led_output; | ||
44 | uint64_t init; | ||
45 | uint64_t exit; | ||
46 | uint64_t warm_reset; | ||
47 | uint64_t wakeup; | ||
48 | uint64_t online_cpu_map; | ||
49 | uint64_t master_reentry_sp; | ||
50 | uint64_t master_reentry_gp; | ||
51 | uint64_t master_reentry_fn; | ||
52 | uint64_t slave_reentry_fn; | ||
53 | uint64_t magic_dword; | ||
54 | uint64_t uart_putchar; | ||
55 | uint64_t size; | ||
56 | uint64_t uart_getchar; | ||
57 | uint64_t nmi_handler; | ||
58 | uint64_t psb_version; | ||
59 | uint64_t mac_addr; | ||
60 | uint64_t cpu_frequency; | ||
61 | uint64_t board_version; | ||
62 | uint64_t malloc; | ||
63 | uint64_t free; | ||
64 | uint64_t global_shmem_addr; | ||
65 | uint64_t global_shmem_size; | ||
66 | uint64_t psb_os_cpu_map; | ||
67 | uint64_t userapp_cpu_map; | ||
68 | uint64_t wakeup_os; | ||
69 | uint64_t psb_mem_map; | ||
70 | uint64_t board_major_version; | ||
71 | uint64_t board_minor_version; | ||
72 | uint64_t board_manf_revision; | ||
73 | uint64_t board_serial_number; | ||
74 | uint64_t psb_physaddr_map; | ||
75 | uint64_t xlr_loaderip_config; | ||
76 | uint64_t bldr_envp; | ||
77 | uint64_t avail_mem_map; | ||
78 | }; | ||
79 | |||
80 | enum { | ||
81 | NETLOGIC_IO_SPACE = 0x10, | ||
82 | PCIX_IO_SPACE, | ||
83 | PCIX_CFG_SPACE, | ||
84 | PCIX_MEMORY_SPACE, | ||
85 | HT_IO_SPACE, | ||
86 | HT_CFG_SPACE, | ||
87 | HT_MEMORY_SPACE, | ||
88 | SRAM_SPACE, | ||
89 | FLASH_CONTROLLER_SPACE | ||
90 | }; | ||
91 | |||
92 | #define NLM_MAX_ARGS 64 | ||
93 | #define NLM_MAX_ENVS 32 | ||
94 | |||
95 | /* This is what netlboot passes and linux boot_mem_map is subtly different */ | ||
96 | #define NLM_BOOT_MEM_MAP_MAX 32 | ||
97 | struct nlm_boot_mem_map { | ||
98 | int nr_map; | ||
99 | struct nlm_boot_mem_map_entry { | ||
100 | uint64_t addr; /* start of memory segment */ | ||
101 | uint64_t size; /* size of memory segment */ | ||
102 | uint32_t type; /* type of memory segment */ | ||
103 | } map[NLM_BOOT_MEM_MAP_MAX]; | ||
104 | }; | ||
105 | |||
106 | /* Pointer to saved boot loader info */ | ||
107 | extern struct psb_info nlm_prom_info; | ||
108 | |||
109 | #endif | ||
diff --git a/arch/mips/include/asm/netlogic/xlr/gpio.h b/arch/mips/include/asm/netlogic/xlr/gpio.h new file mode 100644 index 000000000000..51f6ad4aeb14 --- /dev/null +++ b/arch/mips/include/asm/netlogic/xlr/gpio.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the NetLogic | ||
9 | * license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in | ||
19 | * the documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR | ||
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #ifndef _ASM_NLM_GPIO_H | ||
36 | #define _ASM_NLM_GPIO_H | ||
37 | |||
38 | #define NETLOGIC_GPIO_INT_EN_REG 0 | ||
39 | #define NETLOGIC_GPIO_INPUT_INVERSION_REG 1 | ||
40 | #define NETLOGIC_GPIO_IO_DIR_REG 2 | ||
41 | #define NETLOGIC_GPIO_IO_DATA_WR_REG 3 | ||
42 | #define NETLOGIC_GPIO_IO_DATA_RD_REG 4 | ||
43 | |||
44 | #define NETLOGIC_GPIO_SWRESET_REG 8 | ||
45 | #define NETLOGIC_GPIO_DRAM1_CNTRL_REG 9 | ||
46 | #define NETLOGIC_GPIO_DRAM1_RATIO_REG 10 | ||
47 | #define NETLOGIC_GPIO_DRAM1_RESET_REG 11 | ||
48 | #define NETLOGIC_GPIO_DRAM1_STATUS_REG 12 | ||
49 | #define NETLOGIC_GPIO_DRAM2_CNTRL_REG 13 | ||
50 | #define NETLOGIC_GPIO_DRAM2_RATIO_REG 14 | ||
51 | #define NETLOGIC_GPIO_DRAM2_RESET_REG 15 | ||
52 | #define NETLOGIC_GPIO_DRAM2_STATUS_REG 16 | ||
53 | |||
54 | #define NETLOGIC_GPIO_PWRON_RESET_CFG_REG 21 | ||
55 | #define NETLOGIC_GPIO_BIST_ALL_GO_STATUS_REG 24 | ||
56 | #define NETLOGIC_GPIO_BIST_CPU_GO_STATUS_REG 25 | ||
57 | #define NETLOGIC_GPIO_BIST_DEV_GO_STATUS_REG 26 | ||
58 | |||
59 | #define NETLOGIC_GPIO_FUSE_BANK_REG 35 | ||
60 | #define NETLOGIC_GPIO_CPU_RESET_REG 40 | ||
61 | #define NETLOGIC_GPIO_RNG_REG 43 | ||
62 | |||
63 | #define NETLOGIC_PWRON_RESET_PCMCIA_BOOT 17 | ||
64 | #define NETLOGIC_GPIO_LED_BITMAP 0x1700000 | ||
65 | #define NETLOGIC_GPIO_LED_0_SHIFT 20 | ||
66 | #define NETLOGIC_GPIO_LED_1_SHIFT 24 | ||
67 | |||
68 | #define NETLOGIC_GPIO_LED_OUTPUT_CODE_RESET 0x01 | ||
69 | #define NETLOGIC_GPIO_LED_OUTPUT_CODE_HARD_RESET 0x02 | ||
70 | #define NETLOGIC_GPIO_LED_OUTPUT_CODE_SOFT_RESET 0x03 | ||
71 | #define NETLOGIC_GPIO_LED_OUTPUT_CODE_MAIN 0x04 | ||
72 | |||
73 | #endif | ||
diff --git a/arch/mips/include/asm/netlogic/xlr/iomap.h b/arch/mips/include/asm/netlogic/xlr/iomap.h new file mode 100644 index 000000000000..2e3a4dd53045 --- /dev/null +++ b/arch/mips/include/asm/netlogic/xlr/iomap.h | |||
@@ -0,0 +1,131 @@ | |||
1 | /* | ||
2 | * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the NetLogic | ||
9 | * license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in | ||
19 | * the documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR | ||
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #ifndef _ASM_NLM_IOMAP_H | ||
36 | #define _ASM_NLM_IOMAP_H | ||
37 | |||
38 | #define DEFAULT_NETLOGIC_IO_BASE CKSEG1ADDR(0x1ef00000) | ||
39 | #define NETLOGIC_IO_DDR2_CHN0_OFFSET 0x01000 | ||
40 | #define NETLOGIC_IO_DDR2_CHN1_OFFSET 0x02000 | ||
41 | #define NETLOGIC_IO_DDR2_CHN2_OFFSET 0x03000 | ||
42 | #define NETLOGIC_IO_DDR2_CHN3_OFFSET 0x04000 | ||
43 | #define NETLOGIC_IO_PIC_OFFSET 0x08000 | ||
44 | #define NETLOGIC_IO_UART_0_OFFSET 0x14000 | ||
45 | #define NETLOGIC_IO_UART_1_OFFSET 0x15100 | ||
46 | |||
47 | #define NETLOGIC_IO_SIZE 0x1000 | ||
48 | |||
49 | #define NETLOGIC_IO_BRIDGE_OFFSET 0x00000 | ||
50 | |||
51 | #define NETLOGIC_IO_RLD2_CHN0_OFFSET 0x05000 | ||
52 | #define NETLOGIC_IO_RLD2_CHN1_OFFSET 0x06000 | ||
53 | |||
54 | #define NETLOGIC_IO_SRAM_OFFSET 0x07000 | ||
55 | |||
56 | #define NETLOGIC_IO_PCIX_OFFSET 0x09000 | ||
57 | #define NETLOGIC_IO_HT_OFFSET 0x0A000 | ||
58 | |||
59 | #define NETLOGIC_IO_SECURITY_OFFSET 0x0B000 | ||
60 | |||
61 | #define NETLOGIC_IO_GMAC_0_OFFSET 0x0C000 | ||
62 | #define NETLOGIC_IO_GMAC_1_OFFSET 0x0D000 | ||
63 | #define NETLOGIC_IO_GMAC_2_OFFSET 0x0E000 | ||
64 | #define NETLOGIC_IO_GMAC_3_OFFSET 0x0F000 | ||
65 | |||
66 | /* XLS devices */ | ||
67 | #define NETLOGIC_IO_GMAC_4_OFFSET 0x20000 | ||
68 | #define NETLOGIC_IO_GMAC_5_OFFSET 0x21000 | ||
69 | #define NETLOGIC_IO_GMAC_6_OFFSET 0x22000 | ||
70 | #define NETLOGIC_IO_GMAC_7_OFFSET 0x23000 | ||
71 | |||
72 | #define NETLOGIC_IO_PCIE_0_OFFSET 0x1E000 | ||
73 | #define NETLOGIC_IO_PCIE_1_OFFSET 0x1F000 | ||
74 | #define NETLOGIC_IO_SRIO_0_OFFSET 0x1E000 | ||
75 | #define NETLOGIC_IO_SRIO_1_OFFSET 0x1F000 | ||
76 | |||
77 | #define NETLOGIC_IO_USB_0_OFFSET 0x24000 | ||
78 | #define NETLOGIC_IO_USB_1_OFFSET 0x25000 | ||
79 | |||
80 | #define NETLOGIC_IO_COMP_OFFSET 0x1D000 | ||
81 | /* end XLS devices */ | ||
82 | |||
83 | /* XLR devices */ | ||
84 | #define NETLOGIC_IO_SPI4_0_OFFSET 0x10000 | ||
85 | #define NETLOGIC_IO_XGMAC_0_OFFSET 0x11000 | ||
86 | #define NETLOGIC_IO_SPI4_1_OFFSET 0x12000 | ||
87 | #define NETLOGIC_IO_XGMAC_1_OFFSET 0x13000 | ||
88 | /* end XLR devices */ | ||
89 | |||
90 | #define NETLOGIC_IO_I2C_0_OFFSET 0x16000 | ||
91 | #define NETLOGIC_IO_I2C_1_OFFSET 0x17000 | ||
92 | |||
93 | #define NETLOGIC_IO_GPIO_OFFSET 0x18000 | ||
94 | #define NETLOGIC_IO_FLASH_OFFSET 0x19000 | ||
95 | #define NETLOGIC_IO_TB_OFFSET 0x1C000 | ||
96 | |||
97 | #define NETLOGIC_CPLD_OFFSET KSEG1ADDR(0x1d840000) | ||
98 | |||
99 | /* | ||
100 | * Base Address (Virtual) of the PCI Config address space | ||
101 | * For now, choose 256M phys in kseg1 = 0xA0000000 + (1<<28) | ||
102 | * Config space spans 256 (num of buses) * 256 (num functions) * 256 bytes | ||
103 | * ie 1<<24 = 16M | ||
104 | */ | ||
105 | #define DEFAULT_PCI_CONFIG_BASE 0x18000000 | ||
106 | #define DEFAULT_HT_TYPE0_CFG_BASE 0x16000000 | ||
107 | #define DEFAULT_HT_TYPE1_CFG_BASE 0x17000000 | ||
108 | |||
109 | #ifndef __ASSEMBLY__ | ||
110 | #include <linux/types.h> | ||
111 | #include <asm/byteorder.h> | ||
112 | |||
113 | typedef volatile __u32 nlm_reg_t; | ||
114 | extern unsigned long netlogic_io_base; | ||
115 | |||
116 | /* FIXME read once in write_reg */ | ||
117 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
118 | #define netlogic_read_reg(base, offset) ((base)[(offset)]) | ||
119 | #define netlogic_write_reg(base, offset, value) ((base)[(offset)] = (value)) | ||
120 | #else | ||
121 | #define netlogic_read_reg(base, offset) (be32_to_cpu((base)[(offset)])) | ||
122 | #define netlogic_write_reg(base, offset, value) \ | ||
123 | ((base)[(offset)] = cpu_to_be32((value))) | ||
124 | #endif | ||
125 | |||
126 | #define netlogic_read_reg_le32(base, offset) (le32_to_cpu((base)[(offset)])) | ||
127 | #define netlogic_write_reg_le32(base, offset, value) \ | ||
128 | ((base)[(offset)] = cpu_to_le32((value))) | ||
129 | #define netlogic_io_mmio(offset) ((nlm_reg_t *)(netlogic_io_base+(offset))) | ||
130 | #endif /* __ASSEMBLY__ */ | ||
131 | #endif | ||
diff --git a/arch/mips/include/asm/netlogic/xlr/pic.h b/arch/mips/include/asm/netlogic/xlr/pic.h new file mode 100644 index 000000000000..5cceb746f080 --- /dev/null +++ b/arch/mips/include/asm/netlogic/xlr/pic.h | |||
@@ -0,0 +1,231 @@ | |||
1 | /* | ||
2 | * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the NetLogic | ||
9 | * license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in | ||
19 | * the documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR | ||
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #ifndef _ASM_NLM_XLR_PIC_H | ||
36 | #define _ASM_NLM_XLR_PIC_H | ||
37 | |||
38 | #define PIC_CLKS_PER_SEC 66666666ULL | ||
39 | /* PIC hardware interrupt numbers */ | ||
40 | #define PIC_IRT_WD_INDEX 0 | ||
41 | #define PIC_IRT_TIMER_0_INDEX 1 | ||
42 | #define PIC_IRT_TIMER_1_INDEX 2 | ||
43 | #define PIC_IRT_TIMER_2_INDEX 3 | ||
44 | #define PIC_IRT_TIMER_3_INDEX 4 | ||
45 | #define PIC_IRT_TIMER_4_INDEX 5 | ||
46 | #define PIC_IRT_TIMER_5_INDEX 6 | ||
47 | #define PIC_IRT_TIMER_6_INDEX 7 | ||
48 | #define PIC_IRT_TIMER_7_INDEX 8 | ||
49 | #define PIC_IRT_CLOCK_INDEX PIC_IRT_TIMER_7_INDEX | ||
50 | #define PIC_IRT_UART_0_INDEX 9 | ||
51 | #define PIC_IRT_UART_1_INDEX 10 | ||
52 | #define PIC_IRT_I2C_0_INDEX 11 | ||
53 | #define PIC_IRT_I2C_1_INDEX 12 | ||
54 | #define PIC_IRT_PCMCIA_INDEX 13 | ||
55 | #define PIC_IRT_GPIO_INDEX 14 | ||
56 | #define PIC_IRT_HYPER_INDEX 15 | ||
57 | #define PIC_IRT_PCIX_INDEX 16 | ||
58 | /* XLS */ | ||
59 | #define PIC_IRT_CDE_INDEX 15 | ||
60 | #define PIC_IRT_BRIDGE_TB_XLS_INDEX 16 | ||
61 | /* XLS */ | ||
62 | #define PIC_IRT_GMAC0_INDEX 17 | ||
63 | #define PIC_IRT_GMAC1_INDEX 18 | ||
64 | #define PIC_IRT_GMAC2_INDEX 19 | ||
65 | #define PIC_IRT_GMAC3_INDEX 20 | ||
66 | #define PIC_IRT_XGS0_INDEX 21 | ||
67 | #define PIC_IRT_XGS1_INDEX 22 | ||
68 | #define PIC_IRT_HYPER_FATAL_INDEX 23 | ||
69 | #define PIC_IRT_PCIX_FATAL_INDEX 24 | ||
70 | #define PIC_IRT_BRIDGE_AERR_INDEX 25 | ||
71 | #define PIC_IRT_BRIDGE_BERR_INDEX 26 | ||
72 | #define PIC_IRT_BRIDGE_TB_XLR_INDEX 27 | ||
73 | #define PIC_IRT_BRIDGE_AERR_NMI_INDEX 28 | ||
74 | /* XLS */ | ||
75 | #define PIC_IRT_GMAC4_INDEX 21 | ||
76 | #define PIC_IRT_GMAC5_INDEX 22 | ||
77 | #define PIC_IRT_GMAC6_INDEX 23 | ||
78 | #define PIC_IRT_GMAC7_INDEX 24 | ||
79 | #define PIC_IRT_BRIDGE_ERR_INDEX 25 | ||
80 | #define PIC_IRT_PCIE_LINK0_INDEX 26 | ||
81 | #define PIC_IRT_PCIE_LINK1_INDEX 27 | ||
82 | #define PIC_IRT_PCIE_LINK2_INDEX 23 | ||
83 | #define PIC_IRT_PCIE_LINK3_INDEX 24 | ||
84 | #define PIC_IRT_PCIE_XLSB0_LINK2_INDEX 28 | ||
85 | #define PIC_IRT_PCIE_XLSB0_LINK3_INDEX 29 | ||
86 | #define PIC_IRT_SRIO_LINK0_INDEX 26 | ||
87 | #define PIC_IRT_SRIO_LINK1_INDEX 27 | ||
88 | #define PIC_IRT_SRIO_LINK2_INDEX 28 | ||
89 | #define PIC_IRT_SRIO_LINK3_INDEX 29 | ||
90 | #define PIC_IRT_PCIE_INT_INDEX 28 | ||
91 | #define PIC_IRT_PCIE_FATAL_INDEX 29 | ||
92 | #define PIC_IRT_GPIO_B_INDEX 30 | ||
93 | #define PIC_IRT_USB_INDEX 31 | ||
94 | /* XLS */ | ||
95 | #define PIC_NUM_IRTS 32 | ||
96 | |||
97 | |||
98 | #define PIC_CLOCK_TIMER 7 | ||
99 | |||
100 | /* PIC Registers */ | ||
101 | #define PIC_CTRL 0x00 | ||
102 | #define PIC_IPI 0x04 | ||
103 | #define PIC_INT_ACK 0x06 | ||
104 | |||
105 | #define WD_MAX_VAL_0 0x08 | ||
106 | #define WD_MAX_VAL_1 0x09 | ||
107 | #define WD_MASK_0 0x0a | ||
108 | #define WD_MASK_1 0x0b | ||
109 | #define WD_HEARBEAT_0 0x0c | ||
110 | #define WD_HEARBEAT_1 0x0d | ||
111 | |||
112 | #define PIC_IRT_0_BASE 0x40 | ||
113 | #define PIC_IRT_1_BASE 0x80 | ||
114 | #define PIC_TIMER_MAXVAL_0_BASE 0x100 | ||
115 | #define PIC_TIMER_MAXVAL_1_BASE 0x110 | ||
116 | #define PIC_TIMER_COUNT_0_BASE 0x120 | ||
117 | #define PIC_TIMER_COUNT_1_BASE 0x130 | ||
118 | |||
119 | #define PIC_IRT_0(picintr) (PIC_IRT_0_BASE + (picintr)) | ||
120 | #define PIC_IRT_1(picintr) (PIC_IRT_1_BASE + (picintr)) | ||
121 | |||
122 | #define PIC_TIMER_MAXVAL_0(i) (PIC_TIMER_MAXVAL_0_BASE + (i)) | ||
123 | #define PIC_TIMER_MAXVAL_1(i) (PIC_TIMER_MAXVAL_1_BASE + (i)) | ||
124 | #define PIC_TIMER_COUNT_0(i) (PIC_TIMER_COUNT_0_BASE + (i)) | ||
125 | #define PIC_TIMER_COUNT_1(i) (PIC_TIMER_COUNT_0_BASE + (i)) | ||
126 | |||
127 | /* | ||
128 | * Mapping between hardware interrupt numbers and IRQs on CPU | ||
129 | * we use a simple scheme to map PIC interrupts 0-31 to IRQs | ||
130 | * 8-39. This leaves the IRQ 0-7 for cpu interrupts like | ||
131 | * count/compare and FMN | ||
132 | */ | ||
133 | #define PIC_IRQ_BASE 8 | ||
134 | #define PIC_INTR_TO_IRQ(i) (PIC_IRQ_BASE + (i)) | ||
135 | #define PIC_IRQ_TO_INTR(i) ((i) - PIC_IRQ_BASE) | ||
136 | |||
137 | #define PIC_IRT_FIRST_IRQ PIC_IRQ_BASE | ||
138 | #define PIC_WD_IRQ PIC_INTR_TO_IRQ(PIC_IRT_WD_INDEX) | ||
139 | #define PIC_TIMER_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_0_INDEX) | ||
140 | #define PIC_TIMER_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_1_INDEX) | ||
141 | #define PIC_TIMER_2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_2_INDEX) | ||
142 | #define PIC_TIMER_3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_3_INDEX) | ||
143 | #define PIC_TIMER_4_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_4_INDEX) | ||
144 | #define PIC_TIMER_5_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_5_INDEX) | ||
145 | #define PIC_TIMER_6_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_6_INDEX) | ||
146 | #define PIC_TIMER_7_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_7_INDEX) | ||
147 | #define PIC_CLOCK_IRQ (PIC_TIMER_7_IRQ) | ||
148 | #define PIC_UART_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_UART_0_INDEX) | ||
149 | #define PIC_UART_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_UART_1_INDEX) | ||
150 | #define PIC_I2C_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_I2C_0_INDEX) | ||
151 | #define PIC_I2C_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_I2C_1_INDEX) | ||
152 | #define PIC_PCMCIA_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCMCIA_INDEX) | ||
153 | #define PIC_GPIO_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GPIO_INDEX) | ||
154 | #define PIC_HYPER_IRQ PIC_INTR_TO_IRQ(PIC_IRT_HYPER_INDEX) | ||
155 | #define PIC_PCIX_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIX_INDEX) | ||
156 | /* XLS */ | ||
157 | #define PIC_CDE_IRQ PIC_INTR_TO_IRQ(PIC_IRT_CDE_INDEX) | ||
158 | #define PIC_BRIDGE_TB_XLS_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_TB_XLS_INDEX) | ||
159 | /* end XLS */ | ||
160 | #define PIC_GMAC_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC0_INDEX) | ||
161 | #define PIC_GMAC_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC1_INDEX) | ||
162 | #define PIC_GMAC_2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC2_INDEX) | ||
163 | #define PIC_GMAC_3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC3_INDEX) | ||
164 | #define PIC_XGS_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_XGS0_INDEX) | ||
165 | #define PIC_XGS_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_XGS1_INDEX) | ||
166 | #define PIC_HYPER_FATAL_IRQ PIC_INTR_TO_IRQ(PIC_IRT_HYPER_FATAL_INDEX) | ||
167 | #define PIC_PCIX_FATAL_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIX_FATAL_INDEX) | ||
168 | #define PIC_BRIDGE_AERR_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_AERR_INDEX) | ||
169 | #define PIC_BRIDGE_BERR_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_BERR_INDEX) | ||
170 | #define PIC_BRIDGE_TB_XLR_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_TB_XLR_INDEX) | ||
171 | #define PIC_BRIDGE_AERR_NMI_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_AERR_NMI_INDEX) | ||
172 | /* XLS defines */ | ||
173 | #define PIC_GMAC_4_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC4_INDEX) | ||
174 | #define PIC_GMAC_5_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC5_INDEX) | ||
175 | #define PIC_GMAC_6_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC6_INDEX) | ||
176 | #define PIC_GMAC_7_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC7_INDEX) | ||
177 | #define PIC_BRIDGE_ERR_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_ERR_INDEX) | ||
178 | #define PIC_PCIE_LINK0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK0_INDEX) | ||
179 | #define PIC_PCIE_LINK1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK1_INDEX) | ||
180 | #define PIC_PCIE_LINK2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK2_INDEX) | ||
181 | #define PIC_PCIE_LINK3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK3_INDEX) | ||
182 | #define PIC_PCIE_XLSB0_LINK2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_XLSB0_LINK2_INDEX) | ||
183 | #define PIC_PCIE_XLSB0_LINK3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_XLSB0_LINK3_INDEX) | ||
184 | #define PIC_SRIO_LINK0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK0_INDEX) | ||
185 | #define PIC_SRIO_LINK1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK1_INDEX) | ||
186 | #define PIC_SRIO_LINK2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK2_INDEX) | ||
187 | #define PIC_SRIO_LINK3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK3_INDEX) | ||
188 | #define PIC_PCIE_INT_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_INT__INDEX) | ||
189 | #define PIC_PCIE_FATAL_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_FATAL_INDEX) | ||
190 | #define PIC_GPIO_B_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GPIO_B_INDEX) | ||
191 | #define PIC_USB_IRQ PIC_INTR_TO_IRQ(PIC_IRT_USB_INDEX) | ||
192 | #define PIC_IRT_LAST_IRQ PIC_USB_IRQ | ||
193 | /* end XLS */ | ||
194 | |||
195 | #ifndef __ASSEMBLY__ | ||
196 | static inline void pic_send_ipi(u32 ipi) | ||
197 | { | ||
198 | nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET); | ||
199 | |||
200 | netlogic_write_reg(mmio, PIC_IPI, ipi); | ||
201 | } | ||
202 | |||
203 | static inline u32 pic_read_control(void) | ||
204 | { | ||
205 | nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET); | ||
206 | |||
207 | return netlogic_read_reg(mmio, PIC_CTRL); | ||
208 | } | ||
209 | |||
210 | static inline void pic_write_control(u32 control) | ||
211 | { | ||
212 | nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET); | ||
213 | |||
214 | netlogic_write_reg(mmio, PIC_CTRL, control); | ||
215 | } | ||
216 | |||
217 | static inline void pic_update_control(u32 control) | ||
218 | { | ||
219 | nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET); | ||
220 | |||
221 | netlogic_write_reg(mmio, PIC_CTRL, | ||
222 | (control | netlogic_read_reg(mmio, PIC_CTRL))); | ||
223 | } | ||
224 | |||
225 | #define PIC_IRQ_IS_EDGE_TRIGGERED(irq) (((irq) >= PIC_TIMER_0_IRQ) && \ | ||
226 | ((irq) <= PIC_TIMER_7_IRQ)) | ||
227 | #define PIC_IRQ_IS_IRT(irq) (((irq) >= PIC_IRT_FIRST_IRQ) && \ | ||
228 | ((irq) <= PIC_IRT_LAST_IRQ)) | ||
229 | #endif | ||
230 | |||
231 | #endif /* _ASM_NLM_XLR_PIC_H */ | ||
diff --git a/arch/mips/include/asm/netlogic/xlr/xlr.h b/arch/mips/include/asm/netlogic/xlr/xlr.h new file mode 100644 index 000000000000..3e6372692a04 --- /dev/null +++ b/arch/mips/include/asm/netlogic/xlr/xlr.h | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the NetLogic | ||
9 | * license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in | ||
19 | * the documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR | ||
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #ifndef _ASM_NLM_XLR_H | ||
36 | #define _ASM_NLM_XLR_H | ||
37 | |||
38 | /* Platform UART functions */ | ||
39 | struct uart_port; | ||
40 | unsigned int nlm_xlr_uart_in(struct uart_port *, int); | ||
41 | void nlm_xlr_uart_out(struct uart_port *, int, int); | ||
42 | |||
43 | /* SMP support functions */ | ||
44 | struct irq_desc; | ||
45 | void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc); | ||
46 | void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc); | ||
47 | int nlm_wakeup_secondary_cpus(u32 wakeup_mask); | ||
48 | void nlm_smp_irq_init(void); | ||
49 | void nlm_boot_smp_nmi(void); | ||
50 | void prom_pre_boot_secondary_cpus(void); | ||
51 | |||
52 | extern struct plat_smp_ops nlm_smp_ops; | ||
53 | extern unsigned long nlm_common_ebase; | ||
54 | |||
55 | /* XLS B silicon "Rook" */ | ||
56 | static inline unsigned int nlm_chip_is_xls_b(void) | ||
57 | { | ||
58 | uint32_t prid = read_c0_prid(); | ||
59 | |||
60 | return ((prid & 0xf000) == 0x4000); | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * XLR chip types | ||
65 | */ | ||
66 | /* The XLS product line has chip versions 0x[48c]? */ | ||
67 | static inline unsigned int nlm_chip_is_xls(void) | ||
68 | { | ||
69 | uint32_t prid = read_c0_prid(); | ||
70 | |||
71 | return ((prid & 0xf000) == 0x8000 || (prid & 0xf000) == 0x4000 || | ||
72 | (prid & 0xf000) == 0xc000); | ||
73 | } | ||
74 | |||
75 | #endif /* _ASM_NLM_XLR_H */ | ||
diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h index 9f1b8dba2c81..de39b1f343ea 100644 --- a/arch/mips/include/asm/ptrace.h +++ b/arch/mips/include/asm/ptrace.h | |||
@@ -141,7 +141,8 @@ extern int ptrace_set_watch_regs(struct task_struct *child, | |||
141 | #define instruction_pointer(regs) ((regs)->cp0_epc) | 141 | #define instruction_pointer(regs) ((regs)->cp0_epc) |
142 | #define profile_pc(regs) instruction_pointer(regs) | 142 | #define profile_pc(regs) instruction_pointer(regs) |
143 | 143 | ||
144 | extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit); | 144 | extern asmlinkage void syscall_trace_enter(struct pt_regs *regs); |
145 | extern asmlinkage void syscall_trace_leave(struct pt_regs *regs); | ||
145 | 146 | ||
146 | extern NORET_TYPE void die(const char *, struct pt_regs *) ATTRIB_NORET; | 147 | extern NORET_TYPE void die(const char *, struct pt_regs *) ATTRIB_NORET; |
147 | 148 | ||
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index d71160de4d10..97f8bf6639e7 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h | |||
@@ -149,6 +149,9 @@ register struct thread_info *__current_thread_info __asm__("$28"); | |||
149 | #define _TIF_FPUBOUND (1<<TIF_FPUBOUND) | 149 | #define _TIF_FPUBOUND (1<<TIF_FPUBOUND) |
150 | #define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) | 150 | #define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) |
151 | 151 | ||
152 | /* work to do in syscall_trace_leave() */ | ||
153 | #define _TIF_WORK_SYSCALL_EXIT (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT) | ||
154 | |||
152 | /* work to do on interrupt/exception return */ | 155 | /* work to do on interrupt/exception return */ |
153 | #define _TIF_WORK_MASK (0x0000ffef & \ | 156 | #define _TIF_WORK_MASK (0x0000ffef & \ |
154 | ~(_TIF_SECCOMP | _TIF_SYSCALL_AUDIT)) | 157 | ~(_TIF_SECCOMP | _TIF_SYSCALL_AUDIT)) |
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c index 6a9e14dab91e..d97cfbf882f5 100644 --- a/arch/mips/jz4740/setup.c +++ b/arch/mips/jz4740/setup.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> | 2 | * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> |
3 | * Copyright (C) 2011, Maarten ter Huurne <maarten@treewalker.org> | ||
3 | * JZ4740 setup code | 4 | * JZ4740 setup code |
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
@@ -14,13 +15,44 @@ | |||
14 | */ | 15 | */ |
15 | 16 | ||
16 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/io.h> | ||
17 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
18 | 20 | ||
21 | #include <asm/bootinfo.h> | ||
22 | |||
23 | #include <asm/mach-jz4740/base.h> | ||
24 | |||
19 | #include "reset.h" | 25 | #include "reset.h" |
20 | 26 | ||
27 | |||
28 | #define JZ4740_EMC_SDRAM_CTRL 0x80 | ||
29 | |||
30 | |||
31 | static void __init jz4740_detect_mem(void) | ||
32 | { | ||
33 | void __iomem *jz_emc_base; | ||
34 | u32 ctrl, bus, bank, rows, cols; | ||
35 | phys_t size; | ||
36 | |||
37 | jz_emc_base = ioremap(JZ4740_EMC_BASE_ADDR, 0x100); | ||
38 | ctrl = readl(jz_emc_base + JZ4740_EMC_SDRAM_CTRL); | ||
39 | bus = 2 - ((ctrl >> 31) & 1); | ||
40 | bank = 1 + ((ctrl >> 19) & 1); | ||
41 | cols = 8 + ((ctrl >> 26) & 7); | ||
42 | rows = 11 + ((ctrl >> 20) & 3); | ||
43 | printk(KERN_DEBUG | ||
44 | "SDRAM preconfigured: bus:%u bank:%u rows:%u cols:%u\n", | ||
45 | bus, bank, rows, cols); | ||
46 | iounmap(jz_emc_base); | ||
47 | |||
48 | size = 1 << (bus + bank + cols + rows); | ||
49 | add_memory_region(0, size, BOOT_MEM_RAM); | ||
50 | } | ||
51 | |||
21 | void __init plat_mem_setup(void) | 52 | void __init plat_mem_setup(void) |
22 | { | 53 | { |
23 | jz4740_reset_init(); | 54 | jz4740_reset_init(); |
55 | jz4740_detect_mem(); | ||
24 | } | 56 | } |
25 | 57 | ||
26 | const char *get_system_type(void) | 58 | const char *get_system_type(void) |
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index cedee2bcbd18..83bba332bbfc 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
@@ -52,6 +52,7 @@ obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o | |||
52 | obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o | 52 | obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o |
53 | obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o | 53 | obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o |
54 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += octeon_switch.o | 54 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += octeon_switch.o |
55 | obj-$(CONFIG_CPU_XLR) += r4k_fpu.o r4k_switch.o | ||
55 | 56 | ||
56 | obj-$(CONFIG_SMP) += smp.o | 57 | obj-$(CONFIG_SMP) += smp.o |
57 | obj-$(CONFIG_SMP_UP) += smp-up.o | 58 | obj-$(CONFIG_SMP_UP) += smp-up.o |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index f65d4c8c65a6..bb133d10b145 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -291,6 +291,12 @@ static inline int cpu_has_confreg(void) | |||
291 | #endif | 291 | #endif |
292 | } | 292 | } |
293 | 293 | ||
294 | static inline void set_elf_platform(int cpu, const char *plat) | ||
295 | { | ||
296 | if (cpu == 0) | ||
297 | __elf_platform = plat; | ||
298 | } | ||
299 | |||
294 | /* | 300 | /* |
295 | * Get the FPU Implementation/Revision. | 301 | * Get the FPU Implementation/Revision. |
296 | */ | 302 | */ |
@@ -614,6 +620,16 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
614 | case PRID_IMP_LOONGSON2: | 620 | case PRID_IMP_LOONGSON2: |
615 | c->cputype = CPU_LOONGSON2; | 621 | c->cputype = CPU_LOONGSON2; |
616 | __cpu_name[cpu] = "ICT Loongson-2"; | 622 | __cpu_name[cpu] = "ICT Loongson-2"; |
623 | |||
624 | switch (c->processor_id & PRID_REV_MASK) { | ||
625 | case PRID_REV_LOONGSON2E: | ||
626 | set_elf_platform(cpu, "loongson2e"); | ||
627 | break; | ||
628 | case PRID_REV_LOONGSON2F: | ||
629 | set_elf_platform(cpu, "loongson2f"); | ||
630 | break; | ||
631 | } | ||
632 | |||
617 | c->isa_level = MIPS_CPU_ISA_III; | 633 | c->isa_level = MIPS_CPU_ISA_III; |
618 | c->options = R4K_OPTS | | 634 | c->options = R4K_OPTS | |
619 | MIPS_CPU_FPU | MIPS_CPU_LLSC | | 635 | MIPS_CPU_FPU | MIPS_CPU_LLSC | |
@@ -911,12 +927,14 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) | |||
911 | case PRID_IMP_BMIPS32_REV8: | 927 | case PRID_IMP_BMIPS32_REV8: |
912 | c->cputype = CPU_BMIPS32; | 928 | c->cputype = CPU_BMIPS32; |
913 | __cpu_name[cpu] = "Broadcom BMIPS32"; | 929 | __cpu_name[cpu] = "Broadcom BMIPS32"; |
930 | set_elf_platform(cpu, "bmips32"); | ||
914 | break; | 931 | break; |
915 | case PRID_IMP_BMIPS3300: | 932 | case PRID_IMP_BMIPS3300: |
916 | case PRID_IMP_BMIPS3300_ALT: | 933 | case PRID_IMP_BMIPS3300_ALT: |
917 | case PRID_IMP_BMIPS3300_BUG: | 934 | case PRID_IMP_BMIPS3300_BUG: |
918 | c->cputype = CPU_BMIPS3300; | 935 | c->cputype = CPU_BMIPS3300; |
919 | __cpu_name[cpu] = "Broadcom BMIPS3300"; | 936 | __cpu_name[cpu] = "Broadcom BMIPS3300"; |
937 | set_elf_platform(cpu, "bmips3300"); | ||
920 | break; | 938 | break; |
921 | case PRID_IMP_BMIPS43XX: { | 939 | case PRID_IMP_BMIPS43XX: { |
922 | int rev = c->processor_id & 0xff; | 940 | int rev = c->processor_id & 0xff; |
@@ -925,15 +943,18 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) | |||
925 | rev <= PRID_REV_BMIPS4380_HI) { | 943 | rev <= PRID_REV_BMIPS4380_HI) { |
926 | c->cputype = CPU_BMIPS4380; | 944 | c->cputype = CPU_BMIPS4380; |
927 | __cpu_name[cpu] = "Broadcom BMIPS4380"; | 945 | __cpu_name[cpu] = "Broadcom BMIPS4380"; |
946 | set_elf_platform(cpu, "bmips4380"); | ||
928 | } else { | 947 | } else { |
929 | c->cputype = CPU_BMIPS4350; | 948 | c->cputype = CPU_BMIPS4350; |
930 | __cpu_name[cpu] = "Broadcom BMIPS4350"; | 949 | __cpu_name[cpu] = "Broadcom BMIPS4350"; |
950 | set_elf_platform(cpu, "bmips4350"); | ||
931 | } | 951 | } |
932 | break; | 952 | break; |
933 | } | 953 | } |
934 | case PRID_IMP_BMIPS5000: | 954 | case PRID_IMP_BMIPS5000: |
935 | c->cputype = CPU_BMIPS5000; | 955 | c->cputype = CPU_BMIPS5000; |
936 | __cpu_name[cpu] = "Broadcom BMIPS5000"; | 956 | __cpu_name[cpu] = "Broadcom BMIPS5000"; |
957 | set_elf_platform(cpu, "bmips5000"); | ||
937 | c->options |= MIPS_CPU_ULRI; | 958 | c->options |= MIPS_CPU_ULRI; |
938 | break; | 959 | break; |
939 | } | 960 | } |
@@ -956,14 +977,12 @@ static inline void cpu_probe_cavium(struct cpuinfo_mips *c, unsigned int cpu) | |||
956 | c->cputype = CPU_CAVIUM_OCTEON_PLUS; | 977 | c->cputype = CPU_CAVIUM_OCTEON_PLUS; |
957 | __cpu_name[cpu] = "Cavium Octeon+"; | 978 | __cpu_name[cpu] = "Cavium Octeon+"; |
958 | platform: | 979 | platform: |
959 | if (cpu == 0) | 980 | set_elf_platform(cpu, "octeon"); |
960 | __elf_platform = "octeon"; | ||
961 | break; | 981 | break; |
962 | case PRID_IMP_CAVIUM_CN63XX: | 982 | case PRID_IMP_CAVIUM_CN63XX: |
963 | c->cputype = CPU_CAVIUM_OCTEON2; | 983 | c->cputype = CPU_CAVIUM_OCTEON2; |
964 | __cpu_name[cpu] = "Cavium Octeon II"; | 984 | __cpu_name[cpu] = "Cavium Octeon II"; |
965 | if (cpu == 0) | 985 | set_elf_platform(cpu, "octeon2"); |
966 | __elf_platform = "octeon2"; | ||
967 | break; | 986 | break; |
968 | default: | 987 | default: |
969 | printk(KERN_INFO "Unknown Octeon chip!\n"); | 988 | printk(KERN_INFO "Unknown Octeon chip!\n"); |
@@ -988,6 +1007,59 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu) | |||
988 | } | 1007 | } |
989 | } | 1008 | } |
990 | 1009 | ||
1010 | static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu) | ||
1011 | { | ||
1012 | decode_configs(c); | ||
1013 | |||
1014 | c->options = (MIPS_CPU_TLB | | ||
1015 | MIPS_CPU_4KEX | | ||
1016 | MIPS_CPU_COUNTER | | ||
1017 | MIPS_CPU_DIVEC | | ||
1018 | MIPS_CPU_WATCH | | ||
1019 | MIPS_CPU_EJTAG | | ||
1020 | MIPS_CPU_LLSC); | ||
1021 | |||
1022 | switch (c->processor_id & 0xff00) { | ||
1023 | case PRID_IMP_NETLOGIC_XLR732: | ||
1024 | case PRID_IMP_NETLOGIC_XLR716: | ||
1025 | case PRID_IMP_NETLOGIC_XLR532: | ||
1026 | case PRID_IMP_NETLOGIC_XLR308: | ||
1027 | case PRID_IMP_NETLOGIC_XLR532C: | ||
1028 | case PRID_IMP_NETLOGIC_XLR516C: | ||
1029 | case PRID_IMP_NETLOGIC_XLR508C: | ||
1030 | case PRID_IMP_NETLOGIC_XLR308C: | ||
1031 | c->cputype = CPU_XLR; | ||
1032 | __cpu_name[cpu] = "Netlogic XLR"; | ||
1033 | break; | ||
1034 | |||
1035 | case PRID_IMP_NETLOGIC_XLS608: | ||
1036 | case PRID_IMP_NETLOGIC_XLS408: | ||
1037 | case PRID_IMP_NETLOGIC_XLS404: | ||
1038 | case PRID_IMP_NETLOGIC_XLS208: | ||
1039 | case PRID_IMP_NETLOGIC_XLS204: | ||
1040 | case PRID_IMP_NETLOGIC_XLS108: | ||
1041 | case PRID_IMP_NETLOGIC_XLS104: | ||
1042 | case PRID_IMP_NETLOGIC_XLS616B: | ||
1043 | case PRID_IMP_NETLOGIC_XLS608B: | ||
1044 | case PRID_IMP_NETLOGIC_XLS416B: | ||
1045 | case PRID_IMP_NETLOGIC_XLS412B: | ||
1046 | case PRID_IMP_NETLOGIC_XLS408B: | ||
1047 | case PRID_IMP_NETLOGIC_XLS404B: | ||
1048 | c->cputype = CPU_XLR; | ||
1049 | __cpu_name[cpu] = "Netlogic XLS"; | ||
1050 | break; | ||
1051 | |||
1052 | default: | ||
1053 | printk(KERN_INFO "Unknown Netlogic chip id [%02x]!\n", | ||
1054 | c->processor_id); | ||
1055 | c->cputype = CPU_XLR; | ||
1056 | break; | ||
1057 | } | ||
1058 | |||
1059 | c->isa_level = MIPS_CPU_ISA_M64R1; | ||
1060 | c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1; | ||
1061 | } | ||
1062 | |||
991 | #ifdef CONFIG_64BIT | 1063 | #ifdef CONFIG_64BIT |
992 | /* For use by uaccess.h */ | 1064 | /* For use by uaccess.h */ |
993 | u64 __ua_limit; | 1065 | u64 __ua_limit; |
@@ -1035,6 +1107,9 @@ __cpuinit void cpu_probe(void) | |||
1035 | case PRID_COMP_INGENIC: | 1107 | case PRID_COMP_INGENIC: |
1036 | cpu_probe_ingenic(c, cpu); | 1108 | cpu_probe_ingenic(c, cpu); |
1037 | break; | 1109 | break; |
1110 | case PRID_COMP_NETLOGIC: | ||
1111 | cpu_probe_netlogic(c, cpu); | ||
1112 | break; | ||
1038 | } | 1113 | } |
1039 | 1114 | ||
1040 | BUG_ON(!__cpu_name[cpu]); | 1115 | BUG_ON(!__cpu_name[cpu]); |
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index ffa331029e08..37acfa036d44 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S | |||
@@ -167,14 +167,13 @@ work_notifysig: # deal with pending signals and | |||
167 | FEXPORT(syscall_exit_work_partial) | 167 | FEXPORT(syscall_exit_work_partial) |
168 | SAVE_STATIC | 168 | SAVE_STATIC |
169 | syscall_exit_work: | 169 | syscall_exit_work: |
170 | li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | 170 | li t0, _TIF_WORK_SYSCALL_EXIT |
171 | and t0, a2 # a2 is preloaded with TI_FLAGS | 171 | and t0, a2 # a2 is preloaded with TI_FLAGS |
172 | beqz t0, work_pending # trace bit set? | 172 | beqz t0, work_pending # trace bit set? |
173 | local_irq_enable # could let do_syscall_trace() | 173 | local_irq_enable # could let syscall_trace_leave() |
174 | # call schedule() instead | 174 | # call schedule() instead |
175 | move a0, sp | 175 | move a0, sp |
176 | li a1, 1 | 176 | jal syscall_trace_leave |
177 | jal do_syscall_trace | ||
178 | b resume_userspace | 177 | b resume_userspace |
179 | 178 | ||
180 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT) | 179 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT) |
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 584e6b55c865..4e6ea1ffad46 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
@@ -533,15 +533,10 @@ static inline int audit_arch(void) | |||
533 | * Notification of system call entry/exit | 533 | * Notification of system call entry/exit |
534 | * - triggered by current->work.syscall_trace | 534 | * - triggered by current->work.syscall_trace |
535 | */ | 535 | */ |
536 | asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) | 536 | asmlinkage void syscall_trace_enter(struct pt_regs *regs) |
537 | { | 537 | { |
538 | /* do the secure computing check first */ | 538 | /* do the secure computing check first */ |
539 | if (!entryexit) | 539 | secure_computing(regs->regs[2]); |
540 | secure_computing(regs->regs[2]); | ||
541 | |||
542 | if (unlikely(current->audit_context) && entryexit) | ||
543 | audit_syscall_exit(AUDITSC_RESULT(regs->regs[7]), | ||
544 | -regs->regs[2]); | ||
545 | 540 | ||
546 | if (!(current->ptrace & PT_PTRACED)) | 541 | if (!(current->ptrace & PT_PTRACED)) |
547 | goto out; | 542 | goto out; |
@@ -565,8 +560,40 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) | |||
565 | } | 560 | } |
566 | 561 | ||
567 | out: | 562 | out: |
568 | if (unlikely(current->audit_context) && !entryexit) | 563 | if (unlikely(current->audit_context)) |
569 | audit_syscall_entry(audit_arch(), regs->regs[2], | 564 | audit_syscall_entry(audit_arch(), regs->regs[2], |
570 | regs->regs[4], regs->regs[5], | 565 | regs->regs[4], regs->regs[5], |
571 | regs->regs[6], regs->regs[7]); | 566 | regs->regs[6], regs->regs[7]); |
572 | } | 567 | } |
568 | |||
569 | /* | ||
570 | * Notification of system call entry/exit | ||
571 | * - triggered by current->work.syscall_trace | ||
572 | */ | ||
573 | asmlinkage void syscall_trace_leave(struct pt_regs *regs) | ||
574 | { | ||
575 | if (unlikely(current->audit_context)) | ||
576 | audit_syscall_exit(AUDITSC_RESULT(regs->regs[7]), | ||
577 | -regs->regs[2]); | ||
578 | |||
579 | if (!(current->ptrace & PT_PTRACED)) | ||
580 | return; | ||
581 | |||
582 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | ||
583 | return; | ||
584 | |||
585 | /* The 0x80 provides a way for the tracing parent to distinguish | ||
586 | between a syscall stop and SIGTRAP delivery */ | ||
587 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? | ||
588 | 0x80 : 0)); | ||
589 | |||
590 | /* | ||
591 | * this isn't the same as continuing with a signal, but it will do | ||
592 | * for normal use. strace only continues with a signal if the | ||
593 | * stopping signal is not SIGTRAP. -brl | ||
594 | */ | ||
595 | if (current->exit_code) { | ||
596 | send_sig(current->exit_code, current, 1); | ||
597 | current->exit_code = 0; | ||
598 | } | ||
599 | } | ||
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 7f1377eb22d3..7a8e1dd7f6f2 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -88,8 +88,7 @@ syscall_trace_entry: | |||
88 | SAVE_STATIC | 88 | SAVE_STATIC |
89 | move s0, t2 | 89 | move s0, t2 |
90 | move a0, sp | 90 | move a0, sp |
91 | li a1, 0 | 91 | jal syscall_trace_enter |
92 | jal do_syscall_trace | ||
93 | 92 | ||
94 | move t0, s0 | 93 | move t0, s0 |
95 | RESTORE_STATIC | 94 | RESTORE_STATIC |
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 7c0ef7f128bf..2d31c83224f9 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
@@ -91,8 +91,7 @@ syscall_trace_entry: | |||
91 | SAVE_STATIC | 91 | SAVE_STATIC |
92 | move s0, t2 | 92 | move s0, t2 |
93 | move a0, sp | 93 | move a0, sp |
94 | li a1, 0 | 94 | jal syscall_trace_enter |
95 | jal do_syscall_trace | ||
96 | 95 | ||
97 | move t0, s0 | 96 | move t0, s0 |
98 | RESTORE_STATIC | 97 | RESTORE_STATIC |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index de6c5563beab..38a0503b9a4a 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -89,8 +89,7 @@ n32_syscall_trace_entry: | |||
89 | SAVE_STATIC | 89 | SAVE_STATIC |
90 | move s0, t2 | 90 | move s0, t2 |
91 | move a0, sp | 91 | move a0, sp |
92 | li a1, 0 | 92 | jal syscall_trace_enter |
93 | jal do_syscall_trace | ||
94 | 93 | ||
95 | move t0, s0 | 94 | move t0, s0 |
96 | RESTORE_STATIC | 95 | RESTORE_STATIC |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index b0541dda8830..91ea5e4041dd 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -123,8 +123,7 @@ trace_a_syscall: | |||
123 | 123 | ||
124 | move s0, t2 # Save syscall pointer | 124 | move s0, t2 # Save syscall pointer |
125 | move a0, sp | 125 | move a0, sp |
126 | li a1, 0 | 126 | jal syscall_trace_enter |
127 | jal do_syscall_trace | ||
128 | 127 | ||
129 | move t0, s0 | 128 | move t0, s0 |
130 | RESTORE_STATIC | 129 | RESTORE_STATIC |
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 58beabf50b3c..d02765708ddb 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c | |||
@@ -10,12 +10,9 @@ | |||
10 | #include <linux/capability.h> | 10 | #include <linux/capability.h> |
11 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
12 | #include <linux/linkage.h> | 12 | #include <linux/linkage.h> |
13 | #include <linux/mm.h> | ||
14 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
15 | #include <linux/smp.h> | 14 | #include <linux/smp.h> |
16 | #include <linux/mman.h> | ||
17 | #include <linux/ptrace.h> | 15 | #include <linux/ptrace.h> |
18 | #include <linux/sched.h> | ||
19 | #include <linux/string.h> | 16 | #include <linux/string.h> |
20 | #include <linux/syscalls.h> | 17 | #include <linux/syscalls.h> |
21 | #include <linux/file.h> | 18 | #include <linux/file.h> |
@@ -25,11 +22,9 @@ | |||
25 | #include <linux/msg.h> | 22 | #include <linux/msg.h> |
26 | #include <linux/shm.h> | 23 | #include <linux/shm.h> |
27 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
28 | #include <linux/module.h> | ||
29 | #include <linux/ipc.h> | 25 | #include <linux/ipc.h> |
30 | #include <linux/uaccess.h> | 26 | #include <linux/uaccess.h> |
31 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
32 | #include <linux/random.h> | ||
33 | #include <linux/elf.h> | 28 | #include <linux/elf.h> |
34 | 29 | ||
35 | #include <asm/asm.h> | 30 | #include <asm/asm.h> |
@@ -66,121 +61,6 @@ out: | |||
66 | return res; | 61 | return res; |
67 | } | 62 | } |
68 | 63 | ||
69 | unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ | ||
70 | |||
71 | EXPORT_SYMBOL(shm_align_mask); | ||
72 | |||
73 | #define COLOUR_ALIGN(addr,pgoff) \ | ||
74 | ((((addr) + shm_align_mask) & ~shm_align_mask) + \ | ||
75 | (((pgoff) << PAGE_SHIFT) & shm_align_mask)) | ||
76 | |||
77 | unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | ||
78 | unsigned long len, unsigned long pgoff, unsigned long flags) | ||
79 | { | ||
80 | struct vm_area_struct * vmm; | ||
81 | int do_color_align; | ||
82 | unsigned long task_size; | ||
83 | |||
84 | #ifdef CONFIG_32BIT | ||
85 | task_size = TASK_SIZE; | ||
86 | #else /* Must be CONFIG_64BIT*/ | ||
87 | task_size = test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE; | ||
88 | #endif | ||
89 | |||
90 | if (len > task_size) | ||
91 | return -ENOMEM; | ||
92 | |||
93 | if (flags & MAP_FIXED) { | ||
94 | /* Even MAP_FIXED mappings must reside within task_size. */ | ||
95 | if (task_size - len < addr) | ||
96 | return -EINVAL; | ||
97 | |||
98 | /* | ||
99 | * We do not accept a shared mapping if it would violate | ||
100 | * cache aliasing constraints. | ||
101 | */ | ||
102 | if ((flags & MAP_SHARED) && | ||
103 | ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask)) | ||
104 | return -EINVAL; | ||
105 | return addr; | ||
106 | } | ||
107 | |||
108 | do_color_align = 0; | ||
109 | if (filp || (flags & MAP_SHARED)) | ||
110 | do_color_align = 1; | ||
111 | if (addr) { | ||
112 | if (do_color_align) | ||
113 | addr = COLOUR_ALIGN(addr, pgoff); | ||
114 | else | ||
115 | addr = PAGE_ALIGN(addr); | ||
116 | vmm = find_vma(current->mm, addr); | ||
117 | if (task_size - len >= addr && | ||
118 | (!vmm || addr + len <= vmm->vm_start)) | ||
119 | return addr; | ||
120 | } | ||
121 | addr = current->mm->mmap_base; | ||
122 | if (do_color_align) | ||
123 | addr = COLOUR_ALIGN(addr, pgoff); | ||
124 | else | ||
125 | addr = PAGE_ALIGN(addr); | ||
126 | |||
127 | for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { | ||
128 | /* At this point: (!vmm || addr < vmm->vm_end). */ | ||
129 | if (task_size - len < addr) | ||
130 | return -ENOMEM; | ||
131 | if (!vmm || addr + len <= vmm->vm_start) | ||
132 | return addr; | ||
133 | addr = vmm->vm_end; | ||
134 | if (do_color_align) | ||
135 | addr = COLOUR_ALIGN(addr, pgoff); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | void arch_pick_mmap_layout(struct mm_struct *mm) | ||
140 | { | ||
141 | unsigned long random_factor = 0UL; | ||
142 | |||
143 | if (current->flags & PF_RANDOMIZE) { | ||
144 | random_factor = get_random_int(); | ||
145 | random_factor = random_factor << PAGE_SHIFT; | ||
146 | if (TASK_IS_32BIT_ADDR) | ||
147 | random_factor &= 0xfffffful; | ||
148 | else | ||
149 | random_factor &= 0xffffffful; | ||
150 | } | ||
151 | |||
152 | mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; | ||
153 | mm->get_unmapped_area = arch_get_unmapped_area; | ||
154 | mm->unmap_area = arch_unmap_area; | ||
155 | } | ||
156 | |||
157 | static inline unsigned long brk_rnd(void) | ||
158 | { | ||
159 | unsigned long rnd = get_random_int(); | ||
160 | |||
161 | rnd = rnd << PAGE_SHIFT; | ||
162 | /* 8MB for 32bit, 256MB for 64bit */ | ||
163 | if (TASK_IS_32BIT_ADDR) | ||
164 | rnd = rnd & 0x7ffffful; | ||
165 | else | ||
166 | rnd = rnd & 0xffffffful; | ||
167 | |||
168 | return rnd; | ||
169 | } | ||
170 | |||
171 | unsigned long arch_randomize_brk(struct mm_struct *mm) | ||
172 | { | ||
173 | unsigned long base = mm->brk; | ||
174 | unsigned long ret; | ||
175 | |||
176 | ret = PAGE_ALIGN(base + brk_rnd()); | ||
177 | |||
178 | if (ret < mm->brk) | ||
179 | return mm->brk; | ||
180 | |||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len, | 64 | SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len, |
185 | unsigned long, prot, unsigned long, flags, unsigned long, | 65 | unsigned long, prot, unsigned long, flags, unsigned long, |
186 | fd, off_t, offset) | 66 | fd, off_t, offset) |
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index e4b0b0bec039..cd2ca544454b 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S | |||
@@ -68,6 +68,7 @@ SECTIONS | |||
68 | RODATA | 68 | RODATA |
69 | 69 | ||
70 | /* writeable */ | 70 | /* writeable */ |
71 | _sdata = .; /* Start of data section */ | ||
71 | .data : { /* Data */ | 72 | .data : { /* Data */ |
72 | . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ | 73 | . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ |
73 | 74 | ||
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig new file mode 100644 index 000000000000..3fccf2104513 --- /dev/null +++ b/arch/mips/lantiq/Kconfig | |||
@@ -0,0 +1,23 @@ | |||
1 | if LANTIQ | ||
2 | |||
3 | config SOC_TYPE_XWAY | ||
4 | bool | ||
5 | default n | ||
6 | |||
7 | choice | ||
8 | prompt "SoC Type" | ||
9 | default SOC_XWAY | ||
10 | |||
11 | config SOC_AMAZON_SE | ||
12 | bool "Amazon SE" | ||
13 | select SOC_TYPE_XWAY | ||
14 | |||
15 | config SOC_XWAY | ||
16 | bool "XWAY" | ||
17 | select SOC_TYPE_XWAY | ||
18 | select HW_HAS_PCI | ||
19 | endchoice | ||
20 | |||
21 | source "arch/mips/lantiq/xway/Kconfig" | ||
22 | |||
23 | endif | ||
diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile new file mode 100644 index 000000000000..e5dae0e24b00 --- /dev/null +++ b/arch/mips/lantiq/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | # Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
2 | # | ||
3 | # This program is free software; you can redistribute it and/or modify it | ||
4 | # under the terms of the GNU General Public License version 2 as published | ||
5 | # by the Free Software Foundation. | ||
6 | |||
7 | obj-y := irq.o setup.o clk.o prom.o devices.o | ||
8 | |||
9 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | ||
10 | |||
11 | obj-$(CONFIG_SOC_TYPE_XWAY) += xway/ | ||
diff --git a/arch/mips/lantiq/Platform b/arch/mips/lantiq/Platform new file mode 100644 index 000000000000..f3dff05722de --- /dev/null +++ b/arch/mips/lantiq/Platform | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Lantiq | ||
3 | # | ||
4 | |||
5 | platform-$(CONFIG_LANTIQ) += lantiq/ | ||
6 | cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq | ||
7 | load-$(CONFIG_LANTIQ) = 0xffffffff80002000 | ||
8 | cflags-$(CONFIG_SOC_TYPE_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway | ||
diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c new file mode 100644 index 000000000000..94560899d13e --- /dev/null +++ b/arch/mips/lantiq/clk.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com> | ||
7 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
8 | */ | ||
9 | #include <linux/io.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/clk.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/list.h> | ||
17 | |||
18 | #include <asm/time.h> | ||
19 | #include <asm/irq.h> | ||
20 | #include <asm/div64.h> | ||
21 | |||
22 | #include <lantiq_soc.h> | ||
23 | |||
24 | #include "clk.h" | ||
25 | |||
26 | struct clk { | ||
27 | const char *name; | ||
28 | unsigned long rate; | ||
29 | unsigned long (*get_rate) (void); | ||
30 | }; | ||
31 | |||
32 | static struct clk *cpu_clk; | ||
33 | static int cpu_clk_cnt; | ||
34 | |||
35 | /* lantiq socs have 3 static clocks */ | ||
36 | static struct clk cpu_clk_generic[] = { | ||
37 | { | ||
38 | .name = "cpu", | ||
39 | .get_rate = ltq_get_cpu_hz, | ||
40 | }, { | ||
41 | .name = "fpi", | ||
42 | .get_rate = ltq_get_fpi_hz, | ||
43 | }, { | ||
44 | .name = "io", | ||
45 | .get_rate = ltq_get_io_region_clock, | ||
46 | }, | ||
47 | }; | ||
48 | |||
49 | static struct resource ltq_cgu_resource = { | ||
50 | .name = "cgu", | ||
51 | .start = LTQ_CGU_BASE_ADDR, | ||
52 | .end = LTQ_CGU_BASE_ADDR + LTQ_CGU_SIZE - 1, | ||
53 | .flags = IORESOURCE_MEM, | ||
54 | }; | ||
55 | |||
56 | /* remapped clock register range */ | ||
57 | void __iomem *ltq_cgu_membase; | ||
58 | |||
59 | void clk_init(void) | ||
60 | { | ||
61 | cpu_clk = cpu_clk_generic; | ||
62 | cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic); | ||
63 | } | ||
64 | |||
65 | static inline int clk_good(struct clk *clk) | ||
66 | { | ||
67 | return clk && !IS_ERR(clk); | ||
68 | } | ||
69 | |||
70 | unsigned long clk_get_rate(struct clk *clk) | ||
71 | { | ||
72 | if (unlikely(!clk_good(clk))) | ||
73 | return 0; | ||
74 | |||
75 | if (clk->rate != 0) | ||
76 | return clk->rate; | ||
77 | |||
78 | if (clk->get_rate != NULL) | ||
79 | return clk->get_rate(); | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | EXPORT_SYMBOL(clk_get_rate); | ||
84 | |||
85 | struct clk *clk_get(struct device *dev, const char *id) | ||
86 | { | ||
87 | int i; | ||
88 | |||
89 | for (i = 0; i < cpu_clk_cnt; i++) | ||
90 | if (!strcmp(id, cpu_clk[i].name)) | ||
91 | return &cpu_clk[i]; | ||
92 | BUG(); | ||
93 | return ERR_PTR(-ENOENT); | ||
94 | } | ||
95 | EXPORT_SYMBOL(clk_get); | ||
96 | |||
97 | void clk_put(struct clk *clk) | ||
98 | { | ||
99 | /* not used */ | ||
100 | } | ||
101 | EXPORT_SYMBOL(clk_put); | ||
102 | |||
103 | static inline u32 ltq_get_counter_resolution(void) | ||
104 | { | ||
105 | u32 res; | ||
106 | |||
107 | __asm__ __volatile__( | ||
108 | ".set push\n" | ||
109 | ".set mips32r2\n" | ||
110 | "rdhwr %0, $3\n" | ||
111 | ".set pop\n" | ||
112 | : "=&r" (res) | ||
113 | : /* no input */ | ||
114 | : "memory"); | ||
115 | |||
116 | return res; | ||
117 | } | ||
118 | |||
119 | void __init plat_time_init(void) | ||
120 | { | ||
121 | struct clk *clk; | ||
122 | |||
123 | if (insert_resource(&iomem_resource, <q_cgu_resource) < 0) | ||
124 | panic("Failed to insert cgu memory\n"); | ||
125 | |||
126 | if (request_mem_region(ltq_cgu_resource.start, | ||
127 | resource_size(<q_cgu_resource), "cgu") < 0) | ||
128 | panic("Failed to request cgu memory\n"); | ||
129 | |||
130 | ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start, | ||
131 | resource_size(<q_cgu_resource)); | ||
132 | if (!ltq_cgu_membase) { | ||
133 | pr_err("Failed to remap cgu memory\n"); | ||
134 | unreachable(); | ||
135 | } | ||
136 | clk = clk_get(0, "cpu"); | ||
137 | mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution(); | ||
138 | write_c0_compare(read_c0_count()); | ||
139 | clk_put(clk); | ||
140 | } | ||
diff --git a/arch/mips/lantiq/clk.h b/arch/mips/lantiq/clk.h new file mode 100644 index 000000000000..3328925f2c3f --- /dev/null +++ b/arch/mips/lantiq/clk.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LTQ_CLK_H__ | ||
10 | #define _LTQ_CLK_H__ | ||
11 | |||
12 | extern void clk_init(void); | ||
13 | |||
14 | extern unsigned long ltq_get_cpu_hz(void); | ||
15 | extern unsigned long ltq_get_fpi_hz(void); | ||
16 | extern unsigned long ltq_get_io_region_clock(void); | ||
17 | |||
18 | #endif | ||
diff --git a/arch/mips/lantiq/devices.c b/arch/mips/lantiq/devices.c new file mode 100644 index 000000000000..7b82c34cb169 --- /dev/null +++ b/arch/mips/lantiq/devices.c | |||
@@ -0,0 +1,122 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/reboot.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/leds.h> | ||
17 | #include <linux/etherdevice.h> | ||
18 | #include <linux/reboot.h> | ||
19 | #include <linux/time.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/gpio.h> | ||
22 | #include <linux/leds.h> | ||
23 | |||
24 | #include <asm/bootinfo.h> | ||
25 | #include <asm/irq.h> | ||
26 | |||
27 | #include <lantiq_soc.h> | ||
28 | |||
29 | #include "devices.h" | ||
30 | |||
31 | /* nor flash */ | ||
32 | static struct resource ltq_nor_resource = { | ||
33 | .name = "nor", | ||
34 | .start = LTQ_FLASH_START, | ||
35 | .end = LTQ_FLASH_START + LTQ_FLASH_MAX - 1, | ||
36 | .flags = IORESOURCE_MEM, | ||
37 | }; | ||
38 | |||
39 | static struct platform_device ltq_nor = { | ||
40 | .name = "ltq_nor", | ||
41 | .resource = <q_nor_resource, | ||
42 | .num_resources = 1, | ||
43 | }; | ||
44 | |||
45 | void __init ltq_register_nor(struct physmap_flash_data *data) | ||
46 | { | ||
47 | ltq_nor.dev.platform_data = data; | ||
48 | platform_device_register(<q_nor); | ||
49 | } | ||
50 | |||
51 | /* watchdog */ | ||
52 | static struct resource ltq_wdt_resource = { | ||
53 | .name = "watchdog", | ||
54 | .start = LTQ_WDT_BASE_ADDR, | ||
55 | .end = LTQ_WDT_BASE_ADDR + LTQ_WDT_SIZE - 1, | ||
56 | .flags = IORESOURCE_MEM, | ||
57 | }; | ||
58 | |||
59 | void __init ltq_register_wdt(void) | ||
60 | { | ||
61 | platform_device_register_simple("ltq_wdt", 0, <q_wdt_resource, 1); | ||
62 | } | ||
63 | |||
64 | /* asc ports */ | ||
65 | static struct resource ltq_asc0_resources[] = { | ||
66 | { | ||
67 | .name = "asc0", | ||
68 | .start = LTQ_ASC0_BASE_ADDR, | ||
69 | .end = LTQ_ASC0_BASE_ADDR + LTQ_ASC_SIZE - 1, | ||
70 | .flags = IORESOURCE_MEM, | ||
71 | }, | ||
72 | IRQ_RES(tx, LTQ_ASC_TIR(0)), | ||
73 | IRQ_RES(rx, LTQ_ASC_RIR(0)), | ||
74 | IRQ_RES(err, LTQ_ASC_EIR(0)), | ||
75 | }; | ||
76 | |||
77 | static struct resource ltq_asc1_resources[] = { | ||
78 | { | ||
79 | .name = "asc1", | ||
80 | .start = LTQ_ASC1_BASE_ADDR, | ||
81 | .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1, | ||
82 | .flags = IORESOURCE_MEM, | ||
83 | }, | ||
84 | IRQ_RES(tx, LTQ_ASC_TIR(1)), | ||
85 | IRQ_RES(rx, LTQ_ASC_RIR(1)), | ||
86 | IRQ_RES(err, LTQ_ASC_EIR(1)), | ||
87 | }; | ||
88 | |||
89 | void __init ltq_register_asc(int port) | ||
90 | { | ||
91 | switch (port) { | ||
92 | case 0: | ||
93 | platform_device_register_simple("ltq_asc", 0, | ||
94 | ltq_asc0_resources, ARRAY_SIZE(ltq_asc0_resources)); | ||
95 | break; | ||
96 | case 1: | ||
97 | platform_device_register_simple("ltq_asc", 1, | ||
98 | ltq_asc1_resources, ARRAY_SIZE(ltq_asc1_resources)); | ||
99 | break; | ||
100 | default: | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | #ifdef CONFIG_PCI | ||
106 | /* pci */ | ||
107 | static struct platform_device ltq_pci = { | ||
108 | .name = "ltq_pci", | ||
109 | .num_resources = 0, | ||
110 | }; | ||
111 | |||
112 | void __init ltq_register_pci(struct ltq_pci_data *data) | ||
113 | { | ||
114 | ltq_pci.dev.platform_data = data; | ||
115 | platform_device_register(<q_pci); | ||
116 | } | ||
117 | #else | ||
118 | void __init ltq_register_pci(struct ltq_pci_data *data) | ||
119 | { | ||
120 | pr_err("kernel is compiled without PCI support\n"); | ||
121 | } | ||
122 | #endif | ||
diff --git a/arch/mips/lantiq/devices.h b/arch/mips/lantiq/devices.h new file mode 100644 index 000000000000..2947bb19a528 --- /dev/null +++ b/arch/mips/lantiq/devices.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LTQ_DEVICES_H__ | ||
10 | #define _LTQ_DEVICES_H__ | ||
11 | |||
12 | #include <lantiq_platform.h> | ||
13 | #include <linux/mtd/physmap.h> | ||
14 | |||
15 | #define IRQ_RES(resname, irq) \ | ||
16 | {.name = #resname, .start = (irq), .flags = IORESOURCE_IRQ} | ||
17 | |||
18 | extern void ltq_register_nor(struct physmap_flash_data *data); | ||
19 | extern void ltq_register_wdt(void); | ||
20 | extern void ltq_register_asc(int port); | ||
21 | extern void ltq_register_pci(struct ltq_pci_data *data); | ||
22 | |||
23 | #endif | ||
diff --git a/arch/mips/lantiq/early_printk.c b/arch/mips/lantiq/early_printk.c new file mode 100644 index 000000000000..972e05f87631 --- /dev/null +++ b/arch/mips/lantiq/early_printk.c | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/cpu.h> | ||
11 | |||
12 | #include <lantiq.h> | ||
13 | #include <lantiq_soc.h> | ||
14 | |||
15 | /* no ioremap possible at this early stage, lets use KSEG1 instead */ | ||
16 | #define LTQ_ASC_BASE KSEG1ADDR(LTQ_ASC1_BASE_ADDR) | ||
17 | #define ASC_BUF 1024 | ||
18 | #define LTQ_ASC_FSTAT ((u32 *)(LTQ_ASC_BASE + 0x0048)) | ||
19 | #define LTQ_ASC_TBUF ((u32 *)(LTQ_ASC_BASE + 0x0020)) | ||
20 | #define TXMASK 0x3F00 | ||
21 | #define TXOFFSET 8 | ||
22 | |||
23 | void prom_putchar(char c) | ||
24 | { | ||
25 | unsigned long flags; | ||
26 | |||
27 | local_irq_save(flags); | ||
28 | do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET); | ||
29 | if (c == '\n') | ||
30 | ltq_w32('\r', LTQ_ASC_TBUF); | ||
31 | ltq_w32(c, LTQ_ASC_TBUF); | ||
32 | local_irq_restore(flags); | ||
33 | } | ||
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c new file mode 100644 index 000000000000..fc89795cafdb --- /dev/null +++ b/arch/mips/lantiq/irq.c | |||
@@ -0,0 +1,326 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com> | ||
8 | */ | ||
9 | |||
10 | #include <linux/interrupt.h> | ||
11 | #include <linux/ioport.h> | ||
12 | |||
13 | #include <asm/bootinfo.h> | ||
14 | #include <asm/irq_cpu.h> | ||
15 | |||
16 | #include <lantiq_soc.h> | ||
17 | #include <irq.h> | ||
18 | |||
19 | /* register definitions */ | ||
20 | #define LTQ_ICU_IM0_ISR 0x0000 | ||
21 | #define LTQ_ICU_IM0_IER 0x0008 | ||
22 | #define LTQ_ICU_IM0_IOSR 0x0010 | ||
23 | #define LTQ_ICU_IM0_IRSR 0x0018 | ||
24 | #define LTQ_ICU_IM0_IMR 0x0020 | ||
25 | #define LTQ_ICU_IM1_ISR 0x0028 | ||
26 | #define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR) | ||
27 | |||
28 | #define LTQ_EIU_EXIN_C 0x0000 | ||
29 | #define LTQ_EIU_EXIN_INIC 0x0004 | ||
30 | #define LTQ_EIU_EXIN_INEN 0x000C | ||
31 | |||
32 | /* irq numbers used by the external interrupt unit (EIU) */ | ||
33 | #define LTQ_EIU_IR0 (INT_NUM_IM4_IRL0 + 30) | ||
34 | #define LTQ_EIU_IR1 (INT_NUM_IM3_IRL0 + 31) | ||
35 | #define LTQ_EIU_IR2 (INT_NUM_IM1_IRL0 + 26) | ||
36 | #define LTQ_EIU_IR3 INT_NUM_IM1_IRL0 | ||
37 | #define LTQ_EIU_IR4 (INT_NUM_IM1_IRL0 + 1) | ||
38 | #define LTQ_EIU_IR5 (INT_NUM_IM1_IRL0 + 2) | ||
39 | #define LTQ_EIU_IR6 (INT_NUM_IM2_IRL0 + 30) | ||
40 | |||
41 | #define MAX_EIU 6 | ||
42 | |||
43 | /* irqs generated by device attached to the EBU need to be acked in | ||
44 | * a special manner | ||
45 | */ | ||
46 | #define LTQ_ICU_EBU_IRQ 22 | ||
47 | |||
48 | #define ltq_icu_w32(x, y) ltq_w32((x), ltq_icu_membase + (y)) | ||
49 | #define ltq_icu_r32(x) ltq_r32(ltq_icu_membase + (x)) | ||
50 | |||
51 | #define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y)) | ||
52 | #define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x)) | ||
53 | |||
54 | static unsigned short ltq_eiu_irq[MAX_EIU] = { | ||
55 | LTQ_EIU_IR0, | ||
56 | LTQ_EIU_IR1, | ||
57 | LTQ_EIU_IR2, | ||
58 | LTQ_EIU_IR3, | ||
59 | LTQ_EIU_IR4, | ||
60 | LTQ_EIU_IR5, | ||
61 | }; | ||
62 | |||
63 | static struct resource ltq_icu_resource = { | ||
64 | .name = "icu", | ||
65 | .start = LTQ_ICU_BASE_ADDR, | ||
66 | .end = LTQ_ICU_BASE_ADDR + LTQ_ICU_SIZE - 1, | ||
67 | .flags = IORESOURCE_MEM, | ||
68 | }; | ||
69 | |||
70 | static struct resource ltq_eiu_resource = { | ||
71 | .name = "eiu", | ||
72 | .start = LTQ_EIU_BASE_ADDR, | ||
73 | .end = LTQ_EIU_BASE_ADDR + LTQ_ICU_SIZE - 1, | ||
74 | .flags = IORESOURCE_MEM, | ||
75 | }; | ||
76 | |||
77 | static void __iomem *ltq_icu_membase; | ||
78 | static void __iomem *ltq_eiu_membase; | ||
79 | |||
80 | void ltq_disable_irq(struct irq_data *d) | ||
81 | { | ||
82 | u32 ier = LTQ_ICU_IM0_IER; | ||
83 | int irq_nr = d->irq - INT_NUM_IRQ0; | ||
84 | |||
85 | ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); | ||
86 | irq_nr %= INT_NUM_IM_OFFSET; | ||
87 | ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier); | ||
88 | } | ||
89 | |||
90 | void ltq_mask_and_ack_irq(struct irq_data *d) | ||
91 | { | ||
92 | u32 ier = LTQ_ICU_IM0_IER; | ||
93 | u32 isr = LTQ_ICU_IM0_ISR; | ||
94 | int irq_nr = d->irq - INT_NUM_IRQ0; | ||
95 | |||
96 | ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); | ||
97 | isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); | ||
98 | irq_nr %= INT_NUM_IM_OFFSET; | ||
99 | ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier); | ||
100 | ltq_icu_w32((1 << irq_nr), isr); | ||
101 | } | ||
102 | |||
103 | static void ltq_ack_irq(struct irq_data *d) | ||
104 | { | ||
105 | u32 isr = LTQ_ICU_IM0_ISR; | ||
106 | int irq_nr = d->irq - INT_NUM_IRQ0; | ||
107 | |||
108 | isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); | ||
109 | irq_nr %= INT_NUM_IM_OFFSET; | ||
110 | ltq_icu_w32((1 << irq_nr), isr); | ||
111 | } | ||
112 | |||
113 | void ltq_enable_irq(struct irq_data *d) | ||
114 | { | ||
115 | u32 ier = LTQ_ICU_IM0_IER; | ||
116 | int irq_nr = d->irq - INT_NUM_IRQ0; | ||
117 | |||
118 | ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); | ||
119 | irq_nr %= INT_NUM_IM_OFFSET; | ||
120 | ltq_icu_w32(ltq_icu_r32(ier) | (1 << irq_nr), ier); | ||
121 | } | ||
122 | |||
123 | static unsigned int ltq_startup_eiu_irq(struct irq_data *d) | ||
124 | { | ||
125 | int i; | ||
126 | int irq_nr = d->irq - INT_NUM_IRQ0; | ||
127 | |||
128 | ltq_enable_irq(d); | ||
129 | for (i = 0; i < MAX_EIU; i++) { | ||
130 | if (irq_nr == ltq_eiu_irq[i]) { | ||
131 | /* low level - we should really handle set_type */ | ||
132 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) | | ||
133 | (0x6 << (i * 4)), LTQ_EIU_EXIN_C); | ||
134 | /* clear all pending */ | ||
135 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~(1 << i), | ||
136 | LTQ_EIU_EXIN_INIC); | ||
137 | /* enable */ | ||
138 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | (1 << i), | ||
139 | LTQ_EIU_EXIN_INEN); | ||
140 | break; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static void ltq_shutdown_eiu_irq(struct irq_data *d) | ||
148 | { | ||
149 | int i; | ||
150 | int irq_nr = d->irq - INT_NUM_IRQ0; | ||
151 | |||
152 | ltq_disable_irq(d); | ||
153 | for (i = 0; i < MAX_EIU; i++) { | ||
154 | if (irq_nr == ltq_eiu_irq[i]) { | ||
155 | /* disable */ | ||
156 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~(1 << i), | ||
157 | LTQ_EIU_EXIN_INEN); | ||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | |||
163 | static struct irq_chip ltq_irq_type = { | ||
164 | "icu", | ||
165 | .irq_enable = ltq_enable_irq, | ||
166 | .irq_disable = ltq_disable_irq, | ||
167 | .irq_unmask = ltq_enable_irq, | ||
168 | .irq_ack = ltq_ack_irq, | ||
169 | .irq_mask = ltq_disable_irq, | ||
170 | .irq_mask_ack = ltq_mask_and_ack_irq, | ||
171 | }; | ||
172 | |||
173 | static struct irq_chip ltq_eiu_type = { | ||
174 | "eiu", | ||
175 | .irq_startup = ltq_startup_eiu_irq, | ||
176 | .irq_shutdown = ltq_shutdown_eiu_irq, | ||
177 | .irq_enable = ltq_enable_irq, | ||
178 | .irq_disable = ltq_disable_irq, | ||
179 | .irq_unmask = ltq_enable_irq, | ||
180 | .irq_ack = ltq_ack_irq, | ||
181 | .irq_mask = ltq_disable_irq, | ||
182 | .irq_mask_ack = ltq_mask_and_ack_irq, | ||
183 | }; | ||
184 | |||
185 | static void ltq_hw_irqdispatch(int module) | ||
186 | { | ||
187 | u32 irq; | ||
188 | |||
189 | irq = ltq_icu_r32(LTQ_ICU_IM0_IOSR + (module * LTQ_ICU_OFFSET)); | ||
190 | if (irq == 0) | ||
191 | return; | ||
192 | |||
193 | /* silicon bug causes only the msb set to 1 to be valid. all | ||
194 | * other bits might be bogus | ||
195 | */ | ||
196 | irq = __fls(irq); | ||
197 | do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module)); | ||
198 | |||
199 | /* if this is a EBU irq, we need to ack it or get a deadlock */ | ||
200 | if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0)) | ||
201 | ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10, | ||
202 | LTQ_EBU_PCC_ISTAT); | ||
203 | } | ||
204 | |||
205 | #define DEFINE_HWx_IRQDISPATCH(x) \ | ||
206 | static void ltq_hw ## x ## _irqdispatch(void) \ | ||
207 | { \ | ||
208 | ltq_hw_irqdispatch(x); \ | ||
209 | } | ||
210 | DEFINE_HWx_IRQDISPATCH(0) | ||
211 | DEFINE_HWx_IRQDISPATCH(1) | ||
212 | DEFINE_HWx_IRQDISPATCH(2) | ||
213 | DEFINE_HWx_IRQDISPATCH(3) | ||
214 | DEFINE_HWx_IRQDISPATCH(4) | ||
215 | |||
216 | static void ltq_hw5_irqdispatch(void) | ||
217 | { | ||
218 | do_IRQ(MIPS_CPU_TIMER_IRQ); | ||
219 | } | ||
220 | |||
221 | asmlinkage void plat_irq_dispatch(void) | ||
222 | { | ||
223 | unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; | ||
224 | unsigned int i; | ||
225 | |||
226 | if (pending & CAUSEF_IP7) { | ||
227 | do_IRQ(MIPS_CPU_TIMER_IRQ); | ||
228 | goto out; | ||
229 | } else { | ||
230 | for (i = 0; i < 5; i++) { | ||
231 | if (pending & (CAUSEF_IP2 << i)) { | ||
232 | ltq_hw_irqdispatch(i); | ||
233 | goto out; | ||
234 | } | ||
235 | } | ||
236 | } | ||
237 | pr_alert("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status()); | ||
238 | |||
239 | out: | ||
240 | return; | ||
241 | } | ||
242 | |||
243 | static struct irqaction cascade = { | ||
244 | .handler = no_action, | ||
245 | .flags = IRQF_DISABLED, | ||
246 | .name = "cascade", | ||
247 | }; | ||
248 | |||
249 | void __init arch_init_irq(void) | ||
250 | { | ||
251 | int i; | ||
252 | |||
253 | if (insert_resource(&iomem_resource, <q_icu_resource) < 0) | ||
254 | panic("Failed to insert icu memory\n"); | ||
255 | |||
256 | if (request_mem_region(ltq_icu_resource.start, | ||
257 | resource_size(<q_icu_resource), "icu") < 0) | ||
258 | panic("Failed to request icu memory\n"); | ||
259 | |||
260 | ltq_icu_membase = ioremap_nocache(ltq_icu_resource.start, | ||
261 | resource_size(<q_icu_resource)); | ||
262 | if (!ltq_icu_membase) | ||
263 | panic("Failed to remap icu memory\n"); | ||
264 | |||
265 | if (insert_resource(&iomem_resource, <q_eiu_resource) < 0) | ||
266 | panic("Failed to insert eiu memory\n"); | ||
267 | |||
268 | if (request_mem_region(ltq_eiu_resource.start, | ||
269 | resource_size(<q_eiu_resource), "eiu") < 0) | ||
270 | panic("Failed to request eiu memory\n"); | ||
271 | |||
272 | ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start, | ||
273 | resource_size(<q_eiu_resource)); | ||
274 | if (!ltq_eiu_membase) | ||
275 | panic("Failed to remap eiu memory\n"); | ||
276 | |||
277 | /* make sure all irqs are turned off by default */ | ||
278 | for (i = 0; i < 5; i++) | ||
279 | ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET)); | ||
280 | |||
281 | /* clear all possibly pending interrupts */ | ||
282 | ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET)); | ||
283 | |||
284 | mips_cpu_irq_init(); | ||
285 | |||
286 | for (i = 2; i <= 6; i++) | ||
287 | setup_irq(i, &cascade); | ||
288 | |||
289 | if (cpu_has_vint) { | ||
290 | pr_info("Setting up vectored interrupts\n"); | ||
291 | set_vi_handler(2, ltq_hw0_irqdispatch); | ||
292 | set_vi_handler(3, ltq_hw1_irqdispatch); | ||
293 | set_vi_handler(4, ltq_hw2_irqdispatch); | ||
294 | set_vi_handler(5, ltq_hw3_irqdispatch); | ||
295 | set_vi_handler(6, ltq_hw4_irqdispatch); | ||
296 | set_vi_handler(7, ltq_hw5_irqdispatch); | ||
297 | } | ||
298 | |||
299 | for (i = INT_NUM_IRQ0; | ||
300 | i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++) | ||
301 | if ((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) || | ||
302 | (i == LTQ_EIU_IR2)) | ||
303 | irq_set_chip_and_handler(i, <q_eiu_type, | ||
304 | handle_level_irq); | ||
305 | /* EIU3-5 only exist on ar9 and vr9 */ | ||
306 | else if (((i == LTQ_EIU_IR3) || (i == LTQ_EIU_IR4) || | ||
307 | (i == LTQ_EIU_IR5)) && (ltq_is_ar9() || ltq_is_vr9())) | ||
308 | irq_set_chip_and_handler(i, <q_eiu_type, | ||
309 | handle_level_irq); | ||
310 | else | ||
311 | irq_set_chip_and_handler(i, <q_irq_type, | ||
312 | handle_level_irq); | ||
313 | |||
314 | #if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC) | ||
315 | set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | | ||
316 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5); | ||
317 | #else | ||
318 | set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 | | ||
319 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5); | ||
320 | #endif | ||
321 | } | ||
322 | |||
323 | unsigned int __cpuinit get_c0_compare_int(void) | ||
324 | { | ||
325 | return CP0_LEGACY_COMPARE_IRQ; | ||
326 | } | ||
diff --git a/arch/mips/lantiq/machtypes.h b/arch/mips/lantiq/machtypes.h new file mode 100644 index 000000000000..7e01b8c484eb --- /dev/null +++ b/arch/mips/lantiq/machtypes.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LANTIQ_MACH_H__ | ||
10 | #define _LANTIQ_MACH_H__ | ||
11 | |||
12 | #include <asm/mips_machine.h> | ||
13 | |||
14 | enum lantiq_mach_type { | ||
15 | LTQ_MACH_GENERIC = 0, | ||
16 | LTQ_MACH_EASY50712, /* Danube evaluation board */ | ||
17 | LTQ_MACH_EASY50601, /* Amazon SE evaluation board */ | ||
18 | }; | ||
19 | |||
20 | #endif | ||
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c new file mode 100644 index 000000000000..56ba007bf1e5 --- /dev/null +++ b/arch/mips/lantiq/prom.c | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/clk.h> | ||
11 | #include <asm/bootinfo.h> | ||
12 | #include <asm/time.h> | ||
13 | |||
14 | #include <lantiq.h> | ||
15 | |||
16 | #include "prom.h" | ||
17 | #include "clk.h" | ||
18 | |||
19 | static struct ltq_soc_info soc_info; | ||
20 | |||
21 | unsigned int ltq_get_cpu_ver(void) | ||
22 | { | ||
23 | return soc_info.rev; | ||
24 | } | ||
25 | EXPORT_SYMBOL(ltq_get_cpu_ver); | ||
26 | |||
27 | unsigned int ltq_get_soc_type(void) | ||
28 | { | ||
29 | return soc_info.type; | ||
30 | } | ||
31 | EXPORT_SYMBOL(ltq_get_soc_type); | ||
32 | |||
33 | const char *get_system_type(void) | ||
34 | { | ||
35 | return soc_info.sys_type; | ||
36 | } | ||
37 | |||
38 | void prom_free_prom_memory(void) | ||
39 | { | ||
40 | } | ||
41 | |||
42 | static void __init prom_init_cmdline(void) | ||
43 | { | ||
44 | int argc = fw_arg0; | ||
45 | char **argv = (char **) KSEG1ADDR(fw_arg1); | ||
46 | int i; | ||
47 | |||
48 | for (i = 0; i < argc; i++) { | ||
49 | char *p = (char *) KSEG1ADDR(argv[i]); | ||
50 | |||
51 | if (p && *p) { | ||
52 | strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); | ||
53 | strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); | ||
54 | } | ||
55 | } | ||
56 | } | ||
57 | |||
58 | void __init prom_init(void) | ||
59 | { | ||
60 | struct clk *clk; | ||
61 | |||
62 | ltq_soc_detect(&soc_info); | ||
63 | clk_init(); | ||
64 | clk = clk_get(0, "cpu"); | ||
65 | snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev1.%d", | ||
66 | soc_info.name, soc_info.rev); | ||
67 | clk_put(clk); | ||
68 | soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0'; | ||
69 | pr_info("SoC: %s\n", soc_info.sys_type); | ||
70 | prom_init_cmdline(); | ||
71 | } | ||
diff --git a/arch/mips/lantiq/prom.h b/arch/mips/lantiq/prom.h new file mode 100644 index 000000000000..b4229d94280f --- /dev/null +++ b/arch/mips/lantiq/prom.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LTQ_PROM_H__ | ||
10 | #define _LTQ_PROM_H__ | ||
11 | |||
12 | #define LTQ_SYS_TYPE_LEN 0x100 | ||
13 | |||
14 | struct ltq_soc_info { | ||
15 | unsigned char *name; | ||
16 | unsigned int rev; | ||
17 | unsigned int partnum; | ||
18 | unsigned int type; | ||
19 | unsigned char sys_type[LTQ_SYS_TYPE_LEN]; | ||
20 | }; | ||
21 | |||
22 | extern void ltq_soc_detect(struct ltq_soc_info *i); | ||
23 | extern void ltq_soc_setup(void); | ||
24 | |||
25 | #endif | ||
diff --git a/arch/mips/lantiq/setup.c b/arch/mips/lantiq/setup.c new file mode 100644 index 000000000000..9b8af77ed0f9 --- /dev/null +++ b/arch/mips/lantiq/setup.c | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/io.h> | ||
12 | #include <linux/ioport.h> | ||
13 | #include <asm/bootinfo.h> | ||
14 | |||
15 | #include <lantiq_soc.h> | ||
16 | |||
17 | #include "machtypes.h" | ||
18 | #include "devices.h" | ||
19 | #include "prom.h" | ||
20 | |||
21 | void __init plat_mem_setup(void) | ||
22 | { | ||
23 | /* assume 16M as default incase uboot fails to pass proper ramsize */ | ||
24 | unsigned long memsize = 16; | ||
25 | char **envp = (char **) KSEG1ADDR(fw_arg2); | ||
26 | |||
27 | ioport_resource.start = IOPORT_RESOURCE_START; | ||
28 | ioport_resource.end = IOPORT_RESOURCE_END; | ||
29 | iomem_resource.start = IOMEM_RESOURCE_START; | ||
30 | iomem_resource.end = IOMEM_RESOURCE_END; | ||
31 | |||
32 | set_io_port_base((unsigned long) KSEG1); | ||
33 | |||
34 | while (*envp) { | ||
35 | char *e = (char *)KSEG1ADDR(*envp); | ||
36 | if (!strncmp(e, "memsize=", 8)) { | ||
37 | e += 8; | ||
38 | if (strict_strtoul(e, 0, &memsize)) | ||
39 | pr_warn("bad memsize specified\n"); | ||
40 | } | ||
41 | envp++; | ||
42 | } | ||
43 | memsize *= 1024 * 1024; | ||
44 | add_memory_region(0x00000000, memsize, BOOT_MEM_RAM); | ||
45 | } | ||
46 | |||
47 | static int __init | ||
48 | lantiq_setup(void) | ||
49 | { | ||
50 | ltq_soc_setup(); | ||
51 | mips_machine_setup(); | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | arch_initcall(lantiq_setup); | ||
56 | |||
57 | static void __init | ||
58 | lantiq_generic_init(void) | ||
59 | { | ||
60 | /* Nothing to do */ | ||
61 | } | ||
62 | |||
63 | MIPS_MACHINE(LTQ_MACH_GENERIC, | ||
64 | "Generic", | ||
65 | "Generic Lantiq based board", | ||
66 | lantiq_generic_init); | ||
diff --git a/arch/mips/lantiq/xway/Kconfig b/arch/mips/lantiq/xway/Kconfig new file mode 100644 index 000000000000..2b857de36620 --- /dev/null +++ b/arch/mips/lantiq/xway/Kconfig | |||
@@ -0,0 +1,23 @@ | |||
1 | if SOC_XWAY | ||
2 | |||
3 | menu "MIPS Machine" | ||
4 | |||
5 | config LANTIQ_MACH_EASY50712 | ||
6 | bool "Easy50712 - Danube" | ||
7 | default y | ||
8 | |||
9 | endmenu | ||
10 | |||
11 | endif | ||
12 | |||
13 | if SOC_AMAZON_SE | ||
14 | |||
15 | menu "MIPS Machine" | ||
16 | |||
17 | config LANTIQ_MACH_EASY50601 | ||
18 | bool "Easy50601 - Amazon SE" | ||
19 | default y | ||
20 | |||
21 | endmenu | ||
22 | |||
23 | endif | ||
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile new file mode 100644 index 000000000000..c517f2e77563 --- /dev/null +++ b/arch/mips/lantiq/xway/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o | ||
2 | |||
3 | obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o setup-xway.o | ||
4 | obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o setup-ase.o | ||
5 | |||
6 | obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o | ||
7 | obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o | ||
diff --git a/arch/mips/lantiq/xway/clk-ase.c b/arch/mips/lantiq/xway/clk-ase.c new file mode 100644 index 000000000000..22d823acd536 --- /dev/null +++ b/arch/mips/lantiq/xway/clk-ase.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/io.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/clk.h> | ||
13 | |||
14 | #include <asm/time.h> | ||
15 | #include <asm/irq.h> | ||
16 | #include <asm/div64.h> | ||
17 | |||
18 | #include <lantiq_soc.h> | ||
19 | |||
20 | /* cgu registers */ | ||
21 | #define LTQ_CGU_SYS 0x0010 | ||
22 | |||
23 | unsigned int ltq_get_io_region_clock(void) | ||
24 | { | ||
25 | return CLOCK_133M; | ||
26 | } | ||
27 | EXPORT_SYMBOL(ltq_get_io_region_clock); | ||
28 | |||
29 | unsigned int ltq_get_fpi_bus_clock(int fpi) | ||
30 | { | ||
31 | return CLOCK_133M; | ||
32 | } | ||
33 | EXPORT_SYMBOL(ltq_get_fpi_bus_clock); | ||
34 | |||
35 | unsigned int ltq_get_cpu_hz(void) | ||
36 | { | ||
37 | if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5)) | ||
38 | return CLOCK_266M; | ||
39 | else | ||
40 | return CLOCK_133M; | ||
41 | } | ||
42 | EXPORT_SYMBOL(ltq_get_cpu_hz); | ||
43 | |||
44 | unsigned int ltq_get_fpi_hz(void) | ||
45 | { | ||
46 | return CLOCK_133M; | ||
47 | } | ||
48 | EXPORT_SYMBOL(ltq_get_fpi_hz); | ||
diff --git a/arch/mips/lantiq/xway/clk-xway.c b/arch/mips/lantiq/xway/clk-xway.c new file mode 100644 index 000000000000..ddd39593c581 --- /dev/null +++ b/arch/mips/lantiq/xway/clk-xway.c | |||
@@ -0,0 +1,223 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/io.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/clk.h> | ||
13 | |||
14 | #include <asm/time.h> | ||
15 | #include <asm/irq.h> | ||
16 | #include <asm/div64.h> | ||
17 | |||
18 | #include <lantiq_soc.h> | ||
19 | |||
20 | static unsigned int ltq_ram_clocks[] = { | ||
21 | CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M }; | ||
22 | #define DDR_HZ ltq_ram_clocks[ltq_cgu_r32(LTQ_CGU_SYS) & 0x3] | ||
23 | |||
24 | #define BASIC_FREQUENCY_1 35328000 | ||
25 | #define BASIC_FREQUENCY_2 36000000 | ||
26 | #define BASIS_REQUENCY_USB 12000000 | ||
27 | |||
28 | #define GET_BITS(x, msb, lsb) \ | ||
29 | (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb)) | ||
30 | |||
31 | #define LTQ_CGU_PLL0_CFG 0x0004 | ||
32 | #define LTQ_CGU_PLL1_CFG 0x0008 | ||
33 | #define LTQ_CGU_PLL2_CFG 0x000C | ||
34 | #define LTQ_CGU_SYS 0x0010 | ||
35 | #define LTQ_CGU_UPDATE 0x0014 | ||
36 | #define LTQ_CGU_IF_CLK 0x0018 | ||
37 | #define LTQ_CGU_OSC_CON 0x001C | ||
38 | #define LTQ_CGU_SMD 0x0020 | ||
39 | #define LTQ_CGU_CT1SR 0x0028 | ||
40 | #define LTQ_CGU_CT2SR 0x002C | ||
41 | #define LTQ_CGU_PCMCR 0x0030 | ||
42 | #define LTQ_CGU_PCI_CR 0x0034 | ||
43 | #define LTQ_CGU_PD_PC 0x0038 | ||
44 | #define LTQ_CGU_FMR 0x003C | ||
45 | |||
46 | #define CGU_PLL0_PHASE_DIVIDER_ENABLE \ | ||
47 | (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 31)) | ||
48 | #define CGU_PLL0_BYPASS \ | ||
49 | (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 30)) | ||
50 | #define CGU_PLL0_CFG_DSMSEL \ | ||
51 | (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 28)) | ||
52 | #define CGU_PLL0_CFG_FRAC_EN \ | ||
53 | (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 27)) | ||
54 | #define CGU_PLL1_SRC \ | ||
55 | (ltq_cgu_r32(LTQ_CGU_PLL1_CFG) & (1 << 31)) | ||
56 | #define CGU_PLL2_PHASE_DIVIDER_ENABLE \ | ||
57 | (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & (1 << 20)) | ||
58 | #define CGU_SYS_FPI_SEL (1 << 6) | ||
59 | #define CGU_SYS_DDR_SEL 0x3 | ||
60 | #define CGU_PLL0_SRC (1 << 29) | ||
61 | |||
62 | #define CGU_PLL0_CFG_PLLK GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 26, 17) | ||
63 | #define CGU_PLL0_CFG_PLLN GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 12, 6) | ||
64 | #define CGU_PLL0_CFG_PLLM GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 5, 2) | ||
65 | #define CGU_PLL2_SRC GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 18, 17) | ||
66 | #define CGU_PLL2_CFG_INPUT_DIV GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 16, 13) | ||
67 | |||
68 | static unsigned int ltq_get_pll0_fdiv(void); | ||
69 | |||
70 | static inline unsigned int get_input_clock(int pll) | ||
71 | { | ||
72 | switch (pll) { | ||
73 | case 0: | ||
74 | if (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & CGU_PLL0_SRC) | ||
75 | return BASIS_REQUENCY_USB; | ||
76 | else if (CGU_PLL0_PHASE_DIVIDER_ENABLE) | ||
77 | return BASIC_FREQUENCY_1; | ||
78 | else | ||
79 | return BASIC_FREQUENCY_2; | ||
80 | case 1: | ||
81 | if (CGU_PLL1_SRC) | ||
82 | return BASIS_REQUENCY_USB; | ||
83 | else if (CGU_PLL0_PHASE_DIVIDER_ENABLE) | ||
84 | return BASIC_FREQUENCY_1; | ||
85 | else | ||
86 | return BASIC_FREQUENCY_2; | ||
87 | case 2: | ||
88 | switch (CGU_PLL2_SRC) { | ||
89 | case 0: | ||
90 | return ltq_get_pll0_fdiv(); | ||
91 | case 1: | ||
92 | return CGU_PLL2_PHASE_DIVIDER_ENABLE ? | ||
93 | BASIC_FREQUENCY_1 : | ||
94 | BASIC_FREQUENCY_2; | ||
95 | case 2: | ||
96 | return BASIS_REQUENCY_USB; | ||
97 | } | ||
98 | default: | ||
99 | return 0; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den) | ||
104 | { | ||
105 | u64 res, clock = get_input_clock(pll); | ||
106 | |||
107 | res = num * clock; | ||
108 | do_div(res, den); | ||
109 | return res; | ||
110 | } | ||
111 | |||
112 | static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N, | ||
113 | unsigned int K) | ||
114 | { | ||
115 | unsigned int num = ((N + 1) << 10) + K; | ||
116 | unsigned int den = (M + 1) << 10; | ||
117 | |||
118 | return cal_dsm(pll, num, den); | ||
119 | } | ||
120 | |||
121 | static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N, | ||
122 | unsigned int K) | ||
123 | { | ||
124 | unsigned int num = ((N + 1) << 11) + K + 512; | ||
125 | unsigned int den = (M + 1) << 11; | ||
126 | |||
127 | return cal_dsm(pll, num, den); | ||
128 | } | ||
129 | |||
130 | static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N, | ||
131 | unsigned int K) | ||
132 | { | ||
133 | unsigned int num = K >= 512 ? | ||
134 | ((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584; | ||
135 | unsigned int den = (M + 1) << 12; | ||
136 | |||
137 | return cal_dsm(pll, num, den); | ||
138 | } | ||
139 | |||
140 | static inline unsigned int dsm(int pll, unsigned int M, unsigned int N, | ||
141 | unsigned int K, unsigned int dsmsel, unsigned int phase_div_en) | ||
142 | { | ||
143 | if (!dsmsel) | ||
144 | return mash_dsm(pll, M, N, K); | ||
145 | else if (!phase_div_en) | ||
146 | return mash_dsm(pll, M, N, K); | ||
147 | else | ||
148 | return ssff_dsm_2(pll, M, N, K); | ||
149 | } | ||
150 | |||
151 | static inline unsigned int ltq_get_pll0_fosc(void) | ||
152 | { | ||
153 | if (CGU_PLL0_BYPASS) | ||
154 | return get_input_clock(0); | ||
155 | else | ||
156 | return !CGU_PLL0_CFG_FRAC_EN | ||
157 | ? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0, | ||
158 | CGU_PLL0_CFG_DSMSEL, | ||
159 | CGU_PLL0_PHASE_DIVIDER_ENABLE) | ||
160 | : dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, | ||
161 | CGU_PLL0_CFG_PLLK, CGU_PLL0_CFG_DSMSEL, | ||
162 | CGU_PLL0_PHASE_DIVIDER_ENABLE); | ||
163 | } | ||
164 | |||
165 | static unsigned int ltq_get_pll0_fdiv(void) | ||
166 | { | ||
167 | unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1; | ||
168 | |||
169 | return (ltq_get_pll0_fosc() + (div >> 1)) / div; | ||
170 | } | ||
171 | |||
172 | unsigned int ltq_get_io_region_clock(void) | ||
173 | { | ||
174 | unsigned int ret = ltq_get_pll0_fosc(); | ||
175 | |||
176 | switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) { | ||
177 | default: | ||
178 | case 0: | ||
179 | return (ret + 1) / 2; | ||
180 | case 1: | ||
181 | return (ret * 2 + 2) / 5; | ||
182 | case 2: | ||
183 | return (ret + 1) / 3; | ||
184 | case 3: | ||
185 | return (ret + 2) / 4; | ||
186 | } | ||
187 | } | ||
188 | EXPORT_SYMBOL(ltq_get_io_region_clock); | ||
189 | |||
190 | unsigned int ltq_get_fpi_bus_clock(int fpi) | ||
191 | { | ||
192 | unsigned int ret = ltq_get_io_region_clock(); | ||
193 | |||
194 | if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL)) | ||
195 | ret >>= 1; | ||
196 | return ret; | ||
197 | } | ||
198 | EXPORT_SYMBOL(ltq_get_fpi_bus_clock); | ||
199 | |||
200 | unsigned int ltq_get_cpu_hz(void) | ||
201 | { | ||
202 | switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) { | ||
203 | case 0: | ||
204 | return CLOCK_333M; | ||
205 | case 4: | ||
206 | return DDR_HZ; | ||
207 | case 8: | ||
208 | return DDR_HZ << 1; | ||
209 | default: | ||
210 | return DDR_HZ >> 1; | ||
211 | } | ||
212 | } | ||
213 | EXPORT_SYMBOL(ltq_get_cpu_hz); | ||
214 | |||
215 | unsigned int ltq_get_fpi_hz(void) | ||
216 | { | ||
217 | unsigned int ddr_clock = DDR_HZ; | ||
218 | |||
219 | if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40) | ||
220 | return ddr_clock >> 1; | ||
221 | return ddr_clock; | ||
222 | } | ||
223 | EXPORT_SYMBOL(ltq_get_fpi_hz); | ||
diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c new file mode 100644 index 000000000000..e09e789dfc27 --- /dev/null +++ b/arch/mips/lantiq/xway/devices.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/mtd/physmap.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/reboot.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/leds.h> | ||
18 | #include <linux/etherdevice.h> | ||
19 | #include <linux/reboot.h> | ||
20 | #include <linux/time.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/leds.h> | ||
24 | |||
25 | #include <asm/bootinfo.h> | ||
26 | #include <asm/irq.h> | ||
27 | |||
28 | #include <lantiq_soc.h> | ||
29 | #include <lantiq_irq.h> | ||
30 | #include <lantiq_platform.h> | ||
31 | |||
32 | #include "devices.h" | ||
33 | |||
34 | /* gpio */ | ||
35 | static struct resource ltq_gpio_resource[] = { | ||
36 | { | ||
37 | .name = "gpio0", | ||
38 | .start = LTQ_GPIO0_BASE_ADDR, | ||
39 | .end = LTQ_GPIO0_BASE_ADDR + LTQ_GPIO_SIZE - 1, | ||
40 | .flags = IORESOURCE_MEM, | ||
41 | }, { | ||
42 | .name = "gpio1", | ||
43 | .start = LTQ_GPIO1_BASE_ADDR, | ||
44 | .end = LTQ_GPIO1_BASE_ADDR + LTQ_GPIO_SIZE - 1, | ||
45 | .flags = IORESOURCE_MEM, | ||
46 | }, { | ||
47 | .name = "gpio2", | ||
48 | .start = LTQ_GPIO2_BASE_ADDR, | ||
49 | .end = LTQ_GPIO2_BASE_ADDR + LTQ_GPIO_SIZE - 1, | ||
50 | .flags = IORESOURCE_MEM, | ||
51 | } | ||
52 | }; | ||
53 | |||
54 | void __init ltq_register_gpio(void) | ||
55 | { | ||
56 | platform_device_register_simple("ltq_gpio", 0, | ||
57 | <q_gpio_resource[0], 1); | ||
58 | platform_device_register_simple("ltq_gpio", 1, | ||
59 | <q_gpio_resource[1], 1); | ||
60 | |||
61 | /* AR9 and VR9 have an extra gpio block */ | ||
62 | if (ltq_is_ar9() || ltq_is_vr9()) { | ||
63 | platform_device_register_simple("ltq_gpio", 2, | ||
64 | <q_gpio_resource[2], 1); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | /* serial to parallel conversion */ | ||
69 | static struct resource ltq_stp_resource = { | ||
70 | .name = "stp", | ||
71 | .start = LTQ_STP_BASE_ADDR, | ||
72 | .end = LTQ_STP_BASE_ADDR + LTQ_STP_SIZE - 1, | ||
73 | .flags = IORESOURCE_MEM, | ||
74 | }; | ||
75 | |||
76 | void __init ltq_register_gpio_stp(void) | ||
77 | { | ||
78 | platform_device_register_simple("ltq_stp", 0, <q_stp_resource, 1); | ||
79 | } | ||
80 | |||
81 | /* asc ports - amazon se has its own serial mapping */ | ||
82 | static struct resource ltq_ase_asc_resources[] = { | ||
83 | { | ||
84 | .name = "asc0", | ||
85 | .start = LTQ_ASC1_BASE_ADDR, | ||
86 | .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1, | ||
87 | .flags = IORESOURCE_MEM, | ||
88 | }, | ||
89 | IRQ_RES(tx, LTQ_ASC_ASE_TIR), | ||
90 | IRQ_RES(rx, LTQ_ASC_ASE_RIR), | ||
91 | IRQ_RES(err, LTQ_ASC_ASE_EIR), | ||
92 | }; | ||
93 | |||
94 | void __init ltq_register_ase_asc(void) | ||
95 | { | ||
96 | platform_device_register_simple("ltq_asc", 0, | ||
97 | ltq_ase_asc_resources, ARRAY_SIZE(ltq_ase_asc_resources)); | ||
98 | } | ||
99 | |||
100 | /* ethernet */ | ||
101 | static struct resource ltq_etop_resources = { | ||
102 | .name = "etop", | ||
103 | .start = LTQ_ETOP_BASE_ADDR, | ||
104 | .end = LTQ_ETOP_BASE_ADDR + LTQ_ETOP_SIZE - 1, | ||
105 | .flags = IORESOURCE_MEM, | ||
106 | }; | ||
107 | |||
108 | static struct platform_device ltq_etop = { | ||
109 | .name = "ltq_etop", | ||
110 | .resource = <q_etop_resources, | ||
111 | .num_resources = 1, | ||
112 | }; | ||
113 | |||
114 | void __init | ||
115 | ltq_register_etop(struct ltq_eth_data *eth) | ||
116 | { | ||
117 | if (eth) { | ||
118 | ltq_etop.dev.platform_data = eth; | ||
119 | platform_device_register(<q_etop); | ||
120 | } | ||
121 | } | ||
diff --git a/arch/mips/lantiq/xway/devices.h b/arch/mips/lantiq/xway/devices.h new file mode 100644 index 000000000000..e90493471bc1 --- /dev/null +++ b/arch/mips/lantiq/xway/devices.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LTQ_DEVICES_XWAY_H__ | ||
10 | #define _LTQ_DEVICES_XWAY_H__ | ||
11 | |||
12 | #include "../devices.h" | ||
13 | #include <linux/phy.h> | ||
14 | |||
15 | extern void ltq_register_gpio(void); | ||
16 | extern void ltq_register_gpio_stp(void); | ||
17 | extern void ltq_register_ase_asc(void); | ||
18 | extern void ltq_register_etop(struct ltq_eth_data *eth); | ||
19 | |||
20 | #endif | ||
diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c new file mode 100644 index 000000000000..4278a459d6c4 --- /dev/null +++ b/arch/mips/lantiq/xway/dma.c | |||
@@ -0,0 +1,253 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * You should have received a copy of the GNU General Public License | ||
12 | * along with this program; if not, write to the Free Software | ||
13 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
14 | * | ||
15 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | ||
16 | */ | ||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/dma-mapping.h> | ||
22 | |||
23 | #include <lantiq_soc.h> | ||
24 | #include <xway_dma.h> | ||
25 | |||
26 | #define LTQ_DMA_CTRL 0x10 | ||
27 | #define LTQ_DMA_CPOLL 0x14 | ||
28 | #define LTQ_DMA_CS 0x18 | ||
29 | #define LTQ_DMA_CCTRL 0x1C | ||
30 | #define LTQ_DMA_CDBA 0x20 | ||
31 | #define LTQ_DMA_CDLEN 0x24 | ||
32 | #define LTQ_DMA_CIS 0x28 | ||
33 | #define LTQ_DMA_CIE 0x2C | ||
34 | #define LTQ_DMA_PS 0x40 | ||
35 | #define LTQ_DMA_PCTRL 0x44 | ||
36 | #define LTQ_DMA_IRNEN 0xf4 | ||
37 | |||
38 | #define DMA_DESCPT BIT(3) /* descriptor complete irq */ | ||
39 | #define DMA_TX BIT(8) /* TX channel direction */ | ||
40 | #define DMA_CHAN_ON BIT(0) /* channel on / off bit */ | ||
41 | #define DMA_PDEN BIT(6) /* enable packet drop */ | ||
42 | #define DMA_CHAN_RST BIT(1) /* channel on / off bit */ | ||
43 | #define DMA_RESET BIT(0) /* channel on / off bit */ | ||
44 | #define DMA_IRQ_ACK 0x7e /* IRQ status register */ | ||
45 | #define DMA_POLL BIT(31) /* turn on channel polling */ | ||
46 | #define DMA_CLK_DIV4 BIT(6) /* polling clock divider */ | ||
47 | #define DMA_2W_BURST BIT(1) /* 2 word burst length */ | ||
48 | #define DMA_MAX_CHANNEL 20 /* the soc has 20 channels */ | ||
49 | #define DMA_ETOP_ENDIANESS (0xf << 8) /* endianess swap etop channels */ | ||
50 | #define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */ | ||
51 | |||
52 | #define ltq_dma_r32(x) ltq_r32(ltq_dma_membase + (x)) | ||
53 | #define ltq_dma_w32(x, y) ltq_w32(x, ltq_dma_membase + (y)) | ||
54 | #define ltq_dma_w32_mask(x, y, z) ltq_w32_mask(x, y, \ | ||
55 | ltq_dma_membase + (z)) | ||
56 | |||
57 | static struct resource ltq_dma_resource = { | ||
58 | .name = "dma", | ||
59 | .start = LTQ_DMA_BASE_ADDR, | ||
60 | .end = LTQ_DMA_BASE_ADDR + LTQ_DMA_SIZE - 1, | ||
61 | .flags = IORESOURCE_MEM, | ||
62 | }; | ||
63 | |||
64 | static void __iomem *ltq_dma_membase; | ||
65 | |||
66 | void | ||
67 | ltq_dma_enable_irq(struct ltq_dma_channel *ch) | ||
68 | { | ||
69 | unsigned long flags; | ||
70 | |||
71 | local_irq_save(flags); | ||
72 | ltq_dma_w32(ch->nr, LTQ_DMA_CS); | ||
73 | ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN); | ||
74 | local_irq_restore(flags); | ||
75 | } | ||
76 | EXPORT_SYMBOL_GPL(ltq_dma_enable_irq); | ||
77 | |||
78 | void | ||
79 | ltq_dma_disable_irq(struct ltq_dma_channel *ch) | ||
80 | { | ||
81 | unsigned long flags; | ||
82 | |||
83 | local_irq_save(flags); | ||
84 | ltq_dma_w32(ch->nr, LTQ_DMA_CS); | ||
85 | ltq_dma_w32_mask(1 << ch->nr, 0, LTQ_DMA_IRNEN); | ||
86 | local_irq_restore(flags); | ||
87 | } | ||
88 | EXPORT_SYMBOL_GPL(ltq_dma_disable_irq); | ||
89 | |||
90 | void | ||
91 | ltq_dma_ack_irq(struct ltq_dma_channel *ch) | ||
92 | { | ||
93 | unsigned long flags; | ||
94 | |||
95 | local_irq_save(flags); | ||
96 | ltq_dma_w32(ch->nr, LTQ_DMA_CS); | ||
97 | ltq_dma_w32(DMA_IRQ_ACK, LTQ_DMA_CIS); | ||
98 | local_irq_restore(flags); | ||
99 | } | ||
100 | EXPORT_SYMBOL_GPL(ltq_dma_ack_irq); | ||
101 | |||
102 | void | ||
103 | ltq_dma_open(struct ltq_dma_channel *ch) | ||
104 | { | ||
105 | unsigned long flag; | ||
106 | |||
107 | local_irq_save(flag); | ||
108 | ltq_dma_w32(ch->nr, LTQ_DMA_CS); | ||
109 | ltq_dma_w32_mask(0, DMA_CHAN_ON, LTQ_DMA_CCTRL); | ||
110 | ltq_dma_enable_irq(ch); | ||
111 | local_irq_restore(flag); | ||
112 | } | ||
113 | EXPORT_SYMBOL_GPL(ltq_dma_open); | ||
114 | |||
115 | void | ||
116 | ltq_dma_close(struct ltq_dma_channel *ch) | ||
117 | { | ||
118 | unsigned long flag; | ||
119 | |||
120 | local_irq_save(flag); | ||
121 | ltq_dma_w32(ch->nr, LTQ_DMA_CS); | ||
122 | ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); | ||
123 | ltq_dma_disable_irq(ch); | ||
124 | local_irq_restore(flag); | ||
125 | } | ||
126 | EXPORT_SYMBOL_GPL(ltq_dma_close); | ||
127 | |||
128 | static void | ||
129 | ltq_dma_alloc(struct ltq_dma_channel *ch) | ||
130 | { | ||
131 | unsigned long flags; | ||
132 | |||
133 | ch->desc = 0; | ||
134 | ch->desc_base = dma_alloc_coherent(NULL, | ||
135 | LTQ_DESC_NUM * LTQ_DESC_SIZE, | ||
136 | &ch->phys, GFP_ATOMIC); | ||
137 | memset(ch->desc_base, 0, LTQ_DESC_NUM * LTQ_DESC_SIZE); | ||
138 | |||
139 | local_irq_save(flags); | ||
140 | ltq_dma_w32(ch->nr, LTQ_DMA_CS); | ||
141 | ltq_dma_w32(ch->phys, LTQ_DMA_CDBA); | ||
142 | ltq_dma_w32(LTQ_DESC_NUM, LTQ_DMA_CDLEN); | ||
143 | ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); | ||
144 | wmb(); | ||
145 | ltq_dma_w32_mask(0, DMA_CHAN_RST, LTQ_DMA_CCTRL); | ||
146 | while (ltq_dma_r32(LTQ_DMA_CCTRL) & DMA_CHAN_RST) | ||
147 | ; | ||
148 | local_irq_restore(flags); | ||
149 | } | ||
150 | |||
151 | void | ||
152 | ltq_dma_alloc_tx(struct ltq_dma_channel *ch) | ||
153 | { | ||
154 | unsigned long flags; | ||
155 | |||
156 | ltq_dma_alloc(ch); | ||
157 | |||
158 | local_irq_save(flags); | ||
159 | ltq_dma_w32(DMA_DESCPT, LTQ_DMA_CIE); | ||
160 | ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN); | ||
161 | ltq_dma_w32(DMA_WEIGHT | DMA_TX, LTQ_DMA_CCTRL); | ||
162 | local_irq_restore(flags); | ||
163 | } | ||
164 | EXPORT_SYMBOL_GPL(ltq_dma_alloc_tx); | ||
165 | |||
166 | void | ||
167 | ltq_dma_alloc_rx(struct ltq_dma_channel *ch) | ||
168 | { | ||
169 | unsigned long flags; | ||
170 | |||
171 | ltq_dma_alloc(ch); | ||
172 | |||
173 | local_irq_save(flags); | ||
174 | ltq_dma_w32(DMA_DESCPT, LTQ_DMA_CIE); | ||
175 | ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN); | ||
176 | ltq_dma_w32(DMA_WEIGHT, LTQ_DMA_CCTRL); | ||
177 | local_irq_restore(flags); | ||
178 | } | ||
179 | EXPORT_SYMBOL_GPL(ltq_dma_alloc_rx); | ||
180 | |||
181 | void | ||
182 | ltq_dma_free(struct ltq_dma_channel *ch) | ||
183 | { | ||
184 | if (!ch->desc_base) | ||
185 | return; | ||
186 | ltq_dma_close(ch); | ||
187 | dma_free_coherent(NULL, LTQ_DESC_NUM * LTQ_DESC_SIZE, | ||
188 | ch->desc_base, ch->phys); | ||
189 | } | ||
190 | EXPORT_SYMBOL_GPL(ltq_dma_free); | ||
191 | |||
192 | void | ||
193 | ltq_dma_init_port(int p) | ||
194 | { | ||
195 | ltq_dma_w32(p, LTQ_DMA_PS); | ||
196 | switch (p) { | ||
197 | case DMA_PORT_ETOP: | ||
198 | /* | ||
199 | * Tell the DMA engine to swap the endianess of data frames and | ||
200 | * drop packets if the channel arbitration fails. | ||
201 | */ | ||
202 | ltq_dma_w32_mask(0, DMA_ETOP_ENDIANESS | DMA_PDEN, | ||
203 | LTQ_DMA_PCTRL); | ||
204 | break; | ||
205 | |||
206 | case DMA_PORT_DEU: | ||
207 | ltq_dma_w32((DMA_2W_BURST << 4) | (DMA_2W_BURST << 2), | ||
208 | LTQ_DMA_PCTRL); | ||
209 | break; | ||
210 | |||
211 | default: | ||
212 | break; | ||
213 | } | ||
214 | } | ||
215 | EXPORT_SYMBOL_GPL(ltq_dma_init_port); | ||
216 | |||
217 | int __init | ||
218 | ltq_dma_init(void) | ||
219 | { | ||
220 | int i; | ||
221 | |||
222 | /* insert and request the memory region */ | ||
223 | if (insert_resource(&iomem_resource, <q_dma_resource) < 0) | ||
224 | panic("Failed to insert dma memory\n"); | ||
225 | |||
226 | if (request_mem_region(ltq_dma_resource.start, | ||
227 | resource_size(<q_dma_resource), "dma") < 0) | ||
228 | panic("Failed to request dma memory\n"); | ||
229 | |||
230 | /* remap dma register range */ | ||
231 | ltq_dma_membase = ioremap_nocache(ltq_dma_resource.start, | ||
232 | resource_size(<q_dma_resource)); | ||
233 | if (!ltq_dma_membase) | ||
234 | panic("Failed to remap dma memory\n"); | ||
235 | |||
236 | /* power up and reset the dma engine */ | ||
237 | ltq_pmu_enable(PMU_DMA); | ||
238 | ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL); | ||
239 | |||
240 | /* disable all interrupts */ | ||
241 | ltq_dma_w32(0, LTQ_DMA_IRNEN); | ||
242 | |||
243 | /* reset/configure each channel */ | ||
244 | for (i = 0; i < DMA_MAX_CHANNEL; i++) { | ||
245 | ltq_dma_w32(i, LTQ_DMA_CS); | ||
246 | ltq_dma_w32(DMA_CHAN_RST, LTQ_DMA_CCTRL); | ||
247 | ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); | ||
248 | ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); | ||
249 | } | ||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | postcore_initcall(ltq_dma_init); | ||
diff --git a/arch/mips/lantiq/xway/ebu.c b/arch/mips/lantiq/xway/ebu.c new file mode 100644 index 000000000000..66eb52fa50a1 --- /dev/null +++ b/arch/mips/lantiq/xway/ebu.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * EBU - the external bus unit attaches PCI, NOR and NAND | ||
7 | * | ||
8 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/version.h> | ||
14 | #include <linux/ioport.h> | ||
15 | |||
16 | #include <lantiq_soc.h> | ||
17 | |||
18 | /* all access to the ebu must be locked */ | ||
19 | DEFINE_SPINLOCK(ebu_lock); | ||
20 | EXPORT_SYMBOL_GPL(ebu_lock); | ||
21 | |||
22 | static struct resource ltq_ebu_resource = { | ||
23 | .name = "ebu", | ||
24 | .start = LTQ_EBU_BASE_ADDR, | ||
25 | .end = LTQ_EBU_BASE_ADDR + LTQ_EBU_SIZE - 1, | ||
26 | .flags = IORESOURCE_MEM, | ||
27 | }; | ||
28 | |||
29 | /* remapped base addr of the clock unit and external bus unit */ | ||
30 | void __iomem *ltq_ebu_membase; | ||
31 | |||
32 | static int __init lantiq_ebu_init(void) | ||
33 | { | ||
34 | /* insert and request the memory region */ | ||
35 | if (insert_resource(&iomem_resource, <q_ebu_resource) < 0) | ||
36 | panic("Failed to insert ebu memory\n"); | ||
37 | |||
38 | if (request_mem_region(ltq_ebu_resource.start, | ||
39 | resource_size(<q_ebu_resource), "ebu") < 0) | ||
40 | panic("Failed to request ebu memory\n"); | ||
41 | |||
42 | /* remap ebu register range */ | ||
43 | ltq_ebu_membase = ioremap_nocache(ltq_ebu_resource.start, | ||
44 | resource_size(<q_ebu_resource)); | ||
45 | if (!ltq_ebu_membase) | ||
46 | panic("Failed to remap ebu memory\n"); | ||
47 | |||
48 | /* make sure to unprotect the memory region where flash is located */ | ||
49 | ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0); | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | postcore_initcall(lantiq_ebu_init); | ||
diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c new file mode 100644 index 000000000000..a321451a5455 --- /dev/null +++ b/arch/mips/lantiq/xway/gpio.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/slab.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/gpio.h> | ||
13 | #include <linux/ioport.h> | ||
14 | #include <linux/io.h> | ||
15 | |||
16 | #include <lantiq_soc.h> | ||
17 | |||
18 | #define LTQ_GPIO_OUT 0x00 | ||
19 | #define LTQ_GPIO_IN 0x04 | ||
20 | #define LTQ_GPIO_DIR 0x08 | ||
21 | #define LTQ_GPIO_ALTSEL0 0x0C | ||
22 | #define LTQ_GPIO_ALTSEL1 0x10 | ||
23 | #define LTQ_GPIO_OD 0x14 | ||
24 | |||
25 | #define PINS_PER_PORT 16 | ||
26 | #define MAX_PORTS 3 | ||
27 | |||
28 | #define ltq_gpio_getbit(m, r, p) (!!(ltq_r32(m + r) & (1 << p))) | ||
29 | #define ltq_gpio_setbit(m, r, p) ltq_w32_mask(0, (1 << p), m + r) | ||
30 | #define ltq_gpio_clearbit(m, r, p) ltq_w32_mask((1 << p), 0, m + r) | ||
31 | |||
32 | struct ltq_gpio { | ||
33 | void __iomem *membase; | ||
34 | struct gpio_chip chip; | ||
35 | }; | ||
36 | |||
37 | static struct ltq_gpio ltq_gpio_port[MAX_PORTS]; | ||
38 | |||
39 | int gpio_to_irq(unsigned int gpio) | ||
40 | { | ||
41 | return -EINVAL; | ||
42 | } | ||
43 | EXPORT_SYMBOL(gpio_to_irq); | ||
44 | |||
45 | int irq_to_gpio(unsigned int gpio) | ||
46 | { | ||
47 | return -EINVAL; | ||
48 | } | ||
49 | EXPORT_SYMBOL(irq_to_gpio); | ||
50 | |||
51 | int ltq_gpio_request(unsigned int pin, unsigned int alt0, | ||
52 | unsigned int alt1, unsigned int dir, const char *name) | ||
53 | { | ||
54 | int id = 0; | ||
55 | |||
56 | if (pin >= (MAX_PORTS * PINS_PER_PORT)) | ||
57 | return -EINVAL; | ||
58 | if (gpio_request(pin, name)) { | ||
59 | pr_err("failed to setup lantiq gpio: %s\n", name); | ||
60 | return -EBUSY; | ||
61 | } | ||
62 | if (dir) | ||
63 | gpio_direction_output(pin, 1); | ||
64 | else | ||
65 | gpio_direction_input(pin); | ||
66 | while (pin >= PINS_PER_PORT) { | ||
67 | pin -= PINS_PER_PORT; | ||
68 | id++; | ||
69 | } | ||
70 | if (alt0) | ||
71 | ltq_gpio_setbit(ltq_gpio_port[id].membase, | ||
72 | LTQ_GPIO_ALTSEL0, pin); | ||
73 | else | ||
74 | ltq_gpio_clearbit(ltq_gpio_port[id].membase, | ||
75 | LTQ_GPIO_ALTSEL0, pin); | ||
76 | if (alt1) | ||
77 | ltq_gpio_setbit(ltq_gpio_port[id].membase, | ||
78 | LTQ_GPIO_ALTSEL1, pin); | ||
79 | else | ||
80 | ltq_gpio_clearbit(ltq_gpio_port[id].membase, | ||
81 | LTQ_GPIO_ALTSEL1, pin); | ||
82 | return 0; | ||
83 | } | ||
84 | EXPORT_SYMBOL(ltq_gpio_request); | ||
85 | |||
86 | static void ltq_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) | ||
87 | { | ||
88 | struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); | ||
89 | |||
90 | if (value) | ||
91 | ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset); | ||
92 | else | ||
93 | ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset); | ||
94 | } | ||
95 | |||
96 | static int ltq_gpio_get(struct gpio_chip *chip, unsigned int offset) | ||
97 | { | ||
98 | struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); | ||
99 | |||
100 | return ltq_gpio_getbit(ltq_gpio->membase, LTQ_GPIO_IN, offset); | ||
101 | } | ||
102 | |||
103 | static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) | ||
104 | { | ||
105 | struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); | ||
106 | |||
107 | ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset); | ||
108 | ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset); | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static int ltq_gpio_direction_output(struct gpio_chip *chip, | ||
114 | unsigned int offset, int value) | ||
115 | { | ||
116 | struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); | ||
117 | |||
118 | ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset); | ||
119 | ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset); | ||
120 | ltq_gpio_set(chip, offset, value); | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset) | ||
126 | { | ||
127 | struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); | ||
128 | |||
129 | ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset); | ||
130 | ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset); | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static int ltq_gpio_probe(struct platform_device *pdev) | ||
135 | { | ||
136 | struct resource *res; | ||
137 | |||
138 | if (pdev->id >= MAX_PORTS) { | ||
139 | dev_err(&pdev->dev, "invalid gpio port %d\n", | ||
140 | pdev->id); | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
144 | if (!res) { | ||
145 | dev_err(&pdev->dev, "failed to get memory for gpio port %d\n", | ||
146 | pdev->id); | ||
147 | return -ENOENT; | ||
148 | } | ||
149 | res = devm_request_mem_region(&pdev->dev, res->start, | ||
150 | resource_size(res), dev_name(&pdev->dev)); | ||
151 | if (!res) { | ||
152 | dev_err(&pdev->dev, | ||
153 | "failed to request memory for gpio port %d\n", | ||
154 | pdev->id); | ||
155 | return -EBUSY; | ||
156 | } | ||
157 | ltq_gpio_port[pdev->id].membase = devm_ioremap_nocache(&pdev->dev, | ||
158 | res->start, resource_size(res)); | ||
159 | if (!ltq_gpio_port[pdev->id].membase) { | ||
160 | dev_err(&pdev->dev, "failed to remap memory for gpio port %d\n", | ||
161 | pdev->id); | ||
162 | return -ENOMEM; | ||
163 | } | ||
164 | ltq_gpio_port[pdev->id].chip.label = "ltq_gpio"; | ||
165 | ltq_gpio_port[pdev->id].chip.direction_input = ltq_gpio_direction_input; | ||
166 | ltq_gpio_port[pdev->id].chip.direction_output = | ||
167 | ltq_gpio_direction_output; | ||
168 | ltq_gpio_port[pdev->id].chip.get = ltq_gpio_get; | ||
169 | ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set; | ||
170 | ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req; | ||
171 | ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id; | ||
172 | ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT; | ||
173 | platform_set_drvdata(pdev, <q_gpio_port[pdev->id]); | ||
174 | return gpiochip_add(<q_gpio_port[pdev->id].chip); | ||
175 | } | ||
176 | |||
177 | static struct platform_driver | ||
178 | ltq_gpio_driver = { | ||
179 | .probe = ltq_gpio_probe, | ||
180 | .driver = { | ||
181 | .name = "ltq_gpio", | ||
182 | .owner = THIS_MODULE, | ||
183 | }, | ||
184 | }; | ||
185 | |||
186 | int __init ltq_gpio_init(void) | ||
187 | { | ||
188 | int ret = platform_driver_register(<q_gpio_driver); | ||
189 | |||
190 | if (ret) | ||
191 | pr_info("ltq_gpio : Error registering platfom driver!"); | ||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | postcore_initcall(ltq_gpio_init); | ||
diff --git a/arch/mips/lantiq/xway/gpio_ebu.c b/arch/mips/lantiq/xway/gpio_ebu.c new file mode 100644 index 000000000000..a479355abdb9 --- /dev/null +++ b/arch/mips/lantiq/xway/gpio_ebu.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/mutex.h> | ||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/io.h> | ||
16 | |||
17 | #include <lantiq_soc.h> | ||
18 | |||
19 | /* | ||
20 | * By attaching hardware latches to the EBU it is possible to create output | ||
21 | * only gpios. This driver configures a special memory address, which when | ||
22 | * written to outputs 16 bit to the latches. | ||
23 | */ | ||
24 | |||
25 | #define LTQ_EBU_BUSCON 0x1e7ff /* 16 bit access, slowest timing */ | ||
26 | #define LTQ_EBU_WP 0x80000000 /* write protect bit */ | ||
27 | |||
28 | /* we keep a shadow value of the last value written to the ebu */ | ||
29 | static int ltq_ebu_gpio_shadow = 0x0; | ||
30 | static void __iomem *ltq_ebu_gpio_membase; | ||
31 | |||
32 | static void ltq_ebu_apply(void) | ||
33 | { | ||
34 | unsigned long flags; | ||
35 | |||
36 | spin_lock_irqsave(&ebu_lock, flags); | ||
37 | ltq_ebu_w32(LTQ_EBU_BUSCON, LTQ_EBU_BUSCON1); | ||
38 | *((__u16 *)ltq_ebu_gpio_membase) = ltq_ebu_gpio_shadow; | ||
39 | ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1); | ||
40 | spin_unlock_irqrestore(&ebu_lock, flags); | ||
41 | } | ||
42 | |||
43 | static void ltq_ebu_set(struct gpio_chip *chip, unsigned offset, int value) | ||
44 | { | ||
45 | if (value) | ||
46 | ltq_ebu_gpio_shadow |= (1 << offset); | ||
47 | else | ||
48 | ltq_ebu_gpio_shadow &= ~(1 << offset); | ||
49 | ltq_ebu_apply(); | ||
50 | } | ||
51 | |||
52 | static int ltq_ebu_direction_output(struct gpio_chip *chip, unsigned offset, | ||
53 | int value) | ||
54 | { | ||
55 | ltq_ebu_set(chip, offset, value); | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static struct gpio_chip ltq_ebu_chip = { | ||
61 | .label = "ltq_ebu", | ||
62 | .direction_output = ltq_ebu_direction_output, | ||
63 | .set = ltq_ebu_set, | ||
64 | .base = 72, | ||
65 | .ngpio = 16, | ||
66 | .can_sleep = 1, | ||
67 | .owner = THIS_MODULE, | ||
68 | }; | ||
69 | |||
70 | static int ltq_ebu_probe(struct platform_device *pdev) | ||
71 | { | ||
72 | int ret = 0; | ||
73 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
74 | |||
75 | if (!res) { | ||
76 | dev_err(&pdev->dev, "failed to get memory resource\n"); | ||
77 | return -ENOENT; | ||
78 | } | ||
79 | |||
80 | res = devm_request_mem_region(&pdev->dev, res->start, | ||
81 | resource_size(res), dev_name(&pdev->dev)); | ||
82 | if (!res) { | ||
83 | dev_err(&pdev->dev, "failed to request memory resource\n"); | ||
84 | return -EBUSY; | ||
85 | } | ||
86 | |||
87 | ltq_ebu_gpio_membase = devm_ioremap_nocache(&pdev->dev, res->start, | ||
88 | resource_size(res)); | ||
89 | if (!ltq_ebu_gpio_membase) { | ||
90 | dev_err(&pdev->dev, "Failed to ioremap mem region\n"); | ||
91 | return -ENOMEM; | ||
92 | } | ||
93 | |||
94 | /* grab the default shadow value passed form the platform code */ | ||
95 | ltq_ebu_gpio_shadow = (unsigned int) pdev->dev.platform_data; | ||
96 | |||
97 | /* tell the ebu controller which memory address we will be using */ | ||
98 | ltq_ebu_w32(pdev->resource->start | 0x1, LTQ_EBU_ADDRSEL1); | ||
99 | |||
100 | /* write protect the region */ | ||
101 | ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1); | ||
102 | |||
103 | ret = gpiochip_add(<q_ebu_chip); | ||
104 | if (!ret) | ||
105 | ltq_ebu_apply(); | ||
106 | return ret; | ||
107 | } | ||
108 | |||
109 | static struct platform_driver ltq_ebu_driver = { | ||
110 | .probe = ltq_ebu_probe, | ||
111 | .driver = { | ||
112 | .name = "ltq_ebu", | ||
113 | .owner = THIS_MODULE, | ||
114 | }, | ||
115 | }; | ||
116 | |||
117 | static int __init ltq_ebu_init(void) | ||
118 | { | ||
119 | int ret = platform_driver_register(<q_ebu_driver); | ||
120 | |||
121 | if (ret) | ||
122 | pr_info("ltq_ebu : Error registering platfom driver!"); | ||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | postcore_initcall(ltq_ebu_init); | ||
diff --git a/arch/mips/lantiq/xway/gpio_stp.c b/arch/mips/lantiq/xway/gpio_stp.c new file mode 100644 index 000000000000..67d59d690340 --- /dev/null +++ b/arch/mips/lantiq/xway/gpio_stp.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2007 John Crispin <blogic@openwrt.org> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/slab.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/mutex.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/gpio.h> | ||
18 | |||
19 | #include <lantiq_soc.h> | ||
20 | |||
21 | #define LTQ_STP_CON0 0x00 | ||
22 | #define LTQ_STP_CON1 0x04 | ||
23 | #define LTQ_STP_CPU0 0x08 | ||
24 | #define LTQ_STP_CPU1 0x0C | ||
25 | #define LTQ_STP_AR 0x10 | ||
26 | |||
27 | #define LTQ_STP_CON_SWU (1 << 31) | ||
28 | #define LTQ_STP_2HZ 0 | ||
29 | #define LTQ_STP_4HZ (1 << 23) | ||
30 | #define LTQ_STP_8HZ (2 << 23) | ||
31 | #define LTQ_STP_10HZ (3 << 23) | ||
32 | #define LTQ_STP_SPEED_MASK (0xf << 23) | ||
33 | #define LTQ_STP_UPD_FPI (1 << 31) | ||
34 | #define LTQ_STP_UPD_MASK (3 << 30) | ||
35 | #define LTQ_STP_ADSL_SRC (3 << 24) | ||
36 | |||
37 | #define LTQ_STP_GROUP0 (1 << 0) | ||
38 | |||
39 | #define LTQ_STP_RISING 0 | ||
40 | #define LTQ_STP_FALLING (1 << 26) | ||
41 | #define LTQ_STP_EDGE_MASK (1 << 26) | ||
42 | |||
43 | #define ltq_stp_r32(reg) __raw_readl(ltq_stp_membase + reg) | ||
44 | #define ltq_stp_w32(val, reg) __raw_writel(val, ltq_stp_membase + reg) | ||
45 | #define ltq_stp_w32_mask(clear, set, reg) \ | ||
46 | ltq_w32((ltq_r32(ltq_stp_membase + reg) & ~(clear)) | (set), \ | ||
47 | ltq_stp_membase + (reg)) | ||
48 | |||
49 | static int ltq_stp_shadow = 0xffff; | ||
50 | static void __iomem *ltq_stp_membase; | ||
51 | |||
52 | static void ltq_stp_set(struct gpio_chip *chip, unsigned offset, int value) | ||
53 | { | ||
54 | if (value) | ||
55 | ltq_stp_shadow |= (1 << offset); | ||
56 | else | ||
57 | ltq_stp_shadow &= ~(1 << offset); | ||
58 | ltq_stp_w32(ltq_stp_shadow, LTQ_STP_CPU0); | ||
59 | } | ||
60 | |||
61 | static int ltq_stp_direction_output(struct gpio_chip *chip, unsigned offset, | ||
62 | int value) | ||
63 | { | ||
64 | ltq_stp_set(chip, offset, value); | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static struct gpio_chip ltq_stp_chip = { | ||
70 | .label = "ltq_stp", | ||
71 | .direction_output = ltq_stp_direction_output, | ||
72 | .set = ltq_stp_set, | ||
73 | .base = 48, | ||
74 | .ngpio = 24, | ||
75 | .can_sleep = 1, | ||
76 | .owner = THIS_MODULE, | ||
77 | }; | ||
78 | |||
79 | static int ltq_stp_hw_init(void) | ||
80 | { | ||
81 | /* the 3 pins used to control the external stp */ | ||
82 | ltq_gpio_request(4, 1, 0, 1, "stp-st"); | ||
83 | ltq_gpio_request(5, 1, 0, 1, "stp-d"); | ||
84 | ltq_gpio_request(6, 1, 0, 1, "stp-sh"); | ||
85 | |||
86 | /* sane defaults */ | ||
87 | ltq_stp_w32(0, LTQ_STP_AR); | ||
88 | ltq_stp_w32(0, LTQ_STP_CPU0); | ||
89 | ltq_stp_w32(0, LTQ_STP_CPU1); | ||
90 | ltq_stp_w32(LTQ_STP_CON_SWU, LTQ_STP_CON0); | ||
91 | ltq_stp_w32(0, LTQ_STP_CON1); | ||
92 | |||
93 | /* rising or falling edge */ | ||
94 | ltq_stp_w32_mask(LTQ_STP_EDGE_MASK, LTQ_STP_FALLING, LTQ_STP_CON0); | ||
95 | |||
96 | /* per default stp 15-0 are set */ | ||
97 | ltq_stp_w32_mask(0, LTQ_STP_GROUP0, LTQ_STP_CON1); | ||
98 | |||
99 | /* stp are update periodically by the FPI bus */ | ||
100 | ltq_stp_w32_mask(LTQ_STP_UPD_MASK, LTQ_STP_UPD_FPI, LTQ_STP_CON1); | ||
101 | |||
102 | /* set stp update speed */ | ||
103 | ltq_stp_w32_mask(LTQ_STP_SPEED_MASK, LTQ_STP_8HZ, LTQ_STP_CON1); | ||
104 | |||
105 | /* tell the hardware that pin (led) 0 and 1 are controlled | ||
106 | * by the dsl arc | ||
107 | */ | ||
108 | ltq_stp_w32_mask(0, LTQ_STP_ADSL_SRC, LTQ_STP_CON0); | ||
109 | |||
110 | ltq_pmu_enable(PMU_LED); | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int __devinit ltq_stp_probe(struct platform_device *pdev) | ||
115 | { | ||
116 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
117 | int ret = 0; | ||
118 | |||
119 | if (!res) | ||
120 | return -ENOENT; | ||
121 | res = devm_request_mem_region(&pdev->dev, res->start, | ||
122 | resource_size(res), dev_name(&pdev->dev)); | ||
123 | if (!res) { | ||
124 | dev_err(&pdev->dev, "failed to request STP memory\n"); | ||
125 | return -EBUSY; | ||
126 | } | ||
127 | ltq_stp_membase = devm_ioremap_nocache(&pdev->dev, res->start, | ||
128 | resource_size(res)); | ||
129 | if (!ltq_stp_membase) { | ||
130 | dev_err(&pdev->dev, "failed to remap STP memory\n"); | ||
131 | return -ENOMEM; | ||
132 | } | ||
133 | ret = gpiochip_add(<q_stp_chip); | ||
134 | if (!ret) | ||
135 | ret = ltq_stp_hw_init(); | ||
136 | |||
137 | return ret; | ||
138 | } | ||
139 | |||
140 | static struct platform_driver ltq_stp_driver = { | ||
141 | .probe = ltq_stp_probe, | ||
142 | .driver = { | ||
143 | .name = "ltq_stp", | ||
144 | .owner = THIS_MODULE, | ||
145 | }, | ||
146 | }; | ||
147 | |||
148 | int __init ltq_stp_init(void) | ||
149 | { | ||
150 | int ret = platform_driver_register(<q_stp_driver); | ||
151 | |||
152 | if (ret) | ||
153 | pr_info("ltq_stp: error registering platfom driver"); | ||
154 | return ret; | ||
155 | } | ||
156 | |||
157 | postcore_initcall(ltq_stp_init); | ||
diff --git a/arch/mips/lantiq/xway/mach-easy50601.c b/arch/mips/lantiq/xway/mach-easy50601.c new file mode 100644 index 000000000000..d5aaf637ab19 --- /dev/null +++ b/arch/mips/lantiq/xway/mach-easy50601.c | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/platform_device.h> | ||
11 | #include <linux/mtd/mtd.h> | ||
12 | #include <linux/mtd/partitions.h> | ||
13 | #include <linux/mtd/physmap.h> | ||
14 | #include <linux/input.h> | ||
15 | |||
16 | #include <lantiq.h> | ||
17 | |||
18 | #include "../machtypes.h" | ||
19 | #include "devices.h" | ||
20 | |||
21 | static struct mtd_partition easy50601_partitions[] = { | ||
22 | { | ||
23 | .name = "uboot", | ||
24 | .offset = 0x0, | ||
25 | .size = 0x10000, | ||
26 | }, | ||
27 | { | ||
28 | .name = "uboot_env", | ||
29 | .offset = 0x10000, | ||
30 | .size = 0x10000, | ||
31 | }, | ||
32 | { | ||
33 | .name = "linux", | ||
34 | .offset = 0x20000, | ||
35 | .size = 0xE0000, | ||
36 | }, | ||
37 | { | ||
38 | .name = "rootfs", | ||
39 | .offset = 0x100000, | ||
40 | .size = 0x300000, | ||
41 | }, | ||
42 | }; | ||
43 | |||
44 | static struct physmap_flash_data easy50601_flash_data = { | ||
45 | .nr_parts = ARRAY_SIZE(easy50601_partitions), | ||
46 | .parts = easy50601_partitions, | ||
47 | }; | ||
48 | |||
49 | static void __init easy50601_init(void) | ||
50 | { | ||
51 | ltq_register_nor(&easy50601_flash_data); | ||
52 | } | ||
53 | |||
54 | MIPS_MACHINE(LTQ_MACH_EASY50601, | ||
55 | "EASY50601", | ||
56 | "EASY50601 Eval Board", | ||
57 | easy50601_init); | ||
diff --git a/arch/mips/lantiq/xway/mach-easy50712.c b/arch/mips/lantiq/xway/mach-easy50712.c new file mode 100644 index 000000000000..ea5027b3239d --- /dev/null +++ b/arch/mips/lantiq/xway/mach-easy50712.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/platform_device.h> | ||
11 | #include <linux/mtd/mtd.h> | ||
12 | #include <linux/mtd/partitions.h> | ||
13 | #include <linux/mtd/physmap.h> | ||
14 | #include <linux/input.h> | ||
15 | #include <linux/phy.h> | ||
16 | |||
17 | #include <lantiq_soc.h> | ||
18 | #include <irq.h> | ||
19 | |||
20 | #include "../machtypes.h" | ||
21 | #include "devices.h" | ||
22 | |||
23 | static struct mtd_partition easy50712_partitions[] = { | ||
24 | { | ||
25 | .name = "uboot", | ||
26 | .offset = 0x0, | ||
27 | .size = 0x10000, | ||
28 | }, | ||
29 | { | ||
30 | .name = "uboot_env", | ||
31 | .offset = 0x10000, | ||
32 | .size = 0x10000, | ||
33 | }, | ||
34 | { | ||
35 | .name = "linux", | ||
36 | .offset = 0x20000, | ||
37 | .size = 0xe0000, | ||
38 | }, | ||
39 | { | ||
40 | .name = "rootfs", | ||
41 | .offset = 0x100000, | ||
42 | .size = 0x300000, | ||
43 | }, | ||
44 | }; | ||
45 | |||
46 | static struct physmap_flash_data easy50712_flash_data = { | ||
47 | .nr_parts = ARRAY_SIZE(easy50712_partitions), | ||
48 | .parts = easy50712_partitions, | ||
49 | }; | ||
50 | |||
51 | static struct ltq_pci_data ltq_pci_data = { | ||
52 | .clock = PCI_CLOCK_INT, | ||
53 | .gpio = PCI_GNT1 | PCI_REQ1, | ||
54 | .irq = { | ||
55 | [14] = INT_NUM_IM0_IRL0 + 22, | ||
56 | }, | ||
57 | }; | ||
58 | |||
59 | static struct ltq_eth_data ltq_eth_data = { | ||
60 | .mii_mode = PHY_INTERFACE_MODE_MII, | ||
61 | }; | ||
62 | |||
63 | static void __init easy50712_init(void) | ||
64 | { | ||
65 | ltq_register_gpio_stp(); | ||
66 | ltq_register_nor(&easy50712_flash_data); | ||
67 | ltq_register_pci(<q_pci_data); | ||
68 | ltq_register_etop(<q_eth_data); | ||
69 | } | ||
70 | |||
71 | MIPS_MACHINE(LTQ_MACH_EASY50712, | ||
72 | "EASY50712", | ||
73 | "EASY50712 Eval Board", | ||
74 | easy50712_init); | ||
diff --git a/arch/mips/lantiq/xway/pmu.c b/arch/mips/lantiq/xway/pmu.c new file mode 100644 index 000000000000..9d69f01e352b --- /dev/null +++ b/arch/mips/lantiq/xway/pmu.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/version.h> | ||
12 | #include <linux/ioport.h> | ||
13 | |||
14 | #include <lantiq_soc.h> | ||
15 | |||
16 | /* PMU - the power management unit allows us to turn part of the core | ||
17 | * on and off | ||
18 | */ | ||
19 | |||
20 | /* the enable / disable registers */ | ||
21 | #define LTQ_PMU_PWDCR 0x1C | ||
22 | #define LTQ_PMU_PWDSR 0x20 | ||
23 | |||
24 | #define ltq_pmu_w32(x, y) ltq_w32((x), ltq_pmu_membase + (y)) | ||
25 | #define ltq_pmu_r32(x) ltq_r32(ltq_pmu_membase + (x)) | ||
26 | |||
27 | static struct resource ltq_pmu_resource = { | ||
28 | .name = "pmu", | ||
29 | .start = LTQ_PMU_BASE_ADDR, | ||
30 | .end = LTQ_PMU_BASE_ADDR + LTQ_PMU_SIZE - 1, | ||
31 | .flags = IORESOURCE_MEM, | ||
32 | }; | ||
33 | |||
34 | static void __iomem *ltq_pmu_membase; | ||
35 | |||
36 | void ltq_pmu_enable(unsigned int module) | ||
37 | { | ||
38 | int err = 1000000; | ||
39 | |||
40 | ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR); | ||
41 | do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module)); | ||
42 | |||
43 | if (!err) | ||
44 | panic("activating PMU module failed!\n"); | ||
45 | } | ||
46 | EXPORT_SYMBOL(ltq_pmu_enable); | ||
47 | |||
48 | void ltq_pmu_disable(unsigned int module) | ||
49 | { | ||
50 | ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR); | ||
51 | } | ||
52 | EXPORT_SYMBOL(ltq_pmu_disable); | ||
53 | |||
54 | int __init ltq_pmu_init(void) | ||
55 | { | ||
56 | if (insert_resource(&iomem_resource, <q_pmu_resource) < 0) | ||
57 | panic("Failed to insert pmu memory\n"); | ||
58 | |||
59 | if (request_mem_region(ltq_pmu_resource.start, | ||
60 | resource_size(<q_pmu_resource), "pmu") < 0) | ||
61 | panic("Failed to request pmu memory\n"); | ||
62 | |||
63 | ltq_pmu_membase = ioremap_nocache(ltq_pmu_resource.start, | ||
64 | resource_size(<q_pmu_resource)); | ||
65 | if (!ltq_pmu_membase) | ||
66 | panic("Failed to remap pmu memory\n"); | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | core_initcall(ltq_pmu_init); | ||
diff --git a/arch/mips/lantiq/xway/prom-ase.c b/arch/mips/lantiq/xway/prom-ase.c new file mode 100644 index 000000000000..abe49f4db57f --- /dev/null +++ b/arch/mips/lantiq/xway/prom-ase.c | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/clk.h> | ||
11 | #include <asm/bootinfo.h> | ||
12 | #include <asm/time.h> | ||
13 | |||
14 | #include <lantiq_soc.h> | ||
15 | |||
16 | #include "../prom.h" | ||
17 | |||
18 | #define SOC_AMAZON_SE "Amazon_SE" | ||
19 | |||
20 | #define PART_SHIFT 12 | ||
21 | #define PART_MASK 0x0FFFFFFF | ||
22 | #define REV_SHIFT 28 | ||
23 | #define REV_MASK 0xF0000000 | ||
24 | |||
25 | void __init ltq_soc_detect(struct ltq_soc_info *i) | ||
26 | { | ||
27 | i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT; | ||
28 | i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT; | ||
29 | switch (i->partnum) { | ||
30 | case SOC_ID_AMAZON_SE: | ||
31 | i->name = SOC_AMAZON_SE; | ||
32 | i->type = SOC_TYPE_AMAZON_SE; | ||
33 | break; | ||
34 | |||
35 | default: | ||
36 | unreachable(); | ||
37 | break; | ||
38 | } | ||
39 | } | ||
diff --git a/arch/mips/lantiq/xway/prom-xway.c b/arch/mips/lantiq/xway/prom-xway.c new file mode 100644 index 000000000000..1686692ac24d --- /dev/null +++ b/arch/mips/lantiq/xway/prom-xway.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/clk.h> | ||
11 | #include <asm/bootinfo.h> | ||
12 | #include <asm/time.h> | ||
13 | |||
14 | #include <lantiq_soc.h> | ||
15 | |||
16 | #include "../prom.h" | ||
17 | |||
18 | #define SOC_DANUBE "Danube" | ||
19 | #define SOC_TWINPASS "Twinpass" | ||
20 | #define SOC_AR9 "AR9" | ||
21 | |||
22 | #define PART_SHIFT 12 | ||
23 | #define PART_MASK 0x0FFFFFFF | ||
24 | #define REV_SHIFT 28 | ||
25 | #define REV_MASK 0xF0000000 | ||
26 | |||
27 | void __init ltq_soc_detect(struct ltq_soc_info *i) | ||
28 | { | ||
29 | i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT; | ||
30 | i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT; | ||
31 | switch (i->partnum) { | ||
32 | case SOC_ID_DANUBE1: | ||
33 | case SOC_ID_DANUBE2: | ||
34 | i->name = SOC_DANUBE; | ||
35 | i->type = SOC_TYPE_DANUBE; | ||
36 | break; | ||
37 | |||
38 | case SOC_ID_TWINPASS: | ||
39 | i->name = SOC_TWINPASS; | ||
40 | i->type = SOC_TYPE_DANUBE; | ||
41 | break; | ||
42 | |||
43 | case SOC_ID_ARX188: | ||
44 | case SOC_ID_ARX168: | ||
45 | case SOC_ID_ARX182: | ||
46 | i->name = SOC_AR9; | ||
47 | i->type = SOC_TYPE_AR9; | ||
48 | break; | ||
49 | |||
50 | default: | ||
51 | unreachable(); | ||
52 | break; | ||
53 | } | ||
54 | } | ||
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c new file mode 100644 index 000000000000..a1be36d0e490 --- /dev/null +++ b/arch/mips/lantiq/xway/reset.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/io.h> | ||
11 | #include <linux/ioport.h> | ||
12 | #include <linux/pm.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <asm/reboot.h> | ||
15 | |||
16 | #include <lantiq_soc.h> | ||
17 | |||
18 | #define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y)) | ||
19 | #define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x)) | ||
20 | |||
21 | /* register definitions */ | ||
22 | #define LTQ_RCU_RST 0x0010 | ||
23 | #define LTQ_RCU_RST_ALL 0x40000000 | ||
24 | |||
25 | #define LTQ_RCU_RST_STAT 0x0014 | ||
26 | #define LTQ_RCU_STAT_SHIFT 26 | ||
27 | |||
28 | static struct resource ltq_rcu_resource = { | ||
29 | .name = "rcu", | ||
30 | .start = LTQ_RCU_BASE_ADDR, | ||
31 | .end = LTQ_RCU_BASE_ADDR + LTQ_RCU_SIZE - 1, | ||
32 | .flags = IORESOURCE_MEM, | ||
33 | }; | ||
34 | |||
35 | /* remapped base addr of the reset control unit */ | ||
36 | static void __iomem *ltq_rcu_membase; | ||
37 | |||
38 | /* This function is used by the watchdog driver */ | ||
39 | int ltq_reset_cause(void) | ||
40 | { | ||
41 | u32 val = ltq_rcu_r32(LTQ_RCU_RST_STAT); | ||
42 | return val >> LTQ_RCU_STAT_SHIFT; | ||
43 | } | ||
44 | EXPORT_SYMBOL_GPL(ltq_reset_cause); | ||
45 | |||
46 | static void ltq_machine_restart(char *command) | ||
47 | { | ||
48 | pr_notice("System restart\n"); | ||
49 | local_irq_disable(); | ||
50 | ltq_rcu_w32(ltq_rcu_r32(LTQ_RCU_RST) | LTQ_RCU_RST_ALL, LTQ_RCU_RST); | ||
51 | unreachable(); | ||
52 | } | ||
53 | |||
54 | static void ltq_machine_halt(void) | ||
55 | { | ||
56 | pr_notice("System halted.\n"); | ||
57 | local_irq_disable(); | ||
58 | unreachable(); | ||
59 | } | ||
60 | |||
61 | static void ltq_machine_power_off(void) | ||
62 | { | ||
63 | pr_notice("Please turn off the power now.\n"); | ||
64 | local_irq_disable(); | ||
65 | unreachable(); | ||
66 | } | ||
67 | |||
68 | static int __init mips_reboot_setup(void) | ||
69 | { | ||
70 | /* insert and request the memory region */ | ||
71 | if (insert_resource(&iomem_resource, <q_rcu_resource) < 0) | ||
72 | panic("Failed to insert rcu memory\n"); | ||
73 | |||
74 | if (request_mem_region(ltq_rcu_resource.start, | ||
75 | resource_size(<q_rcu_resource), "rcu") < 0) | ||
76 | panic("Failed to request rcu memory\n"); | ||
77 | |||
78 | /* remap rcu register range */ | ||
79 | ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start, | ||
80 | resource_size(<q_rcu_resource)); | ||
81 | if (!ltq_rcu_membase) | ||
82 | panic("Failed to remap rcu memory\n"); | ||
83 | |||
84 | _machine_restart = ltq_machine_restart; | ||
85 | _machine_halt = ltq_machine_halt; | ||
86 | pm_power_off = ltq_machine_power_off; | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | arch_initcall(mips_reboot_setup); | ||
diff --git a/arch/mips/lantiq/xway/setup-ase.c b/arch/mips/lantiq/xway/setup-ase.c new file mode 100644 index 000000000000..f6f326798a39 --- /dev/null +++ b/arch/mips/lantiq/xway/setup-ase.c | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <lantiq_soc.h> | ||
10 | |||
11 | #include "../prom.h" | ||
12 | #include "devices.h" | ||
13 | |||
14 | void __init ltq_soc_setup(void) | ||
15 | { | ||
16 | ltq_register_ase_asc(); | ||
17 | ltq_register_gpio(); | ||
18 | ltq_register_wdt(); | ||
19 | } | ||
diff --git a/arch/mips/lantiq/xway/setup-xway.c b/arch/mips/lantiq/xway/setup-xway.c new file mode 100644 index 000000000000..c292f643a858 --- /dev/null +++ b/arch/mips/lantiq/xway/setup-xway.c | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <lantiq_soc.h> | ||
10 | |||
11 | #include "../prom.h" | ||
12 | #include "devices.h" | ||
13 | |||
14 | void __init ltq_soc_setup(void) | ||
15 | { | ||
16 | ltq_register_asc(0); | ||
17 | ltq_register_asc(1); | ||
18 | ltq_register_gpio(); | ||
19 | ltq_register_wdt(); | ||
20 | } | ||
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 2adead5a8a37..b2cad4fd5fc4 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile | |||
@@ -28,6 +28,7 @@ obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o | |||
28 | obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o | 28 | obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o |
29 | obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o | 29 | obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o |
30 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += dump_tlb.o | 30 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += dump_tlb.o |
31 | obj-$(CONFIG_CPU_XLR) += dump_tlb.o | ||
31 | 32 | ||
32 | # libgcc-style stuff needed in the kernel | 33 | # libgcc-style stuff needed in the kernel |
33 | obj-y += ashldi3.o ashrdi3.o cmpdi2.o lshrdi3.o ucmpdi2.o | 34 | obj-y += ashldi3.o ashrdi3.o cmpdi2.o lshrdi3.o ucmpdi2.o |
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index d679c772d082..4d8c1623eee2 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile | |||
@@ -3,7 +3,8 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += cache.o dma-default.o extable.o fault.o \ | 5 | obj-y += cache.o dma-default.o extable.o fault.o \ |
6 | init.o tlbex.o tlbex-fault.o uasm.o page.o | 6 | init.o mmap.o tlbex.o tlbex-fault.o uasm.o \ |
7 | page.o | ||
7 | 8 | ||
8 | obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o | 9 | obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o |
9 | obj-$(CONFIG_64BIT) += pgtable-64.o | 10 | obj-$(CONFIG_64BIT) += pgtable-64.o |
@@ -29,6 +30,7 @@ obj-$(CONFIG_CPU_TX39XX) += c-tx39.o tlb-r3k.o | |||
29 | obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o tlb-r4k.o | 30 | obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o tlb-r4k.o |
30 | obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o tlb-r4k.o | 31 | obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o tlb-r4k.o |
31 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += c-octeon.o cex-oct.o tlb-r4k.o | 32 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += c-octeon.o cex-oct.o tlb-r4k.o |
33 | obj-$(CONFIG_CPU_XLR) += c-r4k.o tlb-r4k.o cex-gen.o | ||
32 | 34 | ||
33 | obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o | 35 | obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o |
34 | obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o | 36 | obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 71bddf8f7d25..d9bc5d3593b6 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -1006,6 +1006,7 @@ static void __cpuinit probe_pcache(void) | |||
1006 | case CPU_25KF: | 1006 | case CPU_25KF: |
1007 | case CPU_SB1: | 1007 | case CPU_SB1: |
1008 | case CPU_SB1A: | 1008 | case CPU_SB1A: |
1009 | case CPU_XLR: | ||
1009 | c->dcache.flags |= MIPS_CACHE_PINDEX; | 1010 | c->dcache.flags |= MIPS_CACHE_PINDEX; |
1010 | break; | 1011 | break; |
1011 | 1012 | ||
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c new file mode 100644 index 000000000000..ae3c20a9556e --- /dev/null +++ b/arch/mips/mm/mmap.c | |||
@@ -0,0 +1,122 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2011 Wind River Systems, | ||
7 | * written by Ralf Baechle <ralf@linux-mips.org> | ||
8 | */ | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/mm.h> | ||
11 | #include <linux/mman.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/random.h> | ||
14 | #include <linux/sched.h> | ||
15 | |||
16 | unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ | ||
17 | |||
18 | EXPORT_SYMBOL(shm_align_mask); | ||
19 | |||
20 | #define COLOUR_ALIGN(addr,pgoff) \ | ||
21 | ((((addr) + shm_align_mask) & ~shm_align_mask) + \ | ||
22 | (((pgoff) << PAGE_SHIFT) & shm_align_mask)) | ||
23 | |||
24 | unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | ||
25 | unsigned long len, unsigned long pgoff, unsigned long flags) | ||
26 | { | ||
27 | struct vm_area_struct * vmm; | ||
28 | int do_color_align; | ||
29 | |||
30 | if (len > TASK_SIZE) | ||
31 | return -ENOMEM; | ||
32 | |||
33 | if (flags & MAP_FIXED) { | ||
34 | /* Even MAP_FIXED mappings must reside within TASK_SIZE. */ | ||
35 | if (TASK_SIZE - len < addr) | ||
36 | return -EINVAL; | ||
37 | |||
38 | /* | ||
39 | * We do not accept a shared mapping if it would violate | ||
40 | * cache aliasing constraints. | ||
41 | */ | ||
42 | if ((flags & MAP_SHARED) && | ||
43 | ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask)) | ||
44 | return -EINVAL; | ||
45 | return addr; | ||
46 | } | ||
47 | |||
48 | do_color_align = 0; | ||
49 | if (filp || (flags & MAP_SHARED)) | ||
50 | do_color_align = 1; | ||
51 | if (addr) { | ||
52 | if (do_color_align) | ||
53 | addr = COLOUR_ALIGN(addr, pgoff); | ||
54 | else | ||
55 | addr = PAGE_ALIGN(addr); | ||
56 | vmm = find_vma(current->mm, addr); | ||
57 | if (TASK_SIZE - len >= addr && | ||
58 | (!vmm || addr + len <= vmm->vm_start)) | ||
59 | return addr; | ||
60 | } | ||
61 | addr = current->mm->mmap_base; | ||
62 | if (do_color_align) | ||
63 | addr = COLOUR_ALIGN(addr, pgoff); | ||
64 | else | ||
65 | addr = PAGE_ALIGN(addr); | ||
66 | |||
67 | for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { | ||
68 | /* At this point: (!vmm || addr < vmm->vm_end). */ | ||
69 | if (TASK_SIZE - len < addr) | ||
70 | return -ENOMEM; | ||
71 | if (!vmm || addr + len <= vmm->vm_start) | ||
72 | return addr; | ||
73 | addr = vmm->vm_end; | ||
74 | if (do_color_align) | ||
75 | addr = COLOUR_ALIGN(addr, pgoff); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | void arch_pick_mmap_layout(struct mm_struct *mm) | ||
80 | { | ||
81 | unsigned long random_factor = 0UL; | ||
82 | |||
83 | if (current->flags & PF_RANDOMIZE) { | ||
84 | random_factor = get_random_int(); | ||
85 | random_factor = random_factor << PAGE_SHIFT; | ||
86 | if (TASK_IS_32BIT_ADDR) | ||
87 | random_factor &= 0xfffffful; | ||
88 | else | ||
89 | random_factor &= 0xffffffful; | ||
90 | } | ||
91 | |||
92 | mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; | ||
93 | mm->get_unmapped_area = arch_get_unmapped_area; | ||
94 | mm->unmap_area = arch_unmap_area; | ||
95 | } | ||
96 | |||
97 | static inline unsigned long brk_rnd(void) | ||
98 | { | ||
99 | unsigned long rnd = get_random_int(); | ||
100 | |||
101 | rnd = rnd << PAGE_SHIFT; | ||
102 | /* 8MB for 32bit, 256MB for 64bit */ | ||
103 | if (TASK_IS_32BIT_ADDR) | ||
104 | rnd = rnd & 0x7ffffful; | ||
105 | else | ||
106 | rnd = rnd & 0xffffffful; | ||
107 | |||
108 | return rnd; | ||
109 | } | ||
110 | |||
111 | unsigned long arch_randomize_brk(struct mm_struct *mm) | ||
112 | { | ||
113 | unsigned long base = mm->brk; | ||
114 | unsigned long ret; | ||
115 | |||
116 | ret = PAGE_ALIGN(base + brk_rnd()); | ||
117 | |||
118 | if (ret < mm->brk) | ||
119 | return mm->brk; | ||
120 | |||
121 | return ret; | ||
122 | } | ||
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index f5734c2c8097..424ed4b92e6d 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -404,6 +404,7 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l, | |||
404 | case CPU_5KC: | 404 | case CPU_5KC: |
405 | case CPU_TX49XX: | 405 | case CPU_TX49XX: |
406 | case CPU_PR4450: | 406 | case CPU_PR4450: |
407 | case CPU_XLR: | ||
407 | uasm_i_nop(p); | 408 | uasm_i_nop(p); |
408 | tlbw(p); | 409 | tlbw(p); |
409 | break; | 410 | break; |
diff --git a/arch/mips/netlogic/Kconfig b/arch/mips/netlogic/Kconfig new file mode 100644 index 000000000000..a5ca743613f2 --- /dev/null +++ b/arch/mips/netlogic/Kconfig | |||
@@ -0,0 +1,5 @@ | |||
1 | config NLM_COMMON | ||
2 | bool | ||
3 | |||
4 | config NLM_XLR | ||
5 | bool | ||
diff --git a/arch/mips/netlogic/xlr/Makefile b/arch/mips/netlogic/xlr/Makefile new file mode 100644 index 000000000000..9bd3f731f62e --- /dev/null +++ b/arch/mips/netlogic/xlr/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | obj-y += setup.o platform.o irq.o setup.o time.o | ||
2 | obj-$(CONFIG_SMP) += smp.o smpboot.o | ||
3 | obj-$(CONFIG_EARLY_PRINTK) += xlr_console.o | ||
4 | |||
5 | EXTRA_CFLAGS += -Werror | ||
diff --git a/arch/mips/netlogic/xlr/irq.c b/arch/mips/netlogic/xlr/irq.c new file mode 100644 index 000000000000..1446d58e364c --- /dev/null +++ b/arch/mips/netlogic/xlr/irq.c | |||
@@ -0,0 +1,300 @@ | |||
1 | /* | ||
2 | * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the NetLogic | ||
9 | * license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in | ||
19 | * the documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR | ||
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/init.h> | ||
37 | #include <linux/linkage.h> | ||
38 | #include <linux/interrupt.h> | ||
39 | #include <linux/spinlock.h> | ||
40 | #include <linux/mm.h> | ||
41 | |||
42 | #include <asm/mipsregs.h> | ||
43 | |||
44 | #include <asm/netlogic/xlr/iomap.h> | ||
45 | #include <asm/netlogic/xlr/pic.h> | ||
46 | #include <asm/netlogic/xlr/xlr.h> | ||
47 | |||
48 | #include <asm/netlogic/interrupt.h> | ||
49 | #include <asm/netlogic/mips-extns.h> | ||
50 | |||
51 | static u64 nlm_irq_mask; | ||
52 | static DEFINE_SPINLOCK(nlm_pic_lock); | ||
53 | |||
54 | static void xlr_pic_enable(struct irq_data *d) | ||
55 | { | ||
56 | nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET); | ||
57 | unsigned long flags; | ||
58 | nlm_reg_t reg; | ||
59 | int irq = d->irq; | ||
60 | |||
61 | WARN(!PIC_IRQ_IS_IRT(irq), "Bad irq %d", irq); | ||
62 | |||
63 | spin_lock_irqsave(&nlm_pic_lock, flags); | ||
64 | reg = netlogic_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE); | ||
65 | netlogic_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE, | ||
66 | reg | (1 << 6) | (1 << 30) | (1 << 31)); | ||
67 | spin_unlock_irqrestore(&nlm_pic_lock, flags); | ||
68 | } | ||
69 | |||
70 | static void xlr_pic_mask(struct irq_data *d) | ||
71 | { | ||
72 | nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET); | ||
73 | unsigned long flags; | ||
74 | nlm_reg_t reg; | ||
75 | int irq = d->irq; | ||
76 | |||
77 | WARN(!PIC_IRQ_IS_IRT(irq), "Bad irq %d", irq); | ||
78 | |||
79 | spin_lock_irqsave(&nlm_pic_lock, flags); | ||
80 | reg = netlogic_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE); | ||
81 | netlogic_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE, | ||
82 | reg | (1 << 6) | (1 << 30) | (0 << 31)); | ||
83 | spin_unlock_irqrestore(&nlm_pic_lock, flags); | ||
84 | } | ||
85 | |||
86 | #ifdef CONFIG_PCI | ||
87 | /* Extra ACK needed for XLR on chip PCI controller */ | ||
88 | static void xlr_pci_ack(struct irq_data *d) | ||
89 | { | ||
90 | nlm_reg_t *pci_mmio = netlogic_io_mmio(NETLOGIC_IO_PCIX_OFFSET); | ||
91 | |||
92 | netlogic_read_reg(pci_mmio, (0x140 >> 2)); | ||
93 | } | ||
94 | |||
95 | /* Extra ACK needed for XLS on chip PCIe controller */ | ||
96 | static void xls_pcie_ack(struct irq_data *d) | ||
97 | { | ||
98 | nlm_reg_t *pcie_mmio_le = netlogic_io_mmio(NETLOGIC_IO_PCIE_1_OFFSET); | ||
99 | |||
100 | switch (d->irq) { | ||
101 | case PIC_PCIE_LINK0_IRQ: | ||
102 | netlogic_write_reg(pcie_mmio_le, (0x90 >> 2), 0xffffffff); | ||
103 | break; | ||
104 | case PIC_PCIE_LINK1_IRQ: | ||
105 | netlogic_write_reg(pcie_mmio_le, (0x94 >> 2), 0xffffffff); | ||
106 | break; | ||
107 | case PIC_PCIE_LINK2_IRQ: | ||
108 | netlogic_write_reg(pcie_mmio_le, (0x190 >> 2), 0xffffffff); | ||
109 | break; | ||
110 | case PIC_PCIE_LINK3_IRQ: | ||
111 | netlogic_write_reg(pcie_mmio_le, (0x194 >> 2), 0xffffffff); | ||
112 | break; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | /* For XLS B silicon, the 3,4 PCI interrupts are different */ | ||
117 | static void xls_pcie_ack_b(struct irq_data *d) | ||
118 | { | ||
119 | nlm_reg_t *pcie_mmio_le = netlogic_io_mmio(NETLOGIC_IO_PCIE_1_OFFSET); | ||
120 | |||
121 | switch (d->irq) { | ||
122 | case PIC_PCIE_LINK0_IRQ: | ||
123 | netlogic_write_reg(pcie_mmio_le, (0x90 >> 2), 0xffffffff); | ||
124 | break; | ||
125 | case PIC_PCIE_LINK1_IRQ: | ||
126 | netlogic_write_reg(pcie_mmio_le, (0x94 >> 2), 0xffffffff); | ||
127 | break; | ||
128 | case PIC_PCIE_XLSB0_LINK2_IRQ: | ||
129 | netlogic_write_reg(pcie_mmio_le, (0x190 >> 2), 0xffffffff); | ||
130 | break; | ||
131 | case PIC_PCIE_XLSB0_LINK3_IRQ: | ||
132 | netlogic_write_reg(pcie_mmio_le, (0x194 >> 2), 0xffffffff); | ||
133 | break; | ||
134 | } | ||
135 | } | ||
136 | #endif | ||
137 | |||
138 | static void xlr_pic_ack(struct irq_data *d) | ||
139 | { | ||
140 | unsigned long flags; | ||
141 | nlm_reg_t *mmio; | ||
142 | int irq = d->irq; | ||
143 | void *hd = irq_data_get_irq_handler_data(d); | ||
144 | |||
145 | WARN(!PIC_IRQ_IS_IRT(irq), "Bad irq %d", irq); | ||
146 | |||
147 | if (hd) { | ||
148 | void (*extra_ack)(void *) = hd; | ||
149 | extra_ack(d); | ||
150 | } | ||
151 | mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET); | ||
152 | spin_lock_irqsave(&nlm_pic_lock, flags); | ||
153 | netlogic_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE))); | ||
154 | spin_unlock_irqrestore(&nlm_pic_lock, flags); | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * This chip definition handles interrupts routed thru the XLR | ||
159 | * hardware PIC, currently IRQs 8-39 are mapped to hardware intr | ||
160 | * 0-31 wired the XLR PIC | ||
161 | */ | ||
162 | static struct irq_chip xlr_pic = { | ||
163 | .name = "XLR-PIC", | ||
164 | .irq_enable = xlr_pic_enable, | ||
165 | .irq_mask = xlr_pic_mask, | ||
166 | .irq_ack = xlr_pic_ack, | ||
167 | }; | ||
168 | |||
169 | static void rsvd_irq_handler(struct irq_data *d) | ||
170 | { | ||
171 | WARN(d->irq >= PIC_IRQ_BASE, "Bad irq %d", d->irq); | ||
172 | } | ||
173 | |||
174 | /* | ||
175 | * Chip definition for CPU originated interrupts(timer, msg) and | ||
176 | * IPIs | ||
177 | */ | ||
178 | struct irq_chip nlm_cpu_intr = { | ||
179 | .name = "XLR-CPU-INTR", | ||
180 | .irq_enable = rsvd_irq_handler, | ||
181 | .irq_mask = rsvd_irq_handler, | ||
182 | .irq_ack = rsvd_irq_handler, | ||
183 | }; | ||
184 | |||
185 | void __init init_xlr_irqs(void) | ||
186 | { | ||
187 | nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET); | ||
188 | uint32_t thread_mask = 1; | ||
189 | int level, i; | ||
190 | |||
191 | pr_info("Interrupt thread mask [%x]\n", thread_mask); | ||
192 | for (i = 0; i < PIC_NUM_IRTS; i++) { | ||
193 | level = PIC_IRQ_IS_EDGE_TRIGGERED(i); | ||
194 | |||
195 | /* Bind all PIC irqs to boot cpu */ | ||
196 | netlogic_write_reg(mmio, PIC_IRT_0_BASE + i, thread_mask); | ||
197 | |||
198 | /* | ||
199 | * Use local scheduling and high polarity for all IRTs | ||
200 | * Invalidate all IRTs, by default | ||
201 | */ | ||
202 | netlogic_write_reg(mmio, PIC_IRT_1_BASE + i, | ||
203 | (level << 30) | (1 << 6) | (PIC_IRQ_BASE + i)); | ||
204 | } | ||
205 | |||
206 | /* Make all IRQs as level triggered by default */ | ||
207 | for (i = 0; i < NR_IRQS; i++) { | ||
208 | if (PIC_IRQ_IS_IRT(i)) | ||
209 | irq_set_chip_and_handler(i, &xlr_pic, handle_level_irq); | ||
210 | else | ||
211 | irq_set_chip_and_handler(i, &nlm_cpu_intr, | ||
212 | handle_level_irq); | ||
213 | } | ||
214 | #ifdef CONFIG_SMP | ||
215 | irq_set_chip_and_handler(IRQ_IPI_SMP_FUNCTION, &nlm_cpu_intr, | ||
216 | nlm_smp_function_ipi_handler); | ||
217 | irq_set_chip_and_handler(IRQ_IPI_SMP_RESCHEDULE, &nlm_cpu_intr, | ||
218 | nlm_smp_resched_ipi_handler); | ||
219 | nlm_irq_mask |= | ||
220 | ((1ULL << IRQ_IPI_SMP_FUNCTION) | (1ULL << IRQ_IPI_SMP_RESCHEDULE)); | ||
221 | #endif | ||
222 | |||
223 | #ifdef CONFIG_PCI | ||
224 | /* | ||
225 | * For PCI interrupts, we need to ack the PIC controller too, overload | ||
226 | * irq handler data to do this | ||
227 | */ | ||
228 | if (nlm_chip_is_xls()) { | ||
229 | if (nlm_chip_is_xls_b()) { | ||
230 | irq_set_handler_data(PIC_PCIE_LINK0_IRQ, | ||
231 | xls_pcie_ack_b); | ||
232 | irq_set_handler_data(PIC_PCIE_LINK1_IRQ, | ||
233 | xls_pcie_ack_b); | ||
234 | irq_set_handler_data(PIC_PCIE_XLSB0_LINK2_IRQ, | ||
235 | xls_pcie_ack_b); | ||
236 | irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ, | ||
237 | xls_pcie_ack_b); | ||
238 | } else { | ||
239 | irq_set_handler_data(PIC_PCIE_LINK0_IRQ, xls_pcie_ack); | ||
240 | irq_set_handler_data(PIC_PCIE_LINK1_IRQ, xls_pcie_ack); | ||
241 | irq_set_handler_data(PIC_PCIE_LINK2_IRQ, xls_pcie_ack); | ||
242 | irq_set_handler_data(PIC_PCIE_LINK3_IRQ, xls_pcie_ack); | ||
243 | } | ||
244 | } else { | ||
245 | /* XLR PCI controller ACK */ | ||
246 | irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ, xlr_pci_ack); | ||
247 | } | ||
248 | #endif | ||
249 | /* unmask all PIC related interrupts. If no handler is installed by the | ||
250 | * drivers, it'll just ack the interrupt and return | ||
251 | */ | ||
252 | for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ; i++) | ||
253 | nlm_irq_mask |= (1ULL << i); | ||
254 | |||
255 | nlm_irq_mask |= (1ULL << IRQ_TIMER); | ||
256 | } | ||
257 | |||
258 | void __init arch_init_irq(void) | ||
259 | { | ||
260 | /* Initialize the irq descriptors */ | ||
261 | init_xlr_irqs(); | ||
262 | write_c0_eimr(nlm_irq_mask); | ||
263 | } | ||
264 | |||
265 | void __cpuinit nlm_smp_irq_init(void) | ||
266 | { | ||
267 | /* set interrupt mask for non-zero cpus */ | ||
268 | write_c0_eimr(nlm_irq_mask); | ||
269 | } | ||
270 | |||
271 | asmlinkage void plat_irq_dispatch(void) | ||
272 | { | ||
273 | uint64_t eirr; | ||
274 | int i; | ||
275 | |||
276 | eirr = read_c0_eirr() & read_c0_eimr(); | ||
277 | if (!eirr) | ||
278 | return; | ||
279 | |||
280 | /* no need of EIRR here, writing compare clears interrupt */ | ||
281 | if (eirr & (1 << IRQ_TIMER)) { | ||
282 | do_IRQ(IRQ_TIMER); | ||
283 | return; | ||
284 | } | ||
285 | |||
286 | /* use dcltz: optimize below code */ | ||
287 | for (i = 63; i != -1; i--) { | ||
288 | if (eirr & (1ULL << i)) | ||
289 | break; | ||
290 | } | ||
291 | if (i == -1) { | ||
292 | pr_err("no interrupt !!\n"); | ||
293 | return; | ||
294 | } | ||
295 | |||
296 | /* Ack eirr */ | ||
297 | write_c0_eirr(1ULL << i); | ||
298 | |||
299 | do_IRQ(i); | ||
300 | } | ||
diff --git a/arch/mips/netlogic/xlr/platform.c b/arch/mips/netlogic/xlr/platform.c new file mode 100644 index 000000000000..609ec2534642 --- /dev/null +++ b/arch/mips/netlogic/xlr/platform.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * Copyright 2011, Netlogic Microsystems. | ||
3 | * Copyright 2004, Matt Porter <mporter@kernel.crashing.org> | ||
4 | * | ||
5 | * This file is licensed under the terms of the GNU General Public | ||
6 | * License version 2. This program is licensed "as is" without any | ||
7 | * warranty of any kind, whether express or implied. | ||
8 | */ | ||
9 | |||
10 | #include <linux/device.h> | ||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/resource.h> | ||
15 | #include <linux/serial_8250.h> | ||
16 | #include <linux/serial_reg.h> | ||
17 | |||
18 | #include <asm/netlogic/xlr/iomap.h> | ||
19 | #include <asm/netlogic/xlr/pic.h> | ||
20 | #include <asm/netlogic/xlr/xlr.h> | ||
21 | |||
22 | unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset) | ||
23 | { | ||
24 | nlm_reg_t *mmio; | ||
25 | unsigned int value; | ||
26 | |||
27 | /* XLR uart does not need any mapping of regs */ | ||
28 | mmio = (nlm_reg_t *)(p->membase + (offset << p->regshift)); | ||
29 | value = netlogic_read_reg(mmio, 0); | ||
30 | |||
31 | /* See XLR/XLS errata */ | ||
32 | if (offset == UART_MSR) | ||
33 | value ^= 0xF0; | ||
34 | else if (offset == UART_MCR) | ||
35 | value ^= 0x3; | ||
36 | |||
37 | return value; | ||
38 | } | ||
39 | |||
40 | void nlm_xlr_uart_out(struct uart_port *p, int offset, int value) | ||
41 | { | ||
42 | nlm_reg_t *mmio; | ||
43 | |||
44 | /* XLR uart does not need any mapping of regs */ | ||
45 | mmio = (nlm_reg_t *)(p->membase + (offset << p->regshift)); | ||
46 | |||
47 | /* See XLR/XLS errata */ | ||
48 | if (offset == UART_MSR) | ||
49 | value ^= 0xF0; | ||
50 | else if (offset == UART_MCR) | ||
51 | value ^= 0x3; | ||
52 | |||
53 | netlogic_write_reg(mmio, 0, value); | ||
54 | } | ||
55 | |||
56 | #define PORT(_irq) \ | ||
57 | { \ | ||
58 | .irq = _irq, \ | ||
59 | .regshift = 2, \ | ||
60 | .iotype = UPIO_MEM32, \ | ||
61 | .flags = (UPF_SKIP_TEST | \ | ||
62 | UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\ | ||
63 | .uartclk = PIC_CLKS_PER_SEC, \ | ||
64 | .type = PORT_16550A, \ | ||
65 | .serial_in = nlm_xlr_uart_in, \ | ||
66 | .serial_out = nlm_xlr_uart_out, \ | ||
67 | } | ||
68 | |||
69 | static struct plat_serial8250_port xlr_uart_data[] = { | ||
70 | PORT(PIC_UART_0_IRQ), | ||
71 | PORT(PIC_UART_1_IRQ), | ||
72 | {}, | ||
73 | }; | ||
74 | |||
75 | static struct platform_device uart_device = { | ||
76 | .name = "serial8250", | ||
77 | .id = PLAT8250_DEV_PLATFORM, | ||
78 | .dev = { | ||
79 | .platform_data = xlr_uart_data, | ||
80 | }, | ||
81 | }; | ||
82 | |||
83 | static int __init nlm_uart_init(void) | ||
84 | { | ||
85 | nlm_reg_t *mmio; | ||
86 | |||
87 | mmio = netlogic_io_mmio(NETLOGIC_IO_UART_0_OFFSET); | ||
88 | xlr_uart_data[0].membase = (void __iomem *)mmio; | ||
89 | xlr_uart_data[0].mapbase = CPHYSADDR((unsigned long)mmio); | ||
90 | |||
91 | mmio = netlogic_io_mmio(NETLOGIC_IO_UART_1_OFFSET); | ||
92 | xlr_uart_data[1].membase = (void __iomem *)mmio; | ||
93 | xlr_uart_data[1].mapbase = CPHYSADDR((unsigned long)mmio); | ||
94 | |||
95 | return platform_device_register(&uart_device); | ||
96 | } | ||
97 | |||
98 | arch_initcall(nlm_uart_init); | ||
diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c new file mode 100644 index 000000000000..482802569e74 --- /dev/null +++ b/arch/mips/netlogic/xlr/setup.c | |||
@@ -0,0 +1,188 @@ | |||
1 | /* | ||
2 | * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the NetLogic | ||
9 | * license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in | ||
19 | * the documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR | ||
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/serial_8250.h> | ||
37 | #include <linux/pm.h> | ||
38 | |||
39 | #include <asm/reboot.h> | ||
40 | #include <asm/time.h> | ||
41 | #include <asm/bootinfo.h> | ||
42 | #include <asm/smp-ops.h> | ||
43 | |||
44 | #include <asm/netlogic/interrupt.h> | ||
45 | #include <asm/netlogic/psb-bootinfo.h> | ||
46 | |||
47 | #include <asm/netlogic/xlr/xlr.h> | ||
48 | #include <asm/netlogic/xlr/iomap.h> | ||
49 | #include <asm/netlogic/xlr/pic.h> | ||
50 | #include <asm/netlogic/xlr/gpio.h> | ||
51 | |||
52 | unsigned long netlogic_io_base = (unsigned long)(DEFAULT_NETLOGIC_IO_BASE); | ||
53 | unsigned long nlm_common_ebase = 0x0; | ||
54 | struct psb_info nlm_prom_info; | ||
55 | |||
56 | static void nlm_early_serial_setup(void) | ||
57 | { | ||
58 | struct uart_port s; | ||
59 | nlm_reg_t *uart_base; | ||
60 | |||
61 | uart_base = netlogic_io_mmio(NETLOGIC_IO_UART_0_OFFSET); | ||
62 | memset(&s, 0, sizeof(s)); | ||
63 | s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; | ||
64 | s.iotype = UPIO_MEM32; | ||
65 | s.regshift = 2; | ||
66 | s.irq = PIC_UART_0_IRQ; | ||
67 | s.uartclk = PIC_CLKS_PER_SEC; | ||
68 | s.serial_in = nlm_xlr_uart_in; | ||
69 | s.serial_out = nlm_xlr_uart_out; | ||
70 | s.mapbase = (unsigned long)uart_base; | ||
71 | s.membase = (unsigned char __iomem *)uart_base; | ||
72 | early_serial_setup(&s); | ||
73 | } | ||
74 | |||
75 | static void nlm_linux_exit(void) | ||
76 | { | ||
77 | nlm_reg_t *mmio; | ||
78 | |||
79 | mmio = netlogic_io_mmio(NETLOGIC_IO_GPIO_OFFSET); | ||
80 | /* trigger a chip reset by writing 1 to GPIO_SWRESET_REG */ | ||
81 | netlogic_write_reg(mmio, NETLOGIC_GPIO_SWRESET_REG, 1); | ||
82 | for ( ; ; ) | ||
83 | cpu_wait(); | ||
84 | } | ||
85 | |||
86 | void __init plat_mem_setup(void) | ||
87 | { | ||
88 | panic_timeout = 5; | ||
89 | _machine_restart = (void (*)(char *))nlm_linux_exit; | ||
90 | _machine_halt = nlm_linux_exit; | ||
91 | pm_power_off = nlm_linux_exit; | ||
92 | } | ||
93 | |||
94 | const char *get_system_type(void) | ||
95 | { | ||
96 | return "Netlogic XLR/XLS Series"; | ||
97 | } | ||
98 | |||
99 | void __init prom_free_prom_memory(void) | ||
100 | { | ||
101 | /* Nothing yet */ | ||
102 | } | ||
103 | |||
104 | static void build_arcs_cmdline(int *argv) | ||
105 | { | ||
106 | int i, remain, len; | ||
107 | char *arg; | ||
108 | |||
109 | remain = sizeof(arcs_cmdline) - 1; | ||
110 | arcs_cmdline[0] = '\0'; | ||
111 | for (i = 0; argv[i] != 0; i++) { | ||
112 | arg = (char *)(long)argv[i]; | ||
113 | len = strlen(arg); | ||
114 | if (len + 1 > remain) | ||
115 | break; | ||
116 | strcat(arcs_cmdline, arg); | ||
117 | strcat(arcs_cmdline, " "); | ||
118 | remain -= len + 1; | ||
119 | } | ||
120 | |||
121 | /* Add the default options here */ | ||
122 | if ((strstr(arcs_cmdline, "console=")) == NULL) { | ||
123 | arg = "console=ttyS0,38400 "; | ||
124 | len = strlen(arg); | ||
125 | if (len > remain) | ||
126 | goto fail; | ||
127 | strcat(arcs_cmdline, arg); | ||
128 | remain -= len; | ||
129 | } | ||
130 | #ifdef CONFIG_BLK_DEV_INITRD | ||
131 | if ((strstr(arcs_cmdline, "rdinit=")) == NULL) { | ||
132 | arg = "rdinit=/sbin/init "; | ||
133 | len = strlen(arg); | ||
134 | if (len > remain) | ||
135 | goto fail; | ||
136 | strcat(arcs_cmdline, arg); | ||
137 | remain -= len; | ||
138 | } | ||
139 | #endif | ||
140 | return; | ||
141 | fail: | ||
142 | panic("Cannot add %s, command line too big!", arg); | ||
143 | } | ||
144 | |||
145 | static void prom_add_memory(void) | ||
146 | { | ||
147 | struct nlm_boot_mem_map *bootm; | ||
148 | u64 start, size; | ||
149 | u64 pref_backup = 512; /* avoid pref walking beyond end */ | ||
150 | int i; | ||
151 | |||
152 | bootm = (void *)(long)nlm_prom_info.psb_mem_map; | ||
153 | for (i = 0; i < bootm->nr_map; i++) { | ||
154 | if (bootm->map[i].type != BOOT_MEM_RAM) | ||
155 | continue; | ||
156 | start = bootm->map[i].addr; | ||
157 | size = bootm->map[i].size; | ||
158 | |||
159 | /* Work around for using bootloader mem */ | ||
160 | if (i == 0 && start == 0 && size == 0x0c000000) | ||
161 | size = 0x0ff00000; | ||
162 | |||
163 | add_memory_region(start, size - pref_backup, BOOT_MEM_RAM); | ||
164 | } | ||
165 | } | ||
166 | |||
167 | void __init prom_init(void) | ||
168 | { | ||
169 | int *argv, *envp; /* passed as 32 bit ptrs */ | ||
170 | struct psb_info *prom_infop; | ||
171 | |||
172 | /* truncate to 32 bit and sign extend all args */ | ||
173 | argv = (int *)(long)(int)fw_arg1; | ||
174 | envp = (int *)(long)(int)fw_arg2; | ||
175 | prom_infop = (struct psb_info *)(long)(int)fw_arg3; | ||
176 | |||
177 | nlm_prom_info = *prom_infop; | ||
178 | |||
179 | nlm_early_serial_setup(); | ||
180 | build_arcs_cmdline(argv); | ||
181 | nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1)); | ||
182 | prom_add_memory(); | ||
183 | |||
184 | #ifdef CONFIG_SMP | ||
185 | nlm_wakeup_secondary_cpus(nlm_prom_info.online_cpu_map); | ||
186 | register_smp_ops(&nlm_smp_ops); | ||
187 | #endif | ||
188 | } | ||
diff --git a/arch/mips/netlogic/xlr/smp.c b/arch/mips/netlogic/xlr/smp.c new file mode 100644 index 000000000000..b495a7f1433b --- /dev/null +++ b/arch/mips/netlogic/xlr/smp.c | |||
@@ -0,0 +1,225 @@ | |||
1 | /* | ||
2 | * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the NetLogic | ||
9 | * license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in | ||
19 | * the documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR | ||
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/delay.h> | ||
37 | #include <linux/init.h> | ||
38 | #include <linux/smp.h> | ||
39 | #include <linux/irq.h> | ||
40 | |||
41 | #include <asm/mmu_context.h> | ||
42 | |||
43 | #include <asm/netlogic/interrupt.h> | ||
44 | #include <asm/netlogic/mips-extns.h> | ||
45 | |||
46 | #include <asm/netlogic/xlr/iomap.h> | ||
47 | #include <asm/netlogic/xlr/pic.h> | ||
48 | #include <asm/netlogic/xlr/xlr.h> | ||
49 | |||
50 | void core_send_ipi(int logical_cpu, unsigned int action) | ||
51 | { | ||
52 | int cpu = cpu_logical_map(logical_cpu); | ||
53 | u32 tid = cpu & 0x3; | ||
54 | u32 pid = (cpu >> 2) & 0x07; | ||
55 | u32 ipi = (tid << 16) | (pid << 20); | ||
56 | |||
57 | if (action & SMP_CALL_FUNCTION) | ||
58 | ipi |= IRQ_IPI_SMP_FUNCTION; | ||
59 | else if (action & SMP_RESCHEDULE_YOURSELF) | ||
60 | ipi |= IRQ_IPI_SMP_RESCHEDULE; | ||
61 | else | ||
62 | return; | ||
63 | |||
64 | pic_send_ipi(ipi); | ||
65 | } | ||
66 | |||
67 | void nlm_send_ipi_single(int cpu, unsigned int action) | ||
68 | { | ||
69 | core_send_ipi(cpu, action); | ||
70 | } | ||
71 | |||
72 | void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action) | ||
73 | { | ||
74 | int cpu; | ||
75 | |||
76 | for_each_cpu(cpu, mask) { | ||
77 | core_send_ipi(cpu, action); | ||
78 | } | ||
79 | } | ||
80 | |||
81 | /* IRQ_IPI_SMP_FUNCTION Handler */ | ||
82 | void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc) | ||
83 | { | ||
84 | smp_call_function_interrupt(); | ||
85 | } | ||
86 | |||
87 | /* IRQ_IPI_SMP_RESCHEDULE handler */ | ||
88 | void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc) | ||
89 | { | ||
90 | set_need_resched(); | ||
91 | } | ||
92 | |||
93 | void nlm_common_ipi_handler(int irq, struct pt_regs *regs) | ||
94 | { | ||
95 | if (irq == IRQ_IPI_SMP_FUNCTION) { | ||
96 | smp_call_function_interrupt(); | ||
97 | } else { | ||
98 | /* Announce that we are for reschduling */ | ||
99 | set_need_resched(); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | /* | ||
104 | * Called before going into mips code, early cpu init | ||
105 | */ | ||
106 | void nlm_early_init_secondary(void) | ||
107 | { | ||
108 | write_c0_ebase((uint32_t)nlm_common_ebase); | ||
109 | /* TLB partition here later */ | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * Code to run on secondary just after probing the CPU | ||
114 | */ | ||
115 | static void __cpuinit nlm_init_secondary(void) | ||
116 | { | ||
117 | nlm_smp_irq_init(); | ||
118 | } | ||
119 | |||
120 | void nlm_smp_finish(void) | ||
121 | { | ||
122 | #ifdef notyet | ||
123 | nlm_common_msgring_cpu_init(); | ||
124 | #endif | ||
125 | } | ||
126 | |||
127 | void nlm_cpus_done(void) | ||
128 | { | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * Boot all other cpus in the system, initialize them, and bring them into | ||
133 | * the boot function | ||
134 | */ | ||
135 | int nlm_cpu_unblock[NR_CPUS]; | ||
136 | int nlm_cpu_ready[NR_CPUS]; | ||
137 | unsigned long nlm_next_gp; | ||
138 | unsigned long nlm_next_sp; | ||
139 | cpumask_t phys_cpu_present_map; | ||
140 | |||
141 | void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) | ||
142 | { | ||
143 | unsigned long gp = (unsigned long)task_thread_info(idle); | ||
144 | unsigned long sp = (unsigned long)__KSTK_TOS(idle); | ||
145 | int cpu = cpu_logical_map(logical_cpu); | ||
146 | |||
147 | nlm_next_sp = sp; | ||
148 | nlm_next_gp = gp; | ||
149 | |||
150 | /* barrier */ | ||
151 | __sync(); | ||
152 | nlm_cpu_unblock[cpu] = 1; | ||
153 | } | ||
154 | |||
155 | void __init nlm_smp_setup(void) | ||
156 | { | ||
157 | unsigned int boot_cpu; | ||
158 | int num_cpus, i; | ||
159 | |||
160 | boot_cpu = hard_smp_processor_id(); | ||
161 | cpus_clear(phys_cpu_present_map); | ||
162 | |||
163 | cpu_set(boot_cpu, phys_cpu_present_map); | ||
164 | __cpu_number_map[boot_cpu] = 0; | ||
165 | __cpu_logical_map[0] = boot_cpu; | ||
166 | cpu_set(0, cpu_possible_map); | ||
167 | |||
168 | num_cpus = 1; | ||
169 | for (i = 0; i < NR_CPUS; i++) { | ||
170 | if (nlm_cpu_ready[i]) { | ||
171 | cpu_set(i, phys_cpu_present_map); | ||
172 | __cpu_number_map[i] = num_cpus; | ||
173 | __cpu_logical_map[num_cpus] = i; | ||
174 | cpu_set(num_cpus, cpu_possible_map); | ||
175 | ++num_cpus; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | pr_info("Phys CPU present map: %lx, possible map %lx\n", | ||
180 | (unsigned long)phys_cpu_present_map.bits[0], | ||
181 | (unsigned long)cpu_possible_map.bits[0]); | ||
182 | |||
183 | pr_info("Detected %i Slave CPU(s)\n", num_cpus); | ||
184 | } | ||
185 | |||
186 | void nlm_prepare_cpus(unsigned int max_cpus) | ||
187 | { | ||
188 | } | ||
189 | |||
190 | struct plat_smp_ops nlm_smp_ops = { | ||
191 | .send_ipi_single = nlm_send_ipi_single, | ||
192 | .send_ipi_mask = nlm_send_ipi_mask, | ||
193 | .init_secondary = nlm_init_secondary, | ||
194 | .smp_finish = nlm_smp_finish, | ||
195 | .cpus_done = nlm_cpus_done, | ||
196 | .boot_secondary = nlm_boot_secondary, | ||
197 | .smp_setup = nlm_smp_setup, | ||
198 | .prepare_cpus = nlm_prepare_cpus, | ||
199 | }; | ||
200 | |||
201 | unsigned long secondary_entry_point; | ||
202 | |||
203 | int nlm_wakeup_secondary_cpus(u32 wakeup_mask) | ||
204 | { | ||
205 | unsigned int tid, pid, ipi, i, boot_cpu; | ||
206 | void *reset_vec; | ||
207 | |||
208 | secondary_entry_point = (unsigned long)prom_pre_boot_secondary_cpus; | ||
209 | reset_vec = (void *)CKSEG1ADDR(0x1fc00000); | ||
210 | memcpy(reset_vec, nlm_boot_smp_nmi, 0x80); | ||
211 | boot_cpu = hard_smp_processor_id(); | ||
212 | |||
213 | for (i = 0; i < NR_CPUS; i++) { | ||
214 | if (i == boot_cpu) | ||
215 | continue; | ||
216 | if (wakeup_mask & (1u << i)) { | ||
217 | tid = i & 0x3; | ||
218 | pid = (i >> 2) & 0x7; | ||
219 | ipi = (tid << 16) | (pid << 20) | (1 << 8); | ||
220 | pic_send_ipi(ipi); | ||
221 | } | ||
222 | } | ||
223 | |||
224 | return 0; | ||
225 | } | ||
diff --git a/arch/mips/netlogic/xlr/smpboot.S b/arch/mips/netlogic/xlr/smpboot.S new file mode 100644 index 000000000000..b8e074402c99 --- /dev/null +++ b/arch/mips/netlogic/xlr/smpboot.S | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the NetLogic | ||
9 | * license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in | ||
19 | * the documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR | ||
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #include <asm/asm.h> | ||
36 | #include <asm/asm-offsets.h> | ||
37 | #include <asm/regdef.h> | ||
38 | #include <asm/mipsregs.h> | ||
39 | |||
40 | |||
41 | /* Don't jump to linux function from Bootloader stack. Change it | ||
42 | * here. Kernel might allocate bootloader memory before all the CPUs are | ||
43 | * brought up (eg: Inode cache region) and we better don't overwrite this | ||
44 | * memory | ||
45 | */ | ||
46 | NESTED(prom_pre_boot_secondary_cpus, 16, sp) | ||
47 | .set mips64 | ||
48 | mfc0 t0, $15, 1 # read ebase | ||
49 | andi t0, 0x1f # t0 has the processor_id() | ||
50 | sll t0, 2 # offset in cpu array | ||
51 | |||
52 | PTR_LA t1, nlm_cpu_ready # mark CPU ready | ||
53 | PTR_ADDU t1, t0 | ||
54 | li t2, 1 | ||
55 | sw t2, 0(t1) | ||
56 | |||
57 | PTR_LA t1, nlm_cpu_unblock | ||
58 | PTR_ADDU t1, t0 | ||
59 | 1: lw t2, 0(t1) # wait till unblocked | ||
60 | beqz t2, 1b | ||
61 | nop | ||
62 | |||
63 | PTR_LA t1, nlm_next_sp | ||
64 | PTR_L sp, 0(t1) | ||
65 | PTR_LA t1, nlm_next_gp | ||
66 | PTR_L gp, 0(t1) | ||
67 | |||
68 | PTR_LA t0, nlm_early_init_secondary | ||
69 | jalr t0 | ||
70 | nop | ||
71 | |||
72 | PTR_LA t0, smp_bootstrap | ||
73 | jr t0 | ||
74 | nop | ||
75 | END(prom_pre_boot_secondary_cpus) | ||
76 | |||
77 | NESTED(nlm_boot_smp_nmi, 0, sp) | ||
78 | .set push | ||
79 | .set noat | ||
80 | .set mips64 | ||
81 | .set noreorder | ||
82 | |||
83 | /* Clear the NMI and BEV bits */ | ||
84 | MFC0 k0, CP0_STATUS | ||
85 | li k1, 0xffb7ffff | ||
86 | and k0, k0, k1 | ||
87 | MTC0 k0, CP0_STATUS | ||
88 | |||
89 | PTR_LA k1, secondary_entry_point | ||
90 | PTR_L k0, 0(k1) | ||
91 | jr k0 | ||
92 | nop | ||
93 | .set pop | ||
94 | END(nlm_boot_smp_nmi) | ||
diff --git a/arch/mips/netlogic/xlr/time.c b/arch/mips/netlogic/xlr/time.c new file mode 100644 index 000000000000..0d81b262593c --- /dev/null +++ b/arch/mips/netlogic/xlr/time.c | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the NetLogic | ||
9 | * license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in | ||
19 | * the documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR | ||
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #include <linux/init.h> | ||
36 | |||
37 | #include <asm/time.h> | ||
38 | #include <asm/netlogic/interrupt.h> | ||
39 | #include <asm/netlogic/psb-bootinfo.h> | ||
40 | |||
41 | unsigned int __cpuinit get_c0_compare_int(void) | ||
42 | { | ||
43 | return IRQ_TIMER; | ||
44 | } | ||
45 | |||
46 | void __init plat_time_init(void) | ||
47 | { | ||
48 | mips_hpt_frequency = nlm_prom_info.cpu_frequency; | ||
49 | pr_info("MIPS counter frequency [%ld]\n", | ||
50 | (unsigned long)mips_hpt_frequency); | ||
51 | } | ||
diff --git a/arch/mips/netlogic/xlr/xlr_console.c b/arch/mips/netlogic/xlr/xlr_console.c new file mode 100644 index 000000000000..759df0692201 --- /dev/null +++ b/arch/mips/netlogic/xlr/xlr_console.c | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the NetLogic | ||
9 | * license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in | ||
19 | * the documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR | ||
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #include <linux/types.h> | ||
36 | #include <asm/netlogic/xlr/iomap.h> | ||
37 | |||
38 | void prom_putchar(char c) | ||
39 | { | ||
40 | nlm_reg_t *mmio; | ||
41 | |||
42 | mmio = netlogic_io_mmio(NETLOGIC_IO_UART_0_OFFSET); | ||
43 | while (netlogic_read_reg(mmio, 0x5) == 0) | ||
44 | ; | ||
45 | netlogic_write_reg(mmio, 0x0, c); | ||
46 | } | ||
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index c9209ca6c8e7..4df879937446 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile | |||
@@ -41,6 +41,7 @@ obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o | |||
41 | obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o | 41 | obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o |
42 | obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o | 42 | obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o |
43 | obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o | 43 | obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o |
44 | obj-$(CONFIG_SOC_XWAY) += pci-lantiq.o ops-lantiq.o | ||
44 | obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o | 45 | obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o |
45 | obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o | 46 | obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o |
46 | obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o | 47 | obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o |
@@ -55,6 +56,7 @@ obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o | |||
55 | obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o | 56 | obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o |
56 | obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o | 57 | obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o |
57 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += pci-octeon.o pcie-octeon.o | 58 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += pci-octeon.o pcie-octeon.o |
59 | obj-$(CONFIG_NLM_XLR) += pci-xlr.o | ||
58 | 60 | ||
59 | ifdef CONFIG_PCI_MSI | 61 | ifdef CONFIG_PCI_MSI |
60 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += msi-octeon.o | 62 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += msi-octeon.o |
diff --git a/arch/mips/pci/ops-lantiq.c b/arch/mips/pci/ops-lantiq.c new file mode 100644 index 000000000000..1f2afb55cc71 --- /dev/null +++ b/arch/mips/pci/ops-lantiq.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/types.h> | ||
10 | #include <linux/pci.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/mm.h> | ||
15 | #include <asm/addrspace.h> | ||
16 | #include <linux/vmalloc.h> | ||
17 | |||
18 | #include <lantiq_soc.h> | ||
19 | |||
20 | #include "pci-lantiq.h" | ||
21 | |||
22 | #define LTQ_PCI_CFG_BUSNUM_SHF 16 | ||
23 | #define LTQ_PCI_CFG_DEVNUM_SHF 11 | ||
24 | #define LTQ_PCI_CFG_FUNNUM_SHF 8 | ||
25 | |||
26 | #define PCI_ACCESS_READ 0 | ||
27 | #define PCI_ACCESS_WRITE 1 | ||
28 | |||
29 | static int ltq_pci_config_access(unsigned char access_type, struct pci_bus *bus, | ||
30 | unsigned int devfn, unsigned int where, u32 *data) | ||
31 | { | ||
32 | unsigned long cfg_base; | ||
33 | unsigned long flags; | ||
34 | u32 temp; | ||
35 | |||
36 | /* we support slot from 0 to 15 dev_fn & 0x68 (AD29) is the | ||
37 | SoC itself */ | ||
38 | if ((bus->number != 0) || ((devfn & 0xf8) > 0x78) | ||
39 | || ((devfn & 0xf8) == 0) || ((devfn & 0xf8) == 0x68)) | ||
40 | return 1; | ||
41 | |||
42 | spin_lock_irqsave(&ebu_lock, flags); | ||
43 | |||
44 | cfg_base = (unsigned long) ltq_pci_mapped_cfg; | ||
45 | cfg_base |= (bus->number << LTQ_PCI_CFG_BUSNUM_SHF) | (devfn << | ||
46 | LTQ_PCI_CFG_FUNNUM_SHF) | (where & ~0x3); | ||
47 | |||
48 | /* Perform access */ | ||
49 | if (access_type == PCI_ACCESS_WRITE) { | ||
50 | ltq_w32(swab32(*data), ((u32 *)cfg_base)); | ||
51 | } else { | ||
52 | *data = ltq_r32(((u32 *)(cfg_base))); | ||
53 | *data = swab32(*data); | ||
54 | } | ||
55 | wmb(); | ||
56 | |||
57 | /* clean possible Master abort */ | ||
58 | cfg_base = (unsigned long) ltq_pci_mapped_cfg; | ||
59 | cfg_base |= (0x0 << LTQ_PCI_CFG_FUNNUM_SHF) + 4; | ||
60 | temp = ltq_r32(((u32 *)(cfg_base))); | ||
61 | temp = swab32(temp); | ||
62 | cfg_base = (unsigned long) ltq_pci_mapped_cfg; | ||
63 | cfg_base |= (0x68 << LTQ_PCI_CFG_FUNNUM_SHF) + 4; | ||
64 | ltq_w32(temp, ((u32 *)cfg_base)); | ||
65 | |||
66 | spin_unlock_irqrestore(&ebu_lock, flags); | ||
67 | |||
68 | if (((*data) == 0xffffffff) && (access_type == PCI_ACCESS_READ)) | ||
69 | return 1; | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | int ltq_pci_read_config_dword(struct pci_bus *bus, unsigned int devfn, | ||
75 | int where, int size, u32 *val) | ||
76 | { | ||
77 | u32 data = 0; | ||
78 | |||
79 | if (ltq_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) | ||
80 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
81 | |||
82 | if (size == 1) | ||
83 | *val = (data >> ((where & 3) << 3)) & 0xff; | ||
84 | else if (size == 2) | ||
85 | *val = (data >> ((where & 3) << 3)) & 0xffff; | ||
86 | else | ||
87 | *val = data; | ||
88 | |||
89 | return PCIBIOS_SUCCESSFUL; | ||
90 | } | ||
91 | |||
92 | int ltq_pci_write_config_dword(struct pci_bus *bus, unsigned int devfn, | ||
93 | int where, int size, u32 val) | ||
94 | { | ||
95 | u32 data = 0; | ||
96 | |||
97 | if (size == 4) { | ||
98 | data = val; | ||
99 | } else { | ||
100 | if (ltq_pci_config_access(PCI_ACCESS_READ, bus, | ||
101 | devfn, where, &data)) | ||
102 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
103 | |||
104 | if (size == 1) | ||
105 | data = (data & ~(0xff << ((where & 3) << 3))) | | ||
106 | (val << ((where & 3) << 3)); | ||
107 | else if (size == 2) | ||
108 | data = (data & ~(0xffff << ((where & 3) << 3))) | | ||
109 | (val << ((where & 3) << 3)); | ||
110 | } | ||
111 | |||
112 | if (ltq_pci_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) | ||
113 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
114 | |||
115 | return PCIBIOS_SUCCESSFUL; | ||
116 | } | ||
diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c new file mode 100644 index 000000000000..603d7493e966 --- /dev/null +++ b/arch/mips/pci/pci-lantiq.c | |||
@@ -0,0 +1,297 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/types.h> | ||
10 | #include <linux/pci.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/mm.h> | ||
15 | #include <linux/vmalloc.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include <asm/pci.h> | ||
19 | #include <asm/gpio.h> | ||
20 | #include <asm/addrspace.h> | ||
21 | |||
22 | #include <lantiq_soc.h> | ||
23 | #include <lantiq_irq.h> | ||
24 | #include <lantiq_platform.h> | ||
25 | |||
26 | #include "pci-lantiq.h" | ||
27 | |||
28 | #define LTQ_PCI_CFG_BASE 0x17000000 | ||
29 | #define LTQ_PCI_CFG_SIZE 0x00008000 | ||
30 | #define LTQ_PCI_MEM_BASE 0x18000000 | ||
31 | #define LTQ_PCI_MEM_SIZE 0x02000000 | ||
32 | #define LTQ_PCI_IO_BASE 0x1AE00000 | ||
33 | #define LTQ_PCI_IO_SIZE 0x00200000 | ||
34 | |||
35 | #define PCI_CR_FCI_ADDR_MAP0 0x00C0 | ||
36 | #define PCI_CR_FCI_ADDR_MAP1 0x00C4 | ||
37 | #define PCI_CR_FCI_ADDR_MAP2 0x00C8 | ||
38 | #define PCI_CR_FCI_ADDR_MAP3 0x00CC | ||
39 | #define PCI_CR_FCI_ADDR_MAP4 0x00D0 | ||
40 | #define PCI_CR_FCI_ADDR_MAP5 0x00D4 | ||
41 | #define PCI_CR_FCI_ADDR_MAP6 0x00D8 | ||
42 | #define PCI_CR_FCI_ADDR_MAP7 0x00DC | ||
43 | #define PCI_CR_CLK_CTRL 0x0000 | ||
44 | #define PCI_CR_PCI_MOD 0x0030 | ||
45 | #define PCI_CR_PC_ARB 0x0080 | ||
46 | #define PCI_CR_FCI_ADDR_MAP11hg 0x00E4 | ||
47 | #define PCI_CR_BAR11MASK 0x0044 | ||
48 | #define PCI_CR_BAR12MASK 0x0048 | ||
49 | #define PCI_CR_BAR13MASK 0x004C | ||
50 | #define PCI_CS_BASE_ADDR1 0x0010 | ||
51 | #define PCI_CR_PCI_ADDR_MAP11 0x0064 | ||
52 | #define PCI_CR_FCI_BURST_LENGTH 0x00E8 | ||
53 | #define PCI_CR_PCI_EOI 0x002C | ||
54 | #define PCI_CS_STS_CMD 0x0004 | ||
55 | |||
56 | #define PCI_MASTER0_REQ_MASK_2BITS 8 | ||
57 | #define PCI_MASTER1_REQ_MASK_2BITS 10 | ||
58 | #define PCI_MASTER2_REQ_MASK_2BITS 12 | ||
59 | #define INTERNAL_ARB_ENABLE_BIT 0 | ||
60 | |||
61 | #define LTQ_CGU_IFCCR 0x0018 | ||
62 | #define LTQ_CGU_PCICR 0x0034 | ||
63 | |||
64 | #define ltq_pci_w32(x, y) ltq_w32((x), ltq_pci_membase + (y)) | ||
65 | #define ltq_pci_r32(x) ltq_r32(ltq_pci_membase + (x)) | ||
66 | |||
67 | #define ltq_pci_cfg_w32(x, y) ltq_w32((x), ltq_pci_mapped_cfg + (y)) | ||
68 | #define ltq_pci_cfg_r32(x) ltq_r32(ltq_pci_mapped_cfg + (x)) | ||
69 | |||
70 | struct ltq_pci_gpio_map { | ||
71 | int pin; | ||
72 | int alt0; | ||
73 | int alt1; | ||
74 | int dir; | ||
75 | char *name; | ||
76 | }; | ||
77 | |||
78 | /* the pci core can make use of the following gpios */ | ||
79 | static struct ltq_pci_gpio_map ltq_pci_gpio_map[] = { | ||
80 | { 0, 1, 0, 0, "pci-exin0" }, | ||
81 | { 1, 1, 0, 0, "pci-exin1" }, | ||
82 | { 2, 1, 0, 0, "pci-exin2" }, | ||
83 | { 39, 1, 0, 0, "pci-exin3" }, | ||
84 | { 10, 1, 0, 0, "pci-exin4" }, | ||
85 | { 9, 1, 0, 0, "pci-exin5" }, | ||
86 | { 30, 1, 0, 1, "pci-gnt1" }, | ||
87 | { 23, 1, 0, 1, "pci-gnt2" }, | ||
88 | { 19, 1, 0, 1, "pci-gnt3" }, | ||
89 | { 38, 1, 0, 1, "pci-gnt4" }, | ||
90 | { 29, 1, 0, 0, "pci-req1" }, | ||
91 | { 31, 1, 0, 0, "pci-req2" }, | ||
92 | { 3, 1, 0, 0, "pci-req3" }, | ||
93 | { 37, 1, 0, 0, "pci-req4" }, | ||
94 | }; | ||
95 | |||
96 | __iomem void *ltq_pci_mapped_cfg; | ||
97 | static __iomem void *ltq_pci_membase; | ||
98 | |||
99 | int (*ltqpci_plat_dev_init)(struct pci_dev *dev) = NULL; | ||
100 | |||
101 | /* Since the PCI REQ pins can be reused for other functionality, make it | ||
102 | possible to exclude those from interpretation by the PCI controller */ | ||
103 | static int ltq_pci_req_mask = 0xf; | ||
104 | |||
105 | static int *ltq_pci_irq_map; | ||
106 | |||
107 | struct pci_ops ltq_pci_ops = { | ||
108 | .read = ltq_pci_read_config_dword, | ||
109 | .write = ltq_pci_write_config_dword | ||
110 | }; | ||
111 | |||
112 | static struct resource pci_io_resource = { | ||
113 | .name = "pci io space", | ||
114 | .start = LTQ_PCI_IO_BASE, | ||
115 | .end = LTQ_PCI_IO_BASE + LTQ_PCI_IO_SIZE - 1, | ||
116 | .flags = IORESOURCE_IO | ||
117 | }; | ||
118 | |||
119 | static struct resource pci_mem_resource = { | ||
120 | .name = "pci memory space", | ||
121 | .start = LTQ_PCI_MEM_BASE, | ||
122 | .end = LTQ_PCI_MEM_BASE + LTQ_PCI_MEM_SIZE - 1, | ||
123 | .flags = IORESOURCE_MEM | ||
124 | }; | ||
125 | |||
126 | static struct pci_controller ltq_pci_controller = { | ||
127 | .pci_ops = <q_pci_ops, | ||
128 | .mem_resource = &pci_mem_resource, | ||
129 | .mem_offset = 0x00000000UL, | ||
130 | .io_resource = &pci_io_resource, | ||
131 | .io_offset = 0x00000000UL, | ||
132 | }; | ||
133 | |||
134 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
135 | { | ||
136 | if (ltqpci_plat_dev_init) | ||
137 | return ltqpci_plat_dev_init(dev); | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static u32 ltq_calc_bar11mask(void) | ||
143 | { | ||
144 | u32 mem, bar11mask; | ||
145 | |||
146 | /* BAR11MASK value depends on available memory on system. */ | ||
147 | mem = num_physpages * PAGE_SIZE; | ||
148 | bar11mask = (0x0ffffff0 & ~((1 << (fls(mem) - 1)) - 1)) | 8; | ||
149 | |||
150 | return bar11mask; | ||
151 | } | ||
152 | |||
153 | static void ltq_pci_setup_gpio(int gpio) | ||
154 | { | ||
155 | int i; | ||
156 | for (i = 0; i < ARRAY_SIZE(ltq_pci_gpio_map); i++) { | ||
157 | if (gpio & (1 << i)) { | ||
158 | ltq_gpio_request(ltq_pci_gpio_map[i].pin, | ||
159 | ltq_pci_gpio_map[i].alt0, | ||
160 | ltq_pci_gpio_map[i].alt1, | ||
161 | ltq_pci_gpio_map[i].dir, | ||
162 | ltq_pci_gpio_map[i].name); | ||
163 | } | ||
164 | } | ||
165 | ltq_gpio_request(21, 0, 0, 1, "pci-reset"); | ||
166 | ltq_pci_req_mask = (gpio >> PCI_REQ_SHIFT) & PCI_REQ_MASK; | ||
167 | } | ||
168 | |||
169 | static int __devinit ltq_pci_startup(struct ltq_pci_data *conf) | ||
170 | { | ||
171 | u32 temp_buffer; | ||
172 | |||
173 | /* set clock to 33Mhz */ | ||
174 | ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR); | ||
175 | ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR); | ||
176 | |||
177 | /* external or internal clock ? */ | ||
178 | if (conf->clock) { | ||
179 | ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~(1 << 16), | ||
180 | LTQ_CGU_IFCCR); | ||
181 | ltq_cgu_w32((1 << 30), LTQ_CGU_PCICR); | ||
182 | } else { | ||
183 | ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | (1 << 16), | ||
184 | LTQ_CGU_IFCCR); | ||
185 | ltq_cgu_w32((1 << 31) | (1 << 30), LTQ_CGU_PCICR); | ||
186 | } | ||
187 | |||
188 | /* setup pci clock and gpis used by pci */ | ||
189 | ltq_pci_setup_gpio(conf->gpio); | ||
190 | |||
191 | /* enable auto-switching between PCI and EBU */ | ||
192 | ltq_pci_w32(0xa, PCI_CR_CLK_CTRL); | ||
193 | |||
194 | /* busy, i.e. configuration is not done, PCI access has to be retried */ | ||
195 | ltq_pci_w32(ltq_pci_r32(PCI_CR_PCI_MOD) & ~(1 << 24), PCI_CR_PCI_MOD); | ||
196 | wmb(); | ||
197 | /* BUS Master/IO/MEM access */ | ||
198 | ltq_pci_cfg_w32(ltq_pci_cfg_r32(PCI_CS_STS_CMD) | 7, PCI_CS_STS_CMD); | ||
199 | |||
200 | /* enable external 2 PCI masters */ | ||
201 | temp_buffer = ltq_pci_r32(PCI_CR_PC_ARB); | ||
202 | temp_buffer &= (~(ltq_pci_req_mask << 16)); | ||
203 | /* enable internal arbiter */ | ||
204 | temp_buffer |= (1 << INTERNAL_ARB_ENABLE_BIT); | ||
205 | /* enable internal PCI master reqest */ | ||
206 | temp_buffer &= (~(3 << PCI_MASTER0_REQ_MASK_2BITS)); | ||
207 | |||
208 | /* enable EBU request */ | ||
209 | temp_buffer &= (~(3 << PCI_MASTER1_REQ_MASK_2BITS)); | ||
210 | |||
211 | /* enable all external masters request */ | ||
212 | temp_buffer &= (~(3 << PCI_MASTER2_REQ_MASK_2BITS)); | ||
213 | ltq_pci_w32(temp_buffer, PCI_CR_PC_ARB); | ||
214 | wmb(); | ||
215 | |||
216 | /* setup BAR memory regions */ | ||
217 | ltq_pci_w32(0x18000000, PCI_CR_FCI_ADDR_MAP0); | ||
218 | ltq_pci_w32(0x18400000, PCI_CR_FCI_ADDR_MAP1); | ||
219 | ltq_pci_w32(0x18800000, PCI_CR_FCI_ADDR_MAP2); | ||
220 | ltq_pci_w32(0x18c00000, PCI_CR_FCI_ADDR_MAP3); | ||
221 | ltq_pci_w32(0x19000000, PCI_CR_FCI_ADDR_MAP4); | ||
222 | ltq_pci_w32(0x19400000, PCI_CR_FCI_ADDR_MAP5); | ||
223 | ltq_pci_w32(0x19800000, PCI_CR_FCI_ADDR_MAP6); | ||
224 | ltq_pci_w32(0x19c00000, PCI_CR_FCI_ADDR_MAP7); | ||
225 | ltq_pci_w32(0x1ae00000, PCI_CR_FCI_ADDR_MAP11hg); | ||
226 | ltq_pci_w32(ltq_calc_bar11mask(), PCI_CR_BAR11MASK); | ||
227 | ltq_pci_w32(0, PCI_CR_PCI_ADDR_MAP11); | ||
228 | ltq_pci_w32(0, PCI_CS_BASE_ADDR1); | ||
229 | /* both TX and RX endian swap are enabled */ | ||
230 | ltq_pci_w32(ltq_pci_r32(PCI_CR_PCI_EOI) | 3, PCI_CR_PCI_EOI); | ||
231 | wmb(); | ||
232 | ltq_pci_w32(ltq_pci_r32(PCI_CR_BAR12MASK) | 0x80000000, | ||
233 | PCI_CR_BAR12MASK); | ||
234 | ltq_pci_w32(ltq_pci_r32(PCI_CR_BAR13MASK) | 0x80000000, | ||
235 | PCI_CR_BAR13MASK); | ||
236 | /*use 8 dw burst length */ | ||
237 | ltq_pci_w32(0x303, PCI_CR_FCI_BURST_LENGTH); | ||
238 | ltq_pci_w32(ltq_pci_r32(PCI_CR_PCI_MOD) | (1 << 24), PCI_CR_PCI_MOD); | ||
239 | wmb(); | ||
240 | |||
241 | /* setup irq line */ | ||
242 | ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_CON) | 0xc, LTQ_EBU_PCC_CON); | ||
243 | ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_IEN) | 0x10, LTQ_EBU_PCC_IEN); | ||
244 | |||
245 | /* toggle reset pin */ | ||
246 | __gpio_set_value(21, 0); | ||
247 | wmb(); | ||
248 | mdelay(1); | ||
249 | __gpio_set_value(21, 1); | ||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
254 | { | ||
255 | if (ltq_pci_irq_map[slot]) | ||
256 | return ltq_pci_irq_map[slot]; | ||
257 | printk(KERN_ERR "lq_pci: trying to map irq for unknown slot %d\n", | ||
258 | slot); | ||
259 | |||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | static int __devinit ltq_pci_probe(struct platform_device *pdev) | ||
264 | { | ||
265 | struct ltq_pci_data *ltq_pci_data = | ||
266 | (struct ltq_pci_data *) pdev->dev.platform_data; | ||
267 | pci_probe_only = 0; | ||
268 | ltq_pci_irq_map = ltq_pci_data->irq; | ||
269 | ltq_pci_membase = ioremap_nocache(PCI_CR_BASE_ADDR, PCI_CR_SIZE); | ||
270 | ltq_pci_mapped_cfg = | ||
271 | ioremap_nocache(LTQ_PCI_CFG_BASE, LTQ_PCI_CFG_BASE); | ||
272 | ltq_pci_controller.io_map_base = | ||
273 | (unsigned long)ioremap(LTQ_PCI_IO_BASE, LTQ_PCI_IO_SIZE - 1); | ||
274 | ltq_pci_startup(ltq_pci_data); | ||
275 | register_pci_controller(<q_pci_controller); | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | static struct platform_driver | ||
281 | ltq_pci_driver = { | ||
282 | .probe = ltq_pci_probe, | ||
283 | .driver = { | ||
284 | .name = "ltq_pci", | ||
285 | .owner = THIS_MODULE, | ||
286 | }, | ||
287 | }; | ||
288 | |||
289 | int __init pcibios_init(void) | ||
290 | { | ||
291 | int ret = platform_driver_register(<q_pci_driver); | ||
292 | if (ret) | ||
293 | printk(KERN_INFO "ltq_pci: Error registering platfom driver!"); | ||
294 | return ret; | ||
295 | } | ||
296 | |||
297 | arch_initcall(pcibios_init); | ||
diff --git a/arch/mips/pci/pci-lantiq.h b/arch/mips/pci/pci-lantiq.h new file mode 100644 index 000000000000..66bf6cd6be3c --- /dev/null +++ b/arch/mips/pci/pci-lantiq.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LTQ_PCI_H__ | ||
10 | #define _LTQ_PCI_H__ | ||
11 | |||
12 | extern __iomem void *ltq_pci_mapped_cfg; | ||
13 | extern int ltq_pci_read_config_dword(struct pci_bus *bus, | ||
14 | unsigned int devfn, int where, int size, u32 *val); | ||
15 | extern int ltq_pci_write_config_dword(struct pci_bus *bus, | ||
16 | unsigned int devfn, int where, int size, u32 val); | ||
17 | |||
18 | #endif | ||
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c new file mode 100644 index 000000000000..38fece16c435 --- /dev/null +++ b/arch/mips/pci/pci-xlr.c | |||
@@ -0,0 +1,214 @@ | |||
1 | /* | ||
2 | * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the NetLogic | ||
9 | * license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in | ||
19 | * the documentation and/or other materials provided with the | ||
20 | * distribution. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR | ||
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #include <linux/types.h> | ||
36 | #include <linux/pci.h> | ||
37 | #include <linux/kernel.h> | ||
38 | #include <linux/init.h> | ||
39 | #include <linux/mm.h> | ||
40 | #include <linux/console.h> | ||
41 | |||
42 | #include <asm/io.h> | ||
43 | |||
44 | #include <asm/netlogic/interrupt.h> | ||
45 | #include <asm/netlogic/xlr/iomap.h> | ||
46 | #include <asm/netlogic/xlr/pic.h> | ||
47 | #include <asm/netlogic/xlr/xlr.h> | ||
48 | |||
49 | static void *pci_config_base; | ||
50 | |||
51 | #define pci_cfg_addr(bus, devfn, off) (((bus) << 16) | ((devfn) << 8) | (off)) | ||
52 | |||
53 | /* PCI ops */ | ||
54 | static inline u32 pci_cfg_read_32bit(struct pci_bus *bus, unsigned int devfn, | ||
55 | int where) | ||
56 | { | ||
57 | u32 data; | ||
58 | u32 *cfgaddr; | ||
59 | |||
60 | cfgaddr = (u32 *)(pci_config_base + | ||
61 | pci_cfg_addr(bus->number, devfn, where & ~3)); | ||
62 | data = *cfgaddr; | ||
63 | return cpu_to_le32(data); | ||
64 | } | ||
65 | |||
66 | static inline void pci_cfg_write_32bit(struct pci_bus *bus, unsigned int devfn, | ||
67 | int where, u32 data) | ||
68 | { | ||
69 | u32 *cfgaddr; | ||
70 | |||
71 | cfgaddr = (u32 *)(pci_config_base + | ||
72 | pci_cfg_addr(bus->number, devfn, where & ~3)); | ||
73 | *cfgaddr = cpu_to_le32(data); | ||
74 | } | ||
75 | |||
76 | static int nlm_pcibios_read(struct pci_bus *bus, unsigned int devfn, | ||
77 | int where, int size, u32 *val) | ||
78 | { | ||
79 | u32 data; | ||
80 | |||
81 | if ((size == 2) && (where & 1)) | ||
82 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
83 | else if ((size == 4) && (where & 3)) | ||
84 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
85 | |||
86 | data = pci_cfg_read_32bit(bus, devfn, where); | ||
87 | |||
88 | if (size == 1) | ||
89 | *val = (data >> ((where & 3) << 3)) & 0xff; | ||
90 | else if (size == 2) | ||
91 | *val = (data >> ((where & 3) << 3)) & 0xffff; | ||
92 | else | ||
93 | *val = data; | ||
94 | |||
95 | return PCIBIOS_SUCCESSFUL; | ||
96 | } | ||
97 | |||
98 | |||
99 | static int nlm_pcibios_write(struct pci_bus *bus, unsigned int devfn, | ||
100 | int where, int size, u32 val) | ||
101 | { | ||
102 | u32 data; | ||
103 | |||
104 | if ((size == 2) && (where & 1)) | ||
105 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
106 | else if ((size == 4) && (where & 3)) | ||
107 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
108 | |||
109 | data = pci_cfg_read_32bit(bus, devfn, where); | ||
110 | |||
111 | if (size == 1) | ||
112 | data = (data & ~(0xff << ((where & 3) << 3))) | | ||
113 | (val << ((where & 3) << 3)); | ||
114 | else if (size == 2) | ||
115 | data = (data & ~(0xffff << ((where & 3) << 3))) | | ||
116 | (val << ((where & 3) << 3)); | ||
117 | else | ||
118 | data = val; | ||
119 | |||
120 | pci_cfg_write_32bit(bus, devfn, where, data); | ||
121 | |||
122 | return PCIBIOS_SUCCESSFUL; | ||
123 | } | ||
124 | |||
125 | struct pci_ops nlm_pci_ops = { | ||
126 | .read = nlm_pcibios_read, | ||
127 | .write = nlm_pcibios_write | ||
128 | }; | ||
129 | |||
130 | static struct resource nlm_pci_mem_resource = { | ||
131 | .name = "XLR PCI MEM", | ||
132 | .start = 0xd0000000UL, /* 256MB PCI mem @ 0xd000_0000 */ | ||
133 | .end = 0xdfffffffUL, | ||
134 | .flags = IORESOURCE_MEM, | ||
135 | }; | ||
136 | |||
137 | static struct resource nlm_pci_io_resource = { | ||
138 | .name = "XLR IO MEM", | ||
139 | .start = 0x10000000UL, /* 16MB PCI IO @ 0x1000_0000 */ | ||
140 | .end = 0x100fffffUL, | ||
141 | .flags = IORESOURCE_IO, | ||
142 | }; | ||
143 | |||
144 | struct pci_controller nlm_pci_controller = { | ||
145 | .index = 0, | ||
146 | .pci_ops = &nlm_pci_ops, | ||
147 | .mem_resource = &nlm_pci_mem_resource, | ||
148 | .mem_offset = 0x00000000UL, | ||
149 | .io_resource = &nlm_pci_io_resource, | ||
150 | .io_offset = 0x00000000UL, | ||
151 | }; | ||
152 | |||
153 | int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
154 | { | ||
155 | if (!nlm_chip_is_xls()) | ||
156 | return PIC_PCIX_IRQ; /* for XLR just one IRQ*/ | ||
157 | |||
158 | /* | ||
159 | * For XLS PCIe, there is an IRQ per Link, find out which | ||
160 | * link the device is on to assign interrupts | ||
161 | */ | ||
162 | if (dev->bus->self == NULL) | ||
163 | return 0; | ||
164 | |||
165 | switch (dev->bus->self->devfn) { | ||
166 | case 0x0: | ||
167 | return PIC_PCIE_LINK0_IRQ; | ||
168 | case 0x8: | ||
169 | return PIC_PCIE_LINK1_IRQ; | ||
170 | case 0x10: | ||
171 | if (nlm_chip_is_xls_b()) | ||
172 | return PIC_PCIE_XLSB0_LINK2_IRQ; | ||
173 | else | ||
174 | return PIC_PCIE_LINK2_IRQ; | ||
175 | case 0x18: | ||
176 | if (nlm_chip_is_xls_b()) | ||
177 | return PIC_PCIE_XLSB0_LINK3_IRQ; | ||
178 | else | ||
179 | return PIC_PCIE_LINK3_IRQ; | ||
180 | } | ||
181 | WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn); | ||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | /* Do platform specific device initialization at pci_enable_device() time */ | ||
186 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
187 | { | ||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | static int __init pcibios_init(void) | ||
192 | { | ||
193 | /* PSB assigns PCI resources */ | ||
194 | pci_probe_only = 1; | ||
195 | pci_config_base = ioremap(DEFAULT_PCI_CONFIG_BASE, 16 << 20); | ||
196 | |||
197 | /* Extend IO port for memory mapped io */ | ||
198 | ioport_resource.start = 0; | ||
199 | ioport_resource.end = ~0; | ||
200 | |||
201 | set_io_port_base(CKSEG1); | ||
202 | nlm_pci_controller.io_map_base = CKSEG1; | ||
203 | |||
204 | pr_info("Registering XLR/XLS PCIX/PCIE Controller.\n"); | ||
205 | register_pci_controller(&nlm_pci_controller); | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | arch_initcall(pcibios_init); | ||
211 | |||
212 | struct pci_fixup pcibios_fixups[] = { | ||
213 | {0} | ||
214 | }; | ||
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index a152538d3c97..3f810c9cbf83 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c | |||
@@ -66,18 +66,7 @@ static int rt_next_event(unsigned long delta, struct clock_event_device *evt) | |||
66 | static void rt_set_mode(enum clock_event_mode mode, | 66 | static void rt_set_mode(enum clock_event_mode mode, |
67 | struct clock_event_device *evt) | 67 | struct clock_event_device *evt) |
68 | { | 68 | { |
69 | switch (mode) { | 69 | /* Nothing to do ... */ |
70 | case CLOCK_EVT_MODE_ONESHOT: | ||
71 | /* The only mode supported */ | ||
72 | break; | ||
73 | |||
74 | case CLOCK_EVT_MODE_PERIODIC: | ||
75 | case CLOCK_EVT_MODE_UNUSED: | ||
76 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
77 | case CLOCK_EVT_MODE_RESUME: | ||
78 | /* Nothing to do */ | ||
79 | break; | ||
80 | } | ||
81 | } | 70 | } |
82 | 71 | ||
83 | int rt_timer_irq; | 72 | int rt_timer_irq; |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 44b1f46458ca..5069111c81cc 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -260,6 +260,13 @@ config MTD_BCM963XX | |||
260 | Support for parsing CFE image tag and creating MTD partitions on | 260 | Support for parsing CFE image tag and creating MTD partitions on |
261 | Broadcom BCM63xx boards. | 261 | Broadcom BCM63xx boards. |
262 | 262 | ||
263 | config MTD_LANTIQ | ||
264 | tristate "Lantiq SoC NOR support" | ||
265 | depends on LANTIQ | ||
266 | select MTD_PARTITIONS | ||
267 | help | ||
268 | Support for NOR flash attached to the Lantiq SoC's External Bus Unit. | ||
269 | |||
263 | config MTD_DILNETPC | 270 | config MTD_DILNETPC |
264 | tristate "CFI Flash device mapped on DIL/Net PC" | 271 | tristate "CFI Flash device mapped on DIL/Net PC" |
265 | depends on X86 && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN | 272 | depends on X86 && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN |
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 08533bd5cba7..6adf4c9b9057 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile | |||
@@ -60,3 +60,4 @@ obj-$(CONFIG_MTD_VMU) += vmu-flash.o | |||
60 | obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o | 60 | obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o |
61 | obj-$(CONFIG_MTD_BCM963XX) += bcm963xx-flash.o | 61 | obj-$(CONFIG_MTD_BCM963XX) += bcm963xx-flash.o |
62 | obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o | 62 | obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o |
63 | obj-$(CONFIG_MTD_LANTIQ) += lantiq-flash.o | ||
diff --git a/drivers/mtd/maps/lantiq-flash.c b/drivers/mtd/maps/lantiq-flash.c new file mode 100644 index 000000000000..a90cabd7b84d --- /dev/null +++ b/drivers/mtd/maps/lantiq-flash.c | |||
@@ -0,0 +1,251 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2004 Liu Peng Infineon IFAP DC COM CPE | ||
7 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/mtd/mtd.h> | ||
17 | #include <linux/mtd/map.h> | ||
18 | #include <linux/mtd/partitions.h> | ||
19 | #include <linux/mtd/cfi.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/mtd/physmap.h> | ||
22 | |||
23 | #include <lantiq_soc.h> | ||
24 | #include <lantiq_platform.h> | ||
25 | |||
26 | /* | ||
27 | * The NOR flash is connected to the same external bus unit (EBU) as PCI. | ||
28 | * To make PCI work we need to enable the endianness swapping for the address | ||
29 | * written to the EBU. This endianness swapping works for PCI correctly but | ||
30 | * fails for attached NOR devices. To workaround this we need to use a complex | ||
31 | * map. The workaround involves swapping all addresses whilst probing the chip. | ||
32 | * Once probing is complete we stop swapping the addresses but swizzle the | ||
33 | * unlock addresses to ensure that access to the NOR device works correctly. | ||
34 | */ | ||
35 | |||
36 | enum { | ||
37 | LTQ_NOR_PROBING, | ||
38 | LTQ_NOR_NORMAL | ||
39 | }; | ||
40 | |||
41 | struct ltq_mtd { | ||
42 | struct resource *res; | ||
43 | struct mtd_info *mtd; | ||
44 | struct map_info *map; | ||
45 | }; | ||
46 | |||
47 | static char ltq_map_name[] = "ltq_nor"; | ||
48 | |||
49 | static map_word | ||
50 | ltq_read16(struct map_info *map, unsigned long adr) | ||
51 | { | ||
52 | unsigned long flags; | ||
53 | map_word temp; | ||
54 | |||
55 | if (map->map_priv_1 == LTQ_NOR_PROBING) | ||
56 | adr ^= 2; | ||
57 | spin_lock_irqsave(&ebu_lock, flags); | ||
58 | temp.x[0] = *(u16 *)(map->virt + adr); | ||
59 | spin_unlock_irqrestore(&ebu_lock, flags); | ||
60 | return temp; | ||
61 | } | ||
62 | |||
63 | static void | ||
64 | ltq_write16(struct map_info *map, map_word d, unsigned long adr) | ||
65 | { | ||
66 | unsigned long flags; | ||
67 | |||
68 | if (map->map_priv_1 == LTQ_NOR_PROBING) | ||
69 | adr ^= 2; | ||
70 | spin_lock_irqsave(&ebu_lock, flags); | ||
71 | *(u16 *)(map->virt + adr) = d.x[0]; | ||
72 | spin_unlock_irqrestore(&ebu_lock, flags); | ||
73 | } | ||
74 | |||
75 | /* | ||
76 | * The following 2 functions copy data between iomem and a cached memory | ||
77 | * section. As memcpy() makes use of pre-fetching we cannot use it here. | ||
78 | * The normal alternative of using memcpy_{to,from}io also makes use of | ||
79 | * memcpy() on MIPS so it is not applicable either. We are therefore stuck | ||
80 | * with having to use our own loop. | ||
81 | */ | ||
82 | static void | ||
83 | ltq_copy_from(struct map_info *map, void *to, | ||
84 | unsigned long from, ssize_t len) | ||
85 | { | ||
86 | unsigned char *f = (unsigned char *)map->virt + from; | ||
87 | unsigned char *t = (unsigned char *)to; | ||
88 | unsigned long flags; | ||
89 | |||
90 | spin_lock_irqsave(&ebu_lock, flags); | ||
91 | while (len--) | ||
92 | *t++ = *f++; | ||
93 | spin_unlock_irqrestore(&ebu_lock, flags); | ||
94 | } | ||
95 | |||
96 | static void | ||
97 | ltq_copy_to(struct map_info *map, unsigned long to, | ||
98 | const void *from, ssize_t len) | ||
99 | { | ||
100 | unsigned char *f = (unsigned char *)from; | ||
101 | unsigned char *t = (unsigned char *)map->virt + to; | ||
102 | unsigned long flags; | ||
103 | |||
104 | spin_lock_irqsave(&ebu_lock, flags); | ||
105 | while (len--) | ||
106 | *t++ = *f++; | ||
107 | spin_unlock_irqrestore(&ebu_lock, flags); | ||
108 | } | ||
109 | |||
110 | static const char const *part_probe_types[] = { "cmdlinepart", NULL }; | ||
111 | |||
112 | static int __init | ||
113 | ltq_mtd_probe(struct platform_device *pdev) | ||
114 | { | ||
115 | struct physmap_flash_data *ltq_mtd_data = dev_get_platdata(&pdev->dev); | ||
116 | struct ltq_mtd *ltq_mtd; | ||
117 | struct mtd_partition *parts; | ||
118 | struct resource *res; | ||
119 | int nr_parts = 0; | ||
120 | struct cfi_private *cfi; | ||
121 | int err; | ||
122 | |||
123 | ltq_mtd = kzalloc(sizeof(struct ltq_mtd), GFP_KERNEL); | ||
124 | platform_set_drvdata(pdev, ltq_mtd); | ||
125 | |||
126 | ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
127 | if (!ltq_mtd->res) { | ||
128 | dev_err(&pdev->dev, "failed to get memory resource"); | ||
129 | err = -ENOENT; | ||
130 | goto err_out; | ||
131 | } | ||
132 | |||
133 | res = devm_request_mem_region(&pdev->dev, ltq_mtd->res->start, | ||
134 | resource_size(ltq_mtd->res), dev_name(&pdev->dev)); | ||
135 | if (!ltq_mtd->res) { | ||
136 | dev_err(&pdev->dev, "failed to request mem resource"); | ||
137 | err = -EBUSY; | ||
138 | goto err_out; | ||
139 | } | ||
140 | |||
141 | ltq_mtd->map = kzalloc(sizeof(struct map_info), GFP_KERNEL); | ||
142 | ltq_mtd->map->phys = res->start; | ||
143 | ltq_mtd->map->size = resource_size(res); | ||
144 | ltq_mtd->map->virt = devm_ioremap_nocache(&pdev->dev, | ||
145 | ltq_mtd->map->phys, ltq_mtd->map->size); | ||
146 | if (!ltq_mtd->map->virt) { | ||
147 | dev_err(&pdev->dev, "failed to ioremap!\n"); | ||
148 | err = -ENOMEM; | ||
149 | goto err_free; | ||
150 | } | ||
151 | |||
152 | ltq_mtd->map->name = ltq_map_name; | ||
153 | ltq_mtd->map->bankwidth = 2; | ||
154 | ltq_mtd->map->read = ltq_read16; | ||
155 | ltq_mtd->map->write = ltq_write16; | ||
156 | ltq_mtd->map->copy_from = ltq_copy_from; | ||
157 | ltq_mtd->map->copy_to = ltq_copy_to; | ||
158 | |||
159 | ltq_mtd->map->map_priv_1 = LTQ_NOR_PROBING; | ||
160 | ltq_mtd->mtd = do_map_probe("cfi_probe", ltq_mtd->map); | ||
161 | ltq_mtd->map->map_priv_1 = LTQ_NOR_NORMAL; | ||
162 | |||
163 | if (!ltq_mtd->mtd) { | ||
164 | dev_err(&pdev->dev, "probing failed\n"); | ||
165 | err = -ENXIO; | ||
166 | goto err_unmap; | ||
167 | } | ||
168 | |||
169 | ltq_mtd->mtd->owner = THIS_MODULE; | ||
170 | |||
171 | cfi = ltq_mtd->map->fldrv_priv; | ||
172 | cfi->addr_unlock1 ^= 1; | ||
173 | cfi->addr_unlock2 ^= 1; | ||
174 | |||
175 | nr_parts = parse_mtd_partitions(ltq_mtd->mtd, | ||
176 | part_probe_types, &parts, 0); | ||
177 | if (nr_parts > 0) { | ||
178 | dev_info(&pdev->dev, | ||
179 | "using %d partitions from cmdline", nr_parts); | ||
180 | } else { | ||
181 | nr_parts = ltq_mtd_data->nr_parts; | ||
182 | parts = ltq_mtd_data->parts; | ||
183 | } | ||
184 | |||
185 | err = add_mtd_partitions(ltq_mtd->mtd, parts, nr_parts); | ||
186 | if (err) { | ||
187 | dev_err(&pdev->dev, "failed to add partitions\n"); | ||
188 | goto err_destroy; | ||
189 | } | ||
190 | |||
191 | return 0; | ||
192 | |||
193 | err_destroy: | ||
194 | map_destroy(ltq_mtd->mtd); | ||
195 | err_unmap: | ||
196 | iounmap(ltq_mtd->map->virt); | ||
197 | err_free: | ||
198 | kfree(ltq_mtd->map); | ||
199 | err_out: | ||
200 | kfree(ltq_mtd); | ||
201 | return err; | ||
202 | } | ||
203 | |||
204 | static int __devexit | ||
205 | ltq_mtd_remove(struct platform_device *pdev) | ||
206 | { | ||
207 | struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev); | ||
208 | |||
209 | if (ltq_mtd) { | ||
210 | if (ltq_mtd->mtd) { | ||
211 | del_mtd_partitions(ltq_mtd->mtd); | ||
212 | map_destroy(ltq_mtd->mtd); | ||
213 | } | ||
214 | if (ltq_mtd->map->virt) | ||
215 | iounmap(ltq_mtd->map->virt); | ||
216 | kfree(ltq_mtd->map); | ||
217 | kfree(ltq_mtd); | ||
218 | } | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | static struct platform_driver ltq_mtd_driver = { | ||
223 | .remove = __devexit_p(ltq_mtd_remove), | ||
224 | .driver = { | ||
225 | .name = "ltq_nor", | ||
226 | .owner = THIS_MODULE, | ||
227 | }, | ||
228 | }; | ||
229 | |||
230 | static int __init | ||
231 | init_ltq_mtd(void) | ||
232 | { | ||
233 | int ret = platform_driver_probe(<q_mtd_driver, ltq_mtd_probe); | ||
234 | |||
235 | if (ret) | ||
236 | pr_err("ltq_nor: error registering platform driver"); | ||
237 | return ret; | ||
238 | } | ||
239 | |||
240 | static void __exit | ||
241 | exit_ltq_mtd(void) | ||
242 | { | ||
243 | platform_driver_unregister(<q_mtd_driver); | ||
244 | } | ||
245 | |||
246 | module_init(init_ltq_mtd); | ||
247 | module_exit(exit_ltq_mtd); | ||
248 | |||
249 | MODULE_LICENSE("GPL"); | ||
250 | MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); | ||
251 | MODULE_DESCRIPTION("Lantiq SoC NOR"); | ||
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 3ffe05db4923..5d513b54a7d7 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/gpio.h> | ||
13 | #include <linux/init.h> | 14 | #include <linux/init.h> |
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
@@ -470,7 +471,7 @@ static int __init au1xxx_nand_init(void) | |||
470 | 471 | ||
471 | #ifdef CONFIG_MIPS_PB1550 | 472 | #ifdef CONFIG_MIPS_PB1550 |
472 | /* set gpio206 high */ | 473 | /* set gpio206 high */ |
473 | au_writel(au_readl(GPIO2_DIR) & ~(1 << 6), GPIO2_DIR); | 474 | gpio_direction_input(206); |
474 | 475 | ||
475 | boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr_read(BCSR_STATUS) >> 6) & 0x1); | 476 | boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr_read(BCSR_STATUS) >> 6) & 0x1); |
476 | 477 | ||
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 6c884ef1b069..19f04a34783a 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -2017,6 +2017,13 @@ config FTMAC100 | |||
2017 | from Faraday. It is used on Faraday A320, Andes AG101 and some | 2017 | from Faraday. It is used on Faraday A320, Andes AG101 and some |
2018 | other ARM/NDS32 SoC's. | 2018 | other ARM/NDS32 SoC's. |
2019 | 2019 | ||
2020 | config LANTIQ_ETOP | ||
2021 | tristate "Lantiq SoC ETOP driver" | ||
2022 | depends on SOC_TYPE_XWAY | ||
2023 | help | ||
2024 | Support for the MII0 inside the Lantiq SoC | ||
2025 | |||
2026 | |||
2020 | source "drivers/net/fs_enet/Kconfig" | 2027 | source "drivers/net/fs_enet/Kconfig" |
2021 | 2028 | ||
2022 | source "drivers/net/octeon/Kconfig" | 2029 | source "drivers/net/octeon/Kconfig" |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index e5a7375685ad..209fbb70619b 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -259,6 +259,7 @@ obj-$(CONFIG_MLX4_CORE) += mlx4/ | |||
259 | obj-$(CONFIG_ENC28J60) += enc28j60.o | 259 | obj-$(CONFIG_ENC28J60) += enc28j60.o |
260 | obj-$(CONFIG_ETHOC) += ethoc.o | 260 | obj-$(CONFIG_ETHOC) += ethoc.o |
261 | obj-$(CONFIG_GRETH) += greth.o | 261 | obj-$(CONFIG_GRETH) += greth.o |
262 | obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o | ||
262 | 263 | ||
263 | obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o | 264 | obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o |
264 | 265 | ||
diff --git a/drivers/net/lantiq_etop.c b/drivers/net/lantiq_etop.c new file mode 100644 index 000000000000..45f252b7da30 --- /dev/null +++ b/drivers/net/lantiq_etop.c | |||
@@ -0,0 +1,805 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * You should have received a copy of the GNU General Public License | ||
12 | * along with this program; if not, write to the Free Software | ||
13 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
14 | * | ||
15 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/types.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/uaccess.h> | ||
24 | #include <linux/in.h> | ||
25 | #include <linux/netdevice.h> | ||
26 | #include <linux/etherdevice.h> | ||
27 | #include <linux/phy.h> | ||
28 | #include <linux/ip.h> | ||
29 | #include <linux/tcp.h> | ||
30 | #include <linux/skbuff.h> | ||
31 | #include <linux/mm.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | #include <linux/ethtool.h> | ||
34 | #include <linux/init.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/io.h> | ||
37 | |||
38 | #include <asm/checksum.h> | ||
39 | |||
40 | #include <lantiq_soc.h> | ||
41 | #include <xway_dma.h> | ||
42 | #include <lantiq_platform.h> | ||
43 | |||
44 | #define LTQ_ETOP_MDIO 0x11804 | ||
45 | #define MDIO_REQUEST 0x80000000 | ||
46 | #define MDIO_READ 0x40000000 | ||
47 | #define MDIO_ADDR_MASK 0x1f | ||
48 | #define MDIO_ADDR_OFFSET 0x15 | ||
49 | #define MDIO_REG_MASK 0x1f | ||
50 | #define MDIO_REG_OFFSET 0x10 | ||
51 | #define MDIO_VAL_MASK 0xffff | ||
52 | |||
53 | #define PPE32_CGEN 0x800 | ||
54 | #define LQ_PPE32_ENET_MAC_CFG 0x1840 | ||
55 | |||
56 | #define LTQ_ETOP_ENETS0 0x11850 | ||
57 | #define LTQ_ETOP_MAC_DA0 0x1186C | ||
58 | #define LTQ_ETOP_MAC_DA1 0x11870 | ||
59 | #define LTQ_ETOP_CFG 0x16020 | ||
60 | #define LTQ_ETOP_IGPLEN 0x16080 | ||
61 | |||
62 | #define MAX_DMA_CHAN 0x8 | ||
63 | #define MAX_DMA_CRC_LEN 0x4 | ||
64 | #define MAX_DMA_DATA_LEN 0x600 | ||
65 | |||
66 | #define ETOP_FTCU BIT(28) | ||
67 | #define ETOP_MII_MASK 0xf | ||
68 | #define ETOP_MII_NORMAL 0xd | ||
69 | #define ETOP_MII_REVERSE 0xe | ||
70 | #define ETOP_PLEN_UNDER 0x40 | ||
71 | #define ETOP_CGEN 0x800 | ||
72 | |||
73 | /* use 2 static channels for TX/RX */ | ||
74 | #define LTQ_ETOP_TX_CHANNEL 1 | ||
75 | #define LTQ_ETOP_RX_CHANNEL 6 | ||
76 | #define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL) | ||
77 | #define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL) | ||
78 | |||
79 | #define ltq_etop_r32(x) ltq_r32(ltq_etop_membase + (x)) | ||
80 | #define ltq_etop_w32(x, y) ltq_w32(x, ltq_etop_membase + (y)) | ||
81 | #define ltq_etop_w32_mask(x, y, z) \ | ||
82 | ltq_w32_mask(x, y, ltq_etop_membase + (z)) | ||
83 | |||
84 | #define DRV_VERSION "1.0" | ||
85 | |||
86 | static void __iomem *ltq_etop_membase; | ||
87 | |||
88 | struct ltq_etop_chan { | ||
89 | int idx; | ||
90 | int tx_free; | ||
91 | struct net_device *netdev; | ||
92 | struct napi_struct napi; | ||
93 | struct ltq_dma_channel dma; | ||
94 | struct sk_buff *skb[LTQ_DESC_NUM]; | ||
95 | }; | ||
96 | |||
97 | struct ltq_etop_priv { | ||
98 | struct net_device *netdev; | ||
99 | struct ltq_eth_data *pldata; | ||
100 | struct resource *res; | ||
101 | |||
102 | struct mii_bus *mii_bus; | ||
103 | struct phy_device *phydev; | ||
104 | |||
105 | struct ltq_etop_chan ch[MAX_DMA_CHAN]; | ||
106 | int tx_free[MAX_DMA_CHAN >> 1]; | ||
107 | |||
108 | spinlock_t lock; | ||
109 | }; | ||
110 | |||
111 | static int | ||
112 | ltq_etop_alloc_skb(struct ltq_etop_chan *ch) | ||
113 | { | ||
114 | ch->skb[ch->dma.desc] = dev_alloc_skb(MAX_DMA_DATA_LEN); | ||
115 | if (!ch->skb[ch->dma.desc]) | ||
116 | return -ENOMEM; | ||
117 | ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(NULL, | ||
118 | ch->skb[ch->dma.desc]->data, MAX_DMA_DATA_LEN, | ||
119 | DMA_FROM_DEVICE); | ||
120 | ch->dma.desc_base[ch->dma.desc].addr = | ||
121 | CPHYSADDR(ch->skb[ch->dma.desc]->data); | ||
122 | ch->dma.desc_base[ch->dma.desc].ctl = | ||
123 | LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) | | ||
124 | MAX_DMA_DATA_LEN; | ||
125 | skb_reserve(ch->skb[ch->dma.desc], NET_IP_ALIGN); | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static void | ||
130 | ltq_etop_hw_receive(struct ltq_etop_chan *ch) | ||
131 | { | ||
132 | struct ltq_etop_priv *priv = netdev_priv(ch->netdev); | ||
133 | struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc]; | ||
134 | struct sk_buff *skb = ch->skb[ch->dma.desc]; | ||
135 | int len = (desc->ctl & LTQ_DMA_SIZE_MASK) - MAX_DMA_CRC_LEN; | ||
136 | unsigned long flags; | ||
137 | |||
138 | spin_lock_irqsave(&priv->lock, flags); | ||
139 | if (ltq_etop_alloc_skb(ch)) { | ||
140 | netdev_err(ch->netdev, | ||
141 | "failed to allocate new rx buffer, stopping DMA\n"); | ||
142 | ltq_dma_close(&ch->dma); | ||
143 | } | ||
144 | ch->dma.desc++; | ||
145 | ch->dma.desc %= LTQ_DESC_NUM; | ||
146 | spin_unlock_irqrestore(&priv->lock, flags); | ||
147 | |||
148 | skb_put(skb, len); | ||
149 | skb->dev = ch->netdev; | ||
150 | skb->protocol = eth_type_trans(skb, ch->netdev); | ||
151 | netif_receive_skb(skb); | ||
152 | } | ||
153 | |||
154 | static int | ||
155 | ltq_etop_poll_rx(struct napi_struct *napi, int budget) | ||
156 | { | ||
157 | struct ltq_etop_chan *ch = container_of(napi, | ||
158 | struct ltq_etop_chan, napi); | ||
159 | int rx = 0; | ||
160 | int complete = 0; | ||
161 | |||
162 | while ((rx < budget) && !complete) { | ||
163 | struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc]; | ||
164 | |||
165 | if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) { | ||
166 | ltq_etop_hw_receive(ch); | ||
167 | rx++; | ||
168 | } else { | ||
169 | complete = 1; | ||
170 | } | ||
171 | } | ||
172 | if (complete || !rx) { | ||
173 | napi_complete(&ch->napi); | ||
174 | ltq_dma_ack_irq(&ch->dma); | ||
175 | } | ||
176 | return rx; | ||
177 | } | ||
178 | |||
179 | static int | ||
180 | ltq_etop_poll_tx(struct napi_struct *napi, int budget) | ||
181 | { | ||
182 | struct ltq_etop_chan *ch = | ||
183 | container_of(napi, struct ltq_etop_chan, napi); | ||
184 | struct ltq_etop_priv *priv = netdev_priv(ch->netdev); | ||
185 | struct netdev_queue *txq = | ||
186 | netdev_get_tx_queue(ch->netdev, ch->idx >> 1); | ||
187 | unsigned long flags; | ||
188 | |||
189 | spin_lock_irqsave(&priv->lock, flags); | ||
190 | while ((ch->dma.desc_base[ch->tx_free].ctl & | ||
191 | (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) { | ||
192 | dev_kfree_skb_any(ch->skb[ch->tx_free]); | ||
193 | ch->skb[ch->tx_free] = NULL; | ||
194 | memset(&ch->dma.desc_base[ch->tx_free], 0, | ||
195 | sizeof(struct ltq_dma_desc)); | ||
196 | ch->tx_free++; | ||
197 | ch->tx_free %= LTQ_DESC_NUM; | ||
198 | } | ||
199 | spin_unlock_irqrestore(&priv->lock, flags); | ||
200 | |||
201 | if (netif_tx_queue_stopped(txq)) | ||
202 | netif_tx_start_queue(txq); | ||
203 | napi_complete(&ch->napi); | ||
204 | ltq_dma_ack_irq(&ch->dma); | ||
205 | return 1; | ||
206 | } | ||
207 | |||
208 | static irqreturn_t | ||
209 | ltq_etop_dma_irq(int irq, void *_priv) | ||
210 | { | ||
211 | struct ltq_etop_priv *priv = _priv; | ||
212 | int ch = irq - LTQ_DMA_CH0_INT; | ||
213 | |||
214 | napi_schedule(&priv->ch[ch].napi); | ||
215 | return IRQ_HANDLED; | ||
216 | } | ||
217 | |||
218 | static void | ||
219 | ltq_etop_free_channel(struct net_device *dev, struct ltq_etop_chan *ch) | ||
220 | { | ||
221 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
222 | |||
223 | ltq_dma_free(&ch->dma); | ||
224 | if (ch->dma.irq) | ||
225 | free_irq(ch->dma.irq, priv); | ||
226 | if (IS_RX(ch->idx)) { | ||
227 | int desc; | ||
228 | for (desc = 0; desc < LTQ_DESC_NUM; desc++) | ||
229 | dev_kfree_skb_any(ch->skb[ch->dma.desc]); | ||
230 | } | ||
231 | } | ||
232 | |||
233 | static void | ||
234 | ltq_etop_hw_exit(struct net_device *dev) | ||
235 | { | ||
236 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
237 | int i; | ||
238 | |||
239 | ltq_pmu_disable(PMU_PPE); | ||
240 | for (i = 0; i < MAX_DMA_CHAN; i++) | ||
241 | if (IS_TX(i) || IS_RX(i)) | ||
242 | ltq_etop_free_channel(dev, &priv->ch[i]); | ||
243 | } | ||
244 | |||
245 | static int | ||
246 | ltq_etop_hw_init(struct net_device *dev) | ||
247 | { | ||
248 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
249 | int i; | ||
250 | |||
251 | ltq_pmu_enable(PMU_PPE); | ||
252 | |||
253 | switch (priv->pldata->mii_mode) { | ||
254 | case PHY_INTERFACE_MODE_RMII: | ||
255 | ltq_etop_w32_mask(ETOP_MII_MASK, | ||
256 | ETOP_MII_REVERSE, LTQ_ETOP_CFG); | ||
257 | break; | ||
258 | |||
259 | case PHY_INTERFACE_MODE_MII: | ||
260 | ltq_etop_w32_mask(ETOP_MII_MASK, | ||
261 | ETOP_MII_NORMAL, LTQ_ETOP_CFG); | ||
262 | break; | ||
263 | |||
264 | default: | ||
265 | netdev_err(dev, "unknown mii mode %d\n", | ||
266 | priv->pldata->mii_mode); | ||
267 | return -ENOTSUPP; | ||
268 | } | ||
269 | |||
270 | /* enable crc generation */ | ||
271 | ltq_etop_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG); | ||
272 | |||
273 | ltq_dma_init_port(DMA_PORT_ETOP); | ||
274 | |||
275 | for (i = 0; i < MAX_DMA_CHAN; i++) { | ||
276 | int irq = LTQ_DMA_CH0_INT + i; | ||
277 | struct ltq_etop_chan *ch = &priv->ch[i]; | ||
278 | |||
279 | ch->idx = ch->dma.nr = i; | ||
280 | |||
281 | if (IS_TX(i)) { | ||
282 | ltq_dma_alloc_tx(&ch->dma); | ||
283 | request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED, | ||
284 | "etop_tx", priv); | ||
285 | } else if (IS_RX(i)) { | ||
286 | ltq_dma_alloc_rx(&ch->dma); | ||
287 | for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM; | ||
288 | ch->dma.desc++) | ||
289 | if (ltq_etop_alloc_skb(ch)) | ||
290 | return -ENOMEM; | ||
291 | ch->dma.desc = 0; | ||
292 | request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED, | ||
293 | "etop_rx", priv); | ||
294 | } | ||
295 | ch->dma.irq = irq; | ||
296 | } | ||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | static void | ||
301 | ltq_etop_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | ||
302 | { | ||
303 | strcpy(info->driver, "Lantiq ETOP"); | ||
304 | strcpy(info->bus_info, "internal"); | ||
305 | strcpy(info->version, DRV_VERSION); | ||
306 | } | ||
307 | |||
308 | static int | ||
309 | ltq_etop_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
310 | { | ||
311 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
312 | |||
313 | return phy_ethtool_gset(priv->phydev, cmd); | ||
314 | } | ||
315 | |||
316 | static int | ||
317 | ltq_etop_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
318 | { | ||
319 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
320 | |||
321 | return phy_ethtool_sset(priv->phydev, cmd); | ||
322 | } | ||
323 | |||
324 | static int | ||
325 | ltq_etop_nway_reset(struct net_device *dev) | ||
326 | { | ||
327 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
328 | |||
329 | return phy_start_aneg(priv->phydev); | ||
330 | } | ||
331 | |||
332 | static const struct ethtool_ops ltq_etop_ethtool_ops = { | ||
333 | .get_drvinfo = ltq_etop_get_drvinfo, | ||
334 | .get_settings = ltq_etop_get_settings, | ||
335 | .set_settings = ltq_etop_set_settings, | ||
336 | .nway_reset = ltq_etop_nway_reset, | ||
337 | }; | ||
338 | |||
339 | static int | ||
340 | ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data) | ||
341 | { | ||
342 | u32 val = MDIO_REQUEST | | ||
343 | ((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) | | ||
344 | ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET) | | ||
345 | phy_data; | ||
346 | |||
347 | while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST) | ||
348 | ; | ||
349 | ltq_etop_w32(val, LTQ_ETOP_MDIO); | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static int | ||
354 | ltq_etop_mdio_rd(struct mii_bus *bus, int phy_addr, int phy_reg) | ||
355 | { | ||
356 | u32 val = MDIO_REQUEST | MDIO_READ | | ||
357 | ((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) | | ||
358 | ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET); | ||
359 | |||
360 | while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST) | ||
361 | ; | ||
362 | ltq_etop_w32(val, LTQ_ETOP_MDIO); | ||
363 | while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST) | ||
364 | ; | ||
365 | val = ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_VAL_MASK; | ||
366 | return val; | ||
367 | } | ||
368 | |||
369 | static void | ||
370 | ltq_etop_mdio_link(struct net_device *dev) | ||
371 | { | ||
372 | /* nothing to do */ | ||
373 | } | ||
374 | |||
375 | static int | ||
376 | ltq_etop_mdio_probe(struct net_device *dev) | ||
377 | { | ||
378 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
379 | struct phy_device *phydev = NULL; | ||
380 | int phy_addr; | ||
381 | |||
382 | for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { | ||
383 | if (priv->mii_bus->phy_map[phy_addr]) { | ||
384 | phydev = priv->mii_bus->phy_map[phy_addr]; | ||
385 | break; | ||
386 | } | ||
387 | } | ||
388 | |||
389 | if (!phydev) { | ||
390 | netdev_err(dev, "no PHY found\n"); | ||
391 | return -ENODEV; | ||
392 | } | ||
393 | |||
394 | phydev = phy_connect(dev, dev_name(&phydev->dev), <q_etop_mdio_link, | ||
395 | 0, priv->pldata->mii_mode); | ||
396 | |||
397 | if (IS_ERR(phydev)) { | ||
398 | netdev_err(dev, "Could not attach to PHY\n"); | ||
399 | return PTR_ERR(phydev); | ||
400 | } | ||
401 | |||
402 | phydev->supported &= (SUPPORTED_10baseT_Half | ||
403 | | SUPPORTED_10baseT_Full | ||
404 | | SUPPORTED_100baseT_Half | ||
405 | | SUPPORTED_100baseT_Full | ||
406 | | SUPPORTED_Autoneg | ||
407 | | SUPPORTED_MII | ||
408 | | SUPPORTED_TP); | ||
409 | |||
410 | phydev->advertising = phydev->supported; | ||
411 | priv->phydev = phydev; | ||
412 | pr_info("%s: attached PHY [%s] (phy_addr=%s, irq=%d)\n", | ||
413 | dev->name, phydev->drv->name, | ||
414 | dev_name(&phydev->dev), phydev->irq); | ||
415 | |||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | static int | ||
420 | ltq_etop_mdio_init(struct net_device *dev) | ||
421 | { | ||
422 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
423 | int i; | ||
424 | int err; | ||
425 | |||
426 | priv->mii_bus = mdiobus_alloc(); | ||
427 | if (!priv->mii_bus) { | ||
428 | netdev_err(dev, "failed to allocate mii bus\n"); | ||
429 | err = -ENOMEM; | ||
430 | goto err_out; | ||
431 | } | ||
432 | |||
433 | priv->mii_bus->priv = dev; | ||
434 | priv->mii_bus->read = ltq_etop_mdio_rd; | ||
435 | priv->mii_bus->write = ltq_etop_mdio_wr; | ||
436 | priv->mii_bus->name = "ltq_mii"; | ||
437 | snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0); | ||
438 | priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); | ||
439 | if (!priv->mii_bus->irq) { | ||
440 | err = -ENOMEM; | ||
441 | goto err_out_free_mdiobus; | ||
442 | } | ||
443 | |||
444 | for (i = 0; i < PHY_MAX_ADDR; ++i) | ||
445 | priv->mii_bus->irq[i] = PHY_POLL; | ||
446 | |||
447 | if (mdiobus_register(priv->mii_bus)) { | ||
448 | err = -ENXIO; | ||
449 | goto err_out_free_mdio_irq; | ||
450 | } | ||
451 | |||
452 | if (ltq_etop_mdio_probe(dev)) { | ||
453 | err = -ENXIO; | ||
454 | goto err_out_unregister_bus; | ||
455 | } | ||
456 | return 0; | ||
457 | |||
458 | err_out_unregister_bus: | ||
459 | mdiobus_unregister(priv->mii_bus); | ||
460 | err_out_free_mdio_irq: | ||
461 | kfree(priv->mii_bus->irq); | ||
462 | err_out_free_mdiobus: | ||
463 | mdiobus_free(priv->mii_bus); | ||
464 | err_out: | ||
465 | return err; | ||
466 | } | ||
467 | |||
468 | static void | ||
469 | ltq_etop_mdio_cleanup(struct net_device *dev) | ||
470 | { | ||
471 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
472 | |||
473 | phy_disconnect(priv->phydev); | ||
474 | mdiobus_unregister(priv->mii_bus); | ||
475 | kfree(priv->mii_bus->irq); | ||
476 | mdiobus_free(priv->mii_bus); | ||
477 | } | ||
478 | |||
479 | static int | ||
480 | ltq_etop_open(struct net_device *dev) | ||
481 | { | ||
482 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
483 | int i; | ||
484 | |||
485 | for (i = 0; i < MAX_DMA_CHAN; i++) { | ||
486 | struct ltq_etop_chan *ch = &priv->ch[i]; | ||
487 | |||
488 | if (!IS_TX(i) && (!IS_RX(i))) | ||
489 | continue; | ||
490 | ltq_dma_open(&ch->dma); | ||
491 | napi_enable(&ch->napi); | ||
492 | } | ||
493 | phy_start(priv->phydev); | ||
494 | netif_tx_start_all_queues(dev); | ||
495 | return 0; | ||
496 | } | ||
497 | |||
498 | static int | ||
499 | ltq_etop_stop(struct net_device *dev) | ||
500 | { | ||
501 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
502 | int i; | ||
503 | |||
504 | netif_tx_stop_all_queues(dev); | ||
505 | phy_stop(priv->phydev); | ||
506 | for (i = 0; i < MAX_DMA_CHAN; i++) { | ||
507 | struct ltq_etop_chan *ch = &priv->ch[i]; | ||
508 | |||
509 | if (!IS_RX(i) && !IS_TX(i)) | ||
510 | continue; | ||
511 | napi_disable(&ch->napi); | ||
512 | ltq_dma_close(&ch->dma); | ||
513 | } | ||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | static int | ||
518 | ltq_etop_tx(struct sk_buff *skb, struct net_device *dev) | ||
519 | { | ||
520 | int queue = skb_get_queue_mapping(skb); | ||
521 | struct netdev_queue *txq = netdev_get_tx_queue(dev, queue); | ||
522 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
523 | struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1]; | ||
524 | struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc]; | ||
525 | int len; | ||
526 | unsigned long flags; | ||
527 | u32 byte_offset; | ||
528 | |||
529 | len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; | ||
530 | |||
531 | if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) { | ||
532 | dev_kfree_skb_any(skb); | ||
533 | netdev_err(dev, "tx ring full\n"); | ||
534 | netif_tx_stop_queue(txq); | ||
535 | return NETDEV_TX_BUSY; | ||
536 | } | ||
537 | |||
538 | /* dma needs to start on a 16 byte aligned address */ | ||
539 | byte_offset = CPHYSADDR(skb->data) % 16; | ||
540 | ch->skb[ch->dma.desc] = skb; | ||
541 | |||
542 | dev->trans_start = jiffies; | ||
543 | |||
544 | spin_lock_irqsave(&priv->lock, flags); | ||
545 | desc->addr = ((unsigned int) dma_map_single(NULL, skb->data, len, | ||
546 | DMA_TO_DEVICE)) - byte_offset; | ||
547 | wmb(); | ||
548 | desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP | | ||
549 | LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK); | ||
550 | ch->dma.desc++; | ||
551 | ch->dma.desc %= LTQ_DESC_NUM; | ||
552 | spin_unlock_irqrestore(&priv->lock, flags); | ||
553 | |||
554 | if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN) | ||
555 | netif_tx_stop_queue(txq); | ||
556 | |||
557 | return NETDEV_TX_OK; | ||
558 | } | ||
559 | |||
560 | static int | ||
561 | ltq_etop_change_mtu(struct net_device *dev, int new_mtu) | ||
562 | { | ||
563 | int ret = eth_change_mtu(dev, new_mtu); | ||
564 | |||
565 | if (!ret) { | ||
566 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
567 | unsigned long flags; | ||
568 | |||
569 | spin_lock_irqsave(&priv->lock, flags); | ||
570 | ltq_etop_w32((ETOP_PLEN_UNDER << 16) | new_mtu, | ||
571 | LTQ_ETOP_IGPLEN); | ||
572 | spin_unlock_irqrestore(&priv->lock, flags); | ||
573 | } | ||
574 | return ret; | ||
575 | } | ||
576 | |||
577 | static int | ||
578 | ltq_etop_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | ||
579 | { | ||
580 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
581 | |||
582 | /* TODO: mii-toll reports "No MII transceiver present!." ?!*/ | ||
583 | return phy_mii_ioctl(priv->phydev, rq, cmd); | ||
584 | } | ||
585 | |||
586 | static int | ||
587 | ltq_etop_set_mac_address(struct net_device *dev, void *p) | ||
588 | { | ||
589 | int ret = eth_mac_addr(dev, p); | ||
590 | |||
591 | if (!ret) { | ||
592 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
593 | unsigned long flags; | ||
594 | |||
595 | /* store the mac for the unicast filter */ | ||
596 | spin_lock_irqsave(&priv->lock, flags); | ||
597 | ltq_etop_w32(*((u32 *)dev->dev_addr), LTQ_ETOP_MAC_DA0); | ||
598 | ltq_etop_w32(*((u16 *)&dev->dev_addr[4]) << 16, | ||
599 | LTQ_ETOP_MAC_DA1); | ||
600 | spin_unlock_irqrestore(&priv->lock, flags); | ||
601 | } | ||
602 | return ret; | ||
603 | } | ||
604 | |||
605 | static void | ||
606 | ltq_etop_set_multicast_list(struct net_device *dev) | ||
607 | { | ||
608 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
609 | unsigned long flags; | ||
610 | |||
611 | /* ensure that the unicast filter is not enabled in promiscious mode */ | ||
612 | spin_lock_irqsave(&priv->lock, flags); | ||
613 | if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI)) | ||
614 | ltq_etop_w32_mask(ETOP_FTCU, 0, LTQ_ETOP_ENETS0); | ||
615 | else | ||
616 | ltq_etop_w32_mask(0, ETOP_FTCU, LTQ_ETOP_ENETS0); | ||
617 | spin_unlock_irqrestore(&priv->lock, flags); | ||
618 | } | ||
619 | |||
620 | static u16 | ||
621 | ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb) | ||
622 | { | ||
623 | /* we are currently only using the first queue */ | ||
624 | return 0; | ||
625 | } | ||
626 | |||
627 | static int | ||
628 | ltq_etop_init(struct net_device *dev) | ||
629 | { | ||
630 | struct ltq_etop_priv *priv = netdev_priv(dev); | ||
631 | struct sockaddr mac; | ||
632 | int err; | ||
633 | |||
634 | ether_setup(dev); | ||
635 | dev->watchdog_timeo = 10 * HZ; | ||
636 | err = ltq_etop_hw_init(dev); | ||
637 | if (err) | ||
638 | goto err_hw; | ||
639 | ltq_etop_change_mtu(dev, 1500); | ||
640 | |||
641 | memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr)); | ||
642 | if (!is_valid_ether_addr(mac.sa_data)) { | ||
643 | pr_warn("etop: invalid MAC, using random\n"); | ||
644 | random_ether_addr(mac.sa_data); | ||
645 | } | ||
646 | |||
647 | err = ltq_etop_set_mac_address(dev, &mac); | ||
648 | if (err) | ||
649 | goto err_netdev; | ||
650 | ltq_etop_set_multicast_list(dev); | ||
651 | err = ltq_etop_mdio_init(dev); | ||
652 | if (err) | ||
653 | goto err_netdev; | ||
654 | return 0; | ||
655 | |||
656 | err_netdev: | ||
657 | unregister_netdev(dev); | ||
658 | free_netdev(dev); | ||
659 | err_hw: | ||
660 | ltq_etop_hw_exit(dev); | ||
661 | return err; | ||
662 | } | ||
663 | |||
664 | static void | ||
665 | ltq_etop_tx_timeout(struct net_device *dev) | ||
666 | { | ||
667 | int err; | ||
668 | |||
669 | ltq_etop_hw_exit(dev); | ||
670 | err = ltq_etop_hw_init(dev); | ||
671 | if (err) | ||
672 | goto err_hw; | ||
673 | dev->trans_start = jiffies; | ||
674 | netif_wake_queue(dev); | ||
675 | return; | ||
676 | |||
677 | err_hw: | ||
678 | ltq_etop_hw_exit(dev); | ||
679 | netdev_err(dev, "failed to restart etop after TX timeout\n"); | ||
680 | } | ||
681 | |||
682 | static const struct net_device_ops ltq_eth_netdev_ops = { | ||
683 | .ndo_open = ltq_etop_open, | ||
684 | .ndo_stop = ltq_etop_stop, | ||
685 | .ndo_start_xmit = ltq_etop_tx, | ||
686 | .ndo_change_mtu = ltq_etop_change_mtu, | ||
687 | .ndo_do_ioctl = ltq_etop_ioctl, | ||
688 | .ndo_set_mac_address = ltq_etop_set_mac_address, | ||
689 | .ndo_validate_addr = eth_validate_addr, | ||
690 | .ndo_set_multicast_list = ltq_etop_set_multicast_list, | ||
691 | .ndo_select_queue = ltq_etop_select_queue, | ||
692 | .ndo_init = ltq_etop_init, | ||
693 | .ndo_tx_timeout = ltq_etop_tx_timeout, | ||
694 | }; | ||
695 | |||
696 | static int __init | ||
697 | ltq_etop_probe(struct platform_device *pdev) | ||
698 | { | ||
699 | struct net_device *dev; | ||
700 | struct ltq_etop_priv *priv; | ||
701 | struct resource *res; | ||
702 | int err; | ||
703 | int i; | ||
704 | |||
705 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
706 | if (!res) { | ||
707 | dev_err(&pdev->dev, "failed to get etop resource\n"); | ||
708 | err = -ENOENT; | ||
709 | goto err_out; | ||
710 | } | ||
711 | |||
712 | res = devm_request_mem_region(&pdev->dev, res->start, | ||
713 | resource_size(res), dev_name(&pdev->dev)); | ||
714 | if (!res) { | ||
715 | dev_err(&pdev->dev, "failed to request etop resource\n"); | ||
716 | err = -EBUSY; | ||
717 | goto err_out; | ||
718 | } | ||
719 | |||
720 | ltq_etop_membase = devm_ioremap_nocache(&pdev->dev, | ||
721 | res->start, resource_size(res)); | ||
722 | if (!ltq_etop_membase) { | ||
723 | dev_err(&pdev->dev, "failed to remap etop engine %d\n", | ||
724 | pdev->id); | ||
725 | err = -ENOMEM; | ||
726 | goto err_out; | ||
727 | } | ||
728 | |||
729 | dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4); | ||
730 | strcpy(dev->name, "eth%d"); | ||
731 | dev->netdev_ops = <q_eth_netdev_ops; | ||
732 | dev->ethtool_ops = <q_etop_ethtool_ops; | ||
733 | priv = netdev_priv(dev); | ||
734 | priv->res = res; | ||
735 | priv->pldata = dev_get_platdata(&pdev->dev); | ||
736 | priv->netdev = dev; | ||
737 | spin_lock_init(&priv->lock); | ||
738 | |||
739 | for (i = 0; i < MAX_DMA_CHAN; i++) { | ||
740 | if (IS_TX(i)) | ||
741 | netif_napi_add(dev, &priv->ch[i].napi, | ||
742 | ltq_etop_poll_tx, 8); | ||
743 | else if (IS_RX(i)) | ||
744 | netif_napi_add(dev, &priv->ch[i].napi, | ||
745 | ltq_etop_poll_rx, 32); | ||
746 | priv->ch[i].netdev = dev; | ||
747 | } | ||
748 | |||
749 | err = register_netdev(dev); | ||
750 | if (err) | ||
751 | goto err_free; | ||
752 | |||
753 | platform_set_drvdata(pdev, dev); | ||
754 | return 0; | ||
755 | |||
756 | err_free: | ||
757 | kfree(dev); | ||
758 | err_out: | ||
759 | return err; | ||
760 | } | ||
761 | |||
762 | static int __devexit | ||
763 | ltq_etop_remove(struct platform_device *pdev) | ||
764 | { | ||
765 | struct net_device *dev = platform_get_drvdata(pdev); | ||
766 | |||
767 | if (dev) { | ||
768 | netif_tx_stop_all_queues(dev); | ||
769 | ltq_etop_hw_exit(dev); | ||
770 | ltq_etop_mdio_cleanup(dev); | ||
771 | unregister_netdev(dev); | ||
772 | } | ||
773 | return 0; | ||
774 | } | ||
775 | |||
776 | static struct platform_driver ltq_mii_driver = { | ||
777 | .remove = __devexit_p(ltq_etop_remove), | ||
778 | .driver = { | ||
779 | .name = "ltq_etop", | ||
780 | .owner = THIS_MODULE, | ||
781 | }, | ||
782 | }; | ||
783 | |||
784 | int __init | ||
785 | init_ltq_etop(void) | ||
786 | { | ||
787 | int ret = platform_driver_probe(<q_mii_driver, ltq_etop_probe); | ||
788 | |||
789 | if (ret) | ||
790 | pr_err("ltq_etop: Error registering platfom driver!"); | ||
791 | return ret; | ||
792 | } | ||
793 | |||
794 | static void __exit | ||
795 | exit_ltq_etop(void) | ||
796 | { | ||
797 | platform_driver_unregister(<q_mii_driver); | ||
798 | } | ||
799 | |||
800 | module_init(init_ltq_etop); | ||
801 | module_exit(exit_ltq_etop); | ||
802 | |||
803 | MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); | ||
804 | MODULE_DESCRIPTION("Lantiq SoC ETOP"); | ||
805 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 6f34963b3c64..7ad48585c5e6 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c | |||
@@ -662,7 +662,6 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, | |||
662 | static int ssb_pci_sprom_get(struct ssb_bus *bus, | 662 | static int ssb_pci_sprom_get(struct ssb_bus *bus, |
663 | struct ssb_sprom *sprom) | 663 | struct ssb_sprom *sprom) |
664 | { | 664 | { |
665 | const struct ssb_sprom *fallback; | ||
666 | int err; | 665 | int err; |
667 | u16 *buf; | 666 | u16 *buf; |
668 | 667 | ||
@@ -707,10 +706,17 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, | |||
707 | if (err) { | 706 | if (err) { |
708 | /* All CRC attempts failed. | 707 | /* All CRC attempts failed. |
709 | * Maybe there is no SPROM on the device? | 708 | * Maybe there is no SPROM on the device? |
710 | * If we have a fallback, use that. */ | 709 | * Now we ask the arch code if there is some sprom |
711 | fallback = ssb_get_fallback_sprom(); | 710 | * available for this device in some other storage */ |
712 | if (fallback) { | 711 | err = ssb_fill_sprom_with_fallback(bus, sprom); |
713 | memcpy(sprom, fallback, sizeof(*sprom)); | 712 | if (err) { |
713 | ssb_printk(KERN_WARNING PFX "WARNING: Using" | ||
714 | " fallback SPROM failed (err %d)\n", | ||
715 | err); | ||
716 | } else { | ||
717 | ssb_dprintk(KERN_DEBUG PFX "Using SPROM" | ||
718 | " revision %d provided by" | ||
719 | " platform.\n", sprom->revision); | ||
714 | err = 0; | 720 | err = 0; |
715 | goto out_free; | 721 | goto out_free; |
716 | } | 722 | } |
diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c index 5f34d7a3e3a5..45ff0e3a3828 100644 --- a/drivers/ssb/sprom.c +++ b/drivers/ssb/sprom.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | 18 | ||
19 | 19 | ||
20 | static const struct ssb_sprom *fallback_sprom; | 20 | static int(*get_fallback_sprom)(struct ssb_bus *dev, struct ssb_sprom *out); |
21 | 21 | ||
22 | 22 | ||
23 | static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len, | 23 | static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len, |
@@ -145,36 +145,43 @@ out: | |||
145 | } | 145 | } |
146 | 146 | ||
147 | /** | 147 | /** |
148 | * ssb_arch_set_fallback_sprom - Set a fallback SPROM for use if no SPROM is found. | 148 | * ssb_arch_register_fallback_sprom - Registers a method providing a |
149 | * fallback SPROM if no SPROM is found. | ||
149 | * | 150 | * |
150 | * @sprom: The SPROM data structure to register. | 151 | * @sprom_callback: The callback function. |
151 | * | 152 | * |
152 | * With this function the architecture implementation may register a fallback | 153 | * With this function the architecture implementation may register a |
153 | * SPROM data structure. The fallback is only used for PCI based SSB devices, | 154 | * callback handler which fills the SPROM data structure. The fallback is |
154 | * where no valid SPROM can be found in the shadow registers. | 155 | * only used for PCI based SSB devices, where no valid SPROM can be found |
156 | * in the shadow registers. | ||
155 | * | 157 | * |
156 | * This function is useful for weird architectures that have a half-assed SSB device | 158 | * This function is useful for weird architectures that have a half-assed |
157 | * hardwired to their PCI bus. | 159 | * SSB device hardwired to their PCI bus. |
158 | * | 160 | * |
159 | * Note that it does only work with PCI attached SSB devices. PCMCIA devices currently | 161 | * Note that it does only work with PCI attached SSB devices. PCMCIA |
160 | * don't use this fallback. | 162 | * devices currently don't use this fallback. |
161 | * Architectures must provide the SPROM for native SSB devices anyway, | 163 | * Architectures must provide the SPROM for native SSB devices anyway, so |
162 | * so the fallback also isn't used for native devices. | 164 | * the fallback also isn't used for native devices. |
163 | * | 165 | * |
164 | * This function is available for architecture code, only. So it is not exported. | 166 | * This function is available for architecture code, only. So it is not |
167 | * exported. | ||
165 | */ | 168 | */ |
166 | int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom) | 169 | int ssb_arch_register_fallback_sprom(int (*sprom_callback)(struct ssb_bus *bus, |
170 | struct ssb_sprom *out)) | ||
167 | { | 171 | { |
168 | if (fallback_sprom) | 172 | if (get_fallback_sprom) |
169 | return -EEXIST; | 173 | return -EEXIST; |
170 | fallback_sprom = sprom; | 174 | get_fallback_sprom = sprom_callback; |
171 | 175 | ||
172 | return 0; | 176 | return 0; |
173 | } | 177 | } |
174 | 178 | ||
175 | const struct ssb_sprom *ssb_get_fallback_sprom(void) | 179 | int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out) |
176 | { | 180 | { |
177 | return fallback_sprom; | 181 | if (!get_fallback_sprom) |
182 | return -ENOENT; | ||
183 | |||
184 | return get_fallback_sprom(bus, out); | ||
178 | } | 185 | } |
179 | 186 | ||
180 | /* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */ | 187 | /* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */ |
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h index 0331139a726f..77653014db0b 100644 --- a/drivers/ssb/ssb_private.h +++ b/drivers/ssb/ssb_private.h | |||
@@ -171,7 +171,8 @@ ssize_t ssb_attr_sprom_store(struct ssb_bus *bus, | |||
171 | const char *buf, size_t count, | 171 | const char *buf, size_t count, |
172 | int (*sprom_check_crc)(const u16 *sprom, size_t size), | 172 | int (*sprom_check_crc)(const u16 *sprom, size_t size), |
173 | int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom)); | 173 | int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom)); |
174 | extern const struct ssb_sprom *ssb_get_fallback_sprom(void); | 174 | extern int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, |
175 | struct ssb_sprom *out); | ||
175 | 176 | ||
176 | 177 | ||
177 | /* core.c */ | 178 | /* core.c */ |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 80484af781e1..b1f0f83b870d 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -1391,6 +1391,14 @@ config SERIAL_OF_PLATFORM_NWPSERIAL_CONSOLE | |||
1391 | help | 1391 | help |
1392 | Support for Console on the NWP serial ports. | 1392 | Support for Console on the NWP serial ports. |
1393 | 1393 | ||
1394 | config SERIAL_LANTIQ | ||
1395 | bool "Lantiq serial driver" | ||
1396 | depends on LANTIQ | ||
1397 | select SERIAL_CORE | ||
1398 | select SERIAL_CORE_CONSOLE | ||
1399 | help | ||
1400 | Support for console and UART on Lantiq SoCs. | ||
1401 | |||
1394 | config SERIAL_QE | 1402 | config SERIAL_QE |
1395 | tristate "Freescale QUICC Engine serial port support" | 1403 | tristate "Freescale QUICC Engine serial port support" |
1396 | depends on QUICC_ENGINE | 1404 | depends on QUICC_ENGINE |
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index fee0690ef8e3..35276043d9d1 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -94,3 +94,4 @@ obj-$(CONFIG_SERIAL_IFX6X60) += ifx6x60.o | |||
94 | obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o | 94 | obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o |
95 | obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o | 95 | obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o |
96 | obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o | 96 | obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o |
97 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o | ||
diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c new file mode 100644 index 000000000000..58cf279ed879 --- /dev/null +++ b/drivers/tty/serial/lantiq.c | |||
@@ -0,0 +1,756 @@ | |||
1 | /* | ||
2 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License version 2 as published | ||
6 | * by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
16 | * | ||
17 | * Copyright (C) 2004 Infineon IFAP DC COM CPE | ||
18 | * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org> | ||
19 | * Copyright (C) 2007 John Crispin <blogic@openwrt.org> | ||
20 | * Copyright (C) 2010 Thomas Langer, <thomas.langer@lantiq.com> | ||
21 | */ | ||
22 | |||
23 | #include <linux/slab.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/ioport.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/console.h> | ||
28 | #include <linux/sysrq.h> | ||
29 | #include <linux/device.h> | ||
30 | #include <linux/tty.h> | ||
31 | #include <linux/tty_flip.h> | ||
32 | #include <linux/serial_core.h> | ||
33 | #include <linux/serial.h> | ||
34 | #include <linux/platform_device.h> | ||
35 | #include <linux/io.h> | ||
36 | #include <linux/clk.h> | ||
37 | |||
38 | #include <lantiq_soc.h> | ||
39 | |||
40 | #define PORT_LTQ_ASC 111 | ||
41 | #define MAXPORTS 2 | ||
42 | #define UART_DUMMY_UER_RX 1 | ||
43 | #define DRVNAME "ltq_asc" | ||
44 | #ifdef __BIG_ENDIAN | ||
45 | #define LTQ_ASC_TBUF (0x0020 + 3) | ||
46 | #define LTQ_ASC_RBUF (0x0024 + 3) | ||
47 | #else | ||
48 | #define LTQ_ASC_TBUF 0x0020 | ||
49 | #define LTQ_ASC_RBUF 0x0024 | ||
50 | #endif | ||
51 | #define LTQ_ASC_FSTAT 0x0048 | ||
52 | #define LTQ_ASC_WHBSTATE 0x0018 | ||
53 | #define LTQ_ASC_STATE 0x0014 | ||
54 | #define LTQ_ASC_IRNCR 0x00F8 | ||
55 | #define LTQ_ASC_CLC 0x0000 | ||
56 | #define LTQ_ASC_ID 0x0008 | ||
57 | #define LTQ_ASC_PISEL 0x0004 | ||
58 | #define LTQ_ASC_TXFCON 0x0044 | ||
59 | #define LTQ_ASC_RXFCON 0x0040 | ||
60 | #define LTQ_ASC_CON 0x0010 | ||
61 | #define LTQ_ASC_BG 0x0050 | ||
62 | #define LTQ_ASC_IRNREN 0x00F4 | ||
63 | |||
64 | #define ASC_IRNREN_TX 0x1 | ||
65 | #define ASC_IRNREN_RX 0x2 | ||
66 | #define ASC_IRNREN_ERR 0x4 | ||
67 | #define ASC_IRNREN_TX_BUF 0x8 | ||
68 | #define ASC_IRNCR_TIR 0x1 | ||
69 | #define ASC_IRNCR_RIR 0x2 | ||
70 | #define ASC_IRNCR_EIR 0x4 | ||
71 | |||
72 | #define ASCOPT_CSIZE 0x3 | ||
73 | #define TXFIFO_FL 1 | ||
74 | #define RXFIFO_FL 1 | ||
75 | #define ASCCLC_DISS 0x2 | ||
76 | #define ASCCLC_RMCMASK 0x0000FF00 | ||
77 | #define ASCCLC_RMCOFFSET 8 | ||
78 | #define ASCCON_M_8ASYNC 0x0 | ||
79 | #define ASCCON_M_7ASYNC 0x2 | ||
80 | #define ASCCON_ODD 0x00000020 | ||
81 | #define ASCCON_STP 0x00000080 | ||
82 | #define ASCCON_BRS 0x00000100 | ||
83 | #define ASCCON_FDE 0x00000200 | ||
84 | #define ASCCON_R 0x00008000 | ||
85 | #define ASCCON_FEN 0x00020000 | ||
86 | #define ASCCON_ROEN 0x00080000 | ||
87 | #define ASCCON_TOEN 0x00100000 | ||
88 | #define ASCSTATE_PE 0x00010000 | ||
89 | #define ASCSTATE_FE 0x00020000 | ||
90 | #define ASCSTATE_ROE 0x00080000 | ||
91 | #define ASCSTATE_ANY (ASCSTATE_ROE|ASCSTATE_PE|ASCSTATE_FE) | ||
92 | #define ASCWHBSTATE_CLRREN 0x00000001 | ||
93 | #define ASCWHBSTATE_SETREN 0x00000002 | ||
94 | #define ASCWHBSTATE_CLRPE 0x00000004 | ||
95 | #define ASCWHBSTATE_CLRFE 0x00000008 | ||
96 | #define ASCWHBSTATE_CLRROE 0x00000020 | ||
97 | #define ASCTXFCON_TXFEN 0x0001 | ||
98 | #define ASCTXFCON_TXFFLU 0x0002 | ||
99 | #define ASCTXFCON_TXFITLMASK 0x3F00 | ||
100 | #define ASCTXFCON_TXFITLOFF 8 | ||
101 | #define ASCRXFCON_RXFEN 0x0001 | ||
102 | #define ASCRXFCON_RXFFLU 0x0002 | ||
103 | #define ASCRXFCON_RXFITLMASK 0x3F00 | ||
104 | #define ASCRXFCON_RXFITLOFF 8 | ||
105 | #define ASCFSTAT_RXFFLMASK 0x003F | ||
106 | #define ASCFSTAT_TXFFLMASK 0x3F00 | ||
107 | #define ASCFSTAT_TXFREEMASK 0x3F000000 | ||
108 | #define ASCFSTAT_TXFREEOFF 24 | ||
109 | |||
110 | static void lqasc_tx_chars(struct uart_port *port); | ||
111 | static struct ltq_uart_port *lqasc_port[MAXPORTS]; | ||
112 | static struct uart_driver lqasc_reg; | ||
113 | static DEFINE_SPINLOCK(ltq_asc_lock); | ||
114 | |||
115 | struct ltq_uart_port { | ||
116 | struct uart_port port; | ||
117 | struct clk *clk; | ||
118 | unsigned int tx_irq; | ||
119 | unsigned int rx_irq; | ||
120 | unsigned int err_irq; | ||
121 | }; | ||
122 | |||
123 | static inline struct | ||
124 | ltq_uart_port *to_ltq_uart_port(struct uart_port *port) | ||
125 | { | ||
126 | return container_of(port, struct ltq_uart_port, port); | ||
127 | } | ||
128 | |||
129 | static void | ||
130 | lqasc_stop_tx(struct uart_port *port) | ||
131 | { | ||
132 | return; | ||
133 | } | ||
134 | |||
135 | static void | ||
136 | lqasc_start_tx(struct uart_port *port) | ||
137 | { | ||
138 | unsigned long flags; | ||
139 | spin_lock_irqsave(<q_asc_lock, flags); | ||
140 | lqasc_tx_chars(port); | ||
141 | spin_unlock_irqrestore(<q_asc_lock, flags); | ||
142 | return; | ||
143 | } | ||
144 | |||
145 | static void | ||
146 | lqasc_stop_rx(struct uart_port *port) | ||
147 | { | ||
148 | ltq_w32(ASCWHBSTATE_CLRREN, port->membase + LTQ_ASC_WHBSTATE); | ||
149 | } | ||
150 | |||
151 | static void | ||
152 | lqasc_enable_ms(struct uart_port *port) | ||
153 | { | ||
154 | } | ||
155 | |||
156 | static int | ||
157 | lqasc_rx_chars(struct uart_port *port) | ||
158 | { | ||
159 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
160 | unsigned int ch = 0, rsr = 0, fifocnt; | ||
161 | |||
162 | if (!tty) { | ||
163 | dev_dbg(port->dev, "%s:tty is busy now", __func__); | ||
164 | return -EBUSY; | ||
165 | } | ||
166 | fifocnt = | ||
167 | ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK; | ||
168 | while (fifocnt--) { | ||
169 | u8 flag = TTY_NORMAL; | ||
170 | ch = ltq_r8(port->membase + LTQ_ASC_RBUF); | ||
171 | rsr = (ltq_r32(port->membase + LTQ_ASC_STATE) | ||
172 | & ASCSTATE_ANY) | UART_DUMMY_UER_RX; | ||
173 | tty_flip_buffer_push(tty); | ||
174 | port->icount.rx++; | ||
175 | |||
176 | /* | ||
177 | * Note that the error handling code is | ||
178 | * out of the main execution path | ||
179 | */ | ||
180 | if (rsr & ASCSTATE_ANY) { | ||
181 | if (rsr & ASCSTATE_PE) { | ||
182 | port->icount.parity++; | ||
183 | ltq_w32_mask(0, ASCWHBSTATE_CLRPE, | ||
184 | port->membase + LTQ_ASC_WHBSTATE); | ||
185 | } else if (rsr & ASCSTATE_FE) { | ||
186 | port->icount.frame++; | ||
187 | ltq_w32_mask(0, ASCWHBSTATE_CLRFE, | ||
188 | port->membase + LTQ_ASC_WHBSTATE); | ||
189 | } | ||
190 | if (rsr & ASCSTATE_ROE) { | ||
191 | port->icount.overrun++; | ||
192 | ltq_w32_mask(0, ASCWHBSTATE_CLRROE, | ||
193 | port->membase + LTQ_ASC_WHBSTATE); | ||
194 | } | ||
195 | |||
196 | rsr &= port->read_status_mask; | ||
197 | |||
198 | if (rsr & ASCSTATE_PE) | ||
199 | flag = TTY_PARITY; | ||
200 | else if (rsr & ASCSTATE_FE) | ||
201 | flag = TTY_FRAME; | ||
202 | } | ||
203 | |||
204 | if ((rsr & port->ignore_status_mask) == 0) | ||
205 | tty_insert_flip_char(tty, ch, flag); | ||
206 | |||
207 | if (rsr & ASCSTATE_ROE) | ||
208 | /* | ||
209 | * Overrun is special, since it's reported | ||
210 | * immediately, and doesn't affect the current | ||
211 | * character | ||
212 | */ | ||
213 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
214 | } | ||
215 | if (ch != 0) | ||
216 | tty_flip_buffer_push(tty); | ||
217 | tty_kref_put(tty); | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static void | ||
222 | lqasc_tx_chars(struct uart_port *port) | ||
223 | { | ||
224 | struct circ_buf *xmit = &port->state->xmit; | ||
225 | if (uart_tx_stopped(port)) { | ||
226 | lqasc_stop_tx(port); | ||
227 | return; | ||
228 | } | ||
229 | |||
230 | while (((ltq_r32(port->membase + LTQ_ASC_FSTAT) & | ||
231 | ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF) != 0) { | ||
232 | if (port->x_char) { | ||
233 | ltq_w8(port->x_char, port->membase + LTQ_ASC_TBUF); | ||
234 | port->icount.tx++; | ||
235 | port->x_char = 0; | ||
236 | continue; | ||
237 | } | ||
238 | |||
239 | if (uart_circ_empty(xmit)) | ||
240 | break; | ||
241 | |||
242 | ltq_w8(port->state->xmit.buf[port->state->xmit.tail], | ||
243 | port->membase + LTQ_ASC_TBUF); | ||
244 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
245 | port->icount.tx++; | ||
246 | } | ||
247 | |||
248 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
249 | uart_write_wakeup(port); | ||
250 | } | ||
251 | |||
252 | static irqreturn_t | ||
253 | lqasc_tx_int(int irq, void *_port) | ||
254 | { | ||
255 | unsigned long flags; | ||
256 | struct uart_port *port = (struct uart_port *)_port; | ||
257 | spin_lock_irqsave(<q_asc_lock, flags); | ||
258 | ltq_w32(ASC_IRNCR_TIR, port->membase + LTQ_ASC_IRNCR); | ||
259 | spin_unlock_irqrestore(<q_asc_lock, flags); | ||
260 | lqasc_start_tx(port); | ||
261 | return IRQ_HANDLED; | ||
262 | } | ||
263 | |||
264 | static irqreturn_t | ||
265 | lqasc_err_int(int irq, void *_port) | ||
266 | { | ||
267 | unsigned long flags; | ||
268 | struct uart_port *port = (struct uart_port *)_port; | ||
269 | spin_lock_irqsave(<q_asc_lock, flags); | ||
270 | /* clear any pending interrupts */ | ||
271 | ltq_w32_mask(0, ASCWHBSTATE_CLRPE | ASCWHBSTATE_CLRFE | | ||
272 | ASCWHBSTATE_CLRROE, port->membase + LTQ_ASC_WHBSTATE); | ||
273 | spin_unlock_irqrestore(<q_asc_lock, flags); | ||
274 | return IRQ_HANDLED; | ||
275 | } | ||
276 | |||
277 | static irqreturn_t | ||
278 | lqasc_rx_int(int irq, void *_port) | ||
279 | { | ||
280 | unsigned long flags; | ||
281 | struct uart_port *port = (struct uart_port *)_port; | ||
282 | spin_lock_irqsave(<q_asc_lock, flags); | ||
283 | ltq_w32(ASC_IRNCR_RIR, port->membase + LTQ_ASC_IRNCR); | ||
284 | lqasc_rx_chars(port); | ||
285 | spin_unlock_irqrestore(<q_asc_lock, flags); | ||
286 | return IRQ_HANDLED; | ||
287 | } | ||
288 | |||
289 | static unsigned int | ||
290 | lqasc_tx_empty(struct uart_port *port) | ||
291 | { | ||
292 | int status; | ||
293 | status = ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_TXFFLMASK; | ||
294 | return status ? 0 : TIOCSER_TEMT; | ||
295 | } | ||
296 | |||
297 | static unsigned int | ||
298 | lqasc_get_mctrl(struct uart_port *port) | ||
299 | { | ||
300 | return TIOCM_CTS | TIOCM_CAR | TIOCM_DSR; | ||
301 | } | ||
302 | |||
303 | static void | ||
304 | lqasc_set_mctrl(struct uart_port *port, u_int mctrl) | ||
305 | { | ||
306 | } | ||
307 | |||
308 | static void | ||
309 | lqasc_break_ctl(struct uart_port *port, int break_state) | ||
310 | { | ||
311 | } | ||
312 | |||
313 | static int | ||
314 | lqasc_startup(struct uart_port *port) | ||
315 | { | ||
316 | struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); | ||
317 | int retval; | ||
318 | |||
319 | port->uartclk = clk_get_rate(ltq_port->clk); | ||
320 | |||
321 | ltq_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET), | ||
322 | port->membase + LTQ_ASC_CLC); | ||
323 | |||
324 | ltq_w32(0, port->membase + LTQ_ASC_PISEL); | ||
325 | ltq_w32( | ||
326 | ((TXFIFO_FL << ASCTXFCON_TXFITLOFF) & ASCTXFCON_TXFITLMASK) | | ||
327 | ASCTXFCON_TXFEN | ASCTXFCON_TXFFLU, | ||
328 | port->membase + LTQ_ASC_TXFCON); | ||
329 | ltq_w32( | ||
330 | ((RXFIFO_FL << ASCRXFCON_RXFITLOFF) & ASCRXFCON_RXFITLMASK) | ||
331 | | ASCRXFCON_RXFEN | ASCRXFCON_RXFFLU, | ||
332 | port->membase + LTQ_ASC_RXFCON); | ||
333 | /* make sure other settings are written to hardware before | ||
334 | * setting enable bits | ||
335 | */ | ||
336 | wmb(); | ||
337 | ltq_w32_mask(0, ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_TOEN | | ||
338 | ASCCON_ROEN, port->membase + LTQ_ASC_CON); | ||
339 | |||
340 | retval = request_irq(ltq_port->tx_irq, lqasc_tx_int, | ||
341 | IRQF_DISABLED, "asc_tx", port); | ||
342 | if (retval) { | ||
343 | pr_err("failed to request lqasc_tx_int\n"); | ||
344 | return retval; | ||
345 | } | ||
346 | |||
347 | retval = request_irq(ltq_port->rx_irq, lqasc_rx_int, | ||
348 | IRQF_DISABLED, "asc_rx", port); | ||
349 | if (retval) { | ||
350 | pr_err("failed to request lqasc_rx_int\n"); | ||
351 | goto err1; | ||
352 | } | ||
353 | |||
354 | retval = request_irq(ltq_port->err_irq, lqasc_err_int, | ||
355 | IRQF_DISABLED, "asc_err", port); | ||
356 | if (retval) { | ||
357 | pr_err("failed to request lqasc_err_int\n"); | ||
358 | goto err2; | ||
359 | } | ||
360 | |||
361 | ltq_w32(ASC_IRNREN_RX | ASC_IRNREN_ERR | ASC_IRNREN_TX, | ||
362 | port->membase + LTQ_ASC_IRNREN); | ||
363 | return 0; | ||
364 | |||
365 | err2: | ||
366 | free_irq(ltq_port->rx_irq, port); | ||
367 | err1: | ||
368 | free_irq(ltq_port->tx_irq, port); | ||
369 | return retval; | ||
370 | } | ||
371 | |||
372 | static void | ||
373 | lqasc_shutdown(struct uart_port *port) | ||
374 | { | ||
375 | struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); | ||
376 | free_irq(ltq_port->tx_irq, port); | ||
377 | free_irq(ltq_port->rx_irq, port); | ||
378 | free_irq(ltq_port->err_irq, port); | ||
379 | |||
380 | ltq_w32(0, port->membase + LTQ_ASC_CON); | ||
381 | ltq_w32_mask(ASCRXFCON_RXFEN, ASCRXFCON_RXFFLU, | ||
382 | port->membase + LTQ_ASC_RXFCON); | ||
383 | ltq_w32_mask(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU, | ||
384 | port->membase + LTQ_ASC_TXFCON); | ||
385 | } | ||
386 | |||
387 | static void | ||
388 | lqasc_set_termios(struct uart_port *port, | ||
389 | struct ktermios *new, struct ktermios *old) | ||
390 | { | ||
391 | unsigned int cflag; | ||
392 | unsigned int iflag; | ||
393 | unsigned int divisor; | ||
394 | unsigned int baud; | ||
395 | unsigned int con = 0; | ||
396 | unsigned long flags; | ||
397 | |||
398 | cflag = new->c_cflag; | ||
399 | iflag = new->c_iflag; | ||
400 | |||
401 | switch (cflag & CSIZE) { | ||
402 | case CS7: | ||
403 | con = ASCCON_M_7ASYNC; | ||
404 | break; | ||
405 | |||
406 | case CS5: | ||
407 | case CS6: | ||
408 | default: | ||
409 | new->c_cflag &= ~ CSIZE; | ||
410 | new->c_cflag |= CS8; | ||
411 | con = ASCCON_M_8ASYNC; | ||
412 | break; | ||
413 | } | ||
414 | |||
415 | cflag &= ~CMSPAR; /* Mark/Space parity is not supported */ | ||
416 | |||
417 | if (cflag & CSTOPB) | ||
418 | con |= ASCCON_STP; | ||
419 | |||
420 | if (cflag & PARENB) { | ||
421 | if (!(cflag & PARODD)) | ||
422 | con &= ~ASCCON_ODD; | ||
423 | else | ||
424 | con |= ASCCON_ODD; | ||
425 | } | ||
426 | |||
427 | port->read_status_mask = ASCSTATE_ROE; | ||
428 | if (iflag & INPCK) | ||
429 | port->read_status_mask |= ASCSTATE_FE | ASCSTATE_PE; | ||
430 | |||
431 | port->ignore_status_mask = 0; | ||
432 | if (iflag & IGNPAR) | ||
433 | port->ignore_status_mask |= ASCSTATE_FE | ASCSTATE_PE; | ||
434 | |||
435 | if (iflag & IGNBRK) { | ||
436 | /* | ||
437 | * If we're ignoring parity and break indicators, | ||
438 | * ignore overruns too (for real raw support). | ||
439 | */ | ||
440 | if (iflag & IGNPAR) | ||
441 | port->ignore_status_mask |= ASCSTATE_ROE; | ||
442 | } | ||
443 | |||
444 | if ((cflag & CREAD) == 0) | ||
445 | port->ignore_status_mask |= UART_DUMMY_UER_RX; | ||
446 | |||
447 | /* set error signals - framing, parity and overrun, enable receiver */ | ||
448 | con |= ASCCON_FEN | ASCCON_TOEN | ASCCON_ROEN; | ||
449 | |||
450 | spin_lock_irqsave(<q_asc_lock, flags); | ||
451 | |||
452 | /* set up CON */ | ||
453 | ltq_w32_mask(0, con, port->membase + LTQ_ASC_CON); | ||
454 | |||
455 | /* Set baud rate - take a divider of 2 into account */ | ||
456 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); | ||
457 | divisor = uart_get_divisor(port, baud); | ||
458 | divisor = divisor / 2 - 1; | ||
459 | |||
460 | /* disable the baudrate generator */ | ||
461 | ltq_w32_mask(ASCCON_R, 0, port->membase + LTQ_ASC_CON); | ||
462 | |||
463 | /* make sure the fractional divider is off */ | ||
464 | ltq_w32_mask(ASCCON_FDE, 0, port->membase + LTQ_ASC_CON); | ||
465 | |||
466 | /* set up to use divisor of 2 */ | ||
467 | ltq_w32_mask(ASCCON_BRS, 0, port->membase + LTQ_ASC_CON); | ||
468 | |||
469 | /* now we can write the new baudrate into the register */ | ||
470 | ltq_w32(divisor, port->membase + LTQ_ASC_BG); | ||
471 | |||
472 | /* turn the baudrate generator back on */ | ||
473 | ltq_w32_mask(0, ASCCON_R, port->membase + LTQ_ASC_CON); | ||
474 | |||
475 | /* enable rx */ | ||
476 | ltq_w32(ASCWHBSTATE_SETREN, port->membase + LTQ_ASC_WHBSTATE); | ||
477 | |||
478 | spin_unlock_irqrestore(<q_asc_lock, flags); | ||
479 | |||
480 | /* Don't rewrite B0 */ | ||
481 | if (tty_termios_baud_rate(new)) | ||
482 | tty_termios_encode_baud_rate(new, baud, baud); | ||
483 | } | ||
484 | |||
485 | static const char* | ||
486 | lqasc_type(struct uart_port *port) | ||
487 | { | ||
488 | if (port->type == PORT_LTQ_ASC) | ||
489 | return DRVNAME; | ||
490 | else | ||
491 | return NULL; | ||
492 | } | ||
493 | |||
494 | static void | ||
495 | lqasc_release_port(struct uart_port *port) | ||
496 | { | ||
497 | if (port->flags & UPF_IOREMAP) { | ||
498 | iounmap(port->membase); | ||
499 | port->membase = NULL; | ||
500 | } | ||
501 | } | ||
502 | |||
503 | static int | ||
504 | lqasc_request_port(struct uart_port *port) | ||
505 | { | ||
506 | struct platform_device *pdev = to_platform_device(port->dev); | ||
507 | struct resource *res; | ||
508 | int size; | ||
509 | |||
510 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
511 | if (!res) { | ||
512 | dev_err(&pdev->dev, "cannot obtain I/O memory region"); | ||
513 | return -ENODEV; | ||
514 | } | ||
515 | size = resource_size(res); | ||
516 | |||
517 | res = devm_request_mem_region(&pdev->dev, res->start, | ||
518 | size, dev_name(&pdev->dev)); | ||
519 | if (!res) { | ||
520 | dev_err(&pdev->dev, "cannot request I/O memory region"); | ||
521 | return -EBUSY; | ||
522 | } | ||
523 | |||
524 | if (port->flags & UPF_IOREMAP) { | ||
525 | port->membase = devm_ioremap_nocache(&pdev->dev, | ||
526 | port->mapbase, size); | ||
527 | if (port->membase == NULL) | ||
528 | return -ENOMEM; | ||
529 | } | ||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | static void | ||
534 | lqasc_config_port(struct uart_port *port, int flags) | ||
535 | { | ||
536 | if (flags & UART_CONFIG_TYPE) { | ||
537 | port->type = PORT_LTQ_ASC; | ||
538 | lqasc_request_port(port); | ||
539 | } | ||
540 | } | ||
541 | |||
542 | static int | ||
543 | lqasc_verify_port(struct uart_port *port, | ||
544 | struct serial_struct *ser) | ||
545 | { | ||
546 | int ret = 0; | ||
547 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_LTQ_ASC) | ||
548 | ret = -EINVAL; | ||
549 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | ||
550 | ret = -EINVAL; | ||
551 | if (ser->baud_base < 9600) | ||
552 | ret = -EINVAL; | ||
553 | return ret; | ||
554 | } | ||
555 | |||
556 | static struct uart_ops lqasc_pops = { | ||
557 | .tx_empty = lqasc_tx_empty, | ||
558 | .set_mctrl = lqasc_set_mctrl, | ||
559 | .get_mctrl = lqasc_get_mctrl, | ||
560 | .stop_tx = lqasc_stop_tx, | ||
561 | .start_tx = lqasc_start_tx, | ||
562 | .stop_rx = lqasc_stop_rx, | ||
563 | .enable_ms = lqasc_enable_ms, | ||
564 | .break_ctl = lqasc_break_ctl, | ||
565 | .startup = lqasc_startup, | ||
566 | .shutdown = lqasc_shutdown, | ||
567 | .set_termios = lqasc_set_termios, | ||
568 | .type = lqasc_type, | ||
569 | .release_port = lqasc_release_port, | ||
570 | .request_port = lqasc_request_port, | ||
571 | .config_port = lqasc_config_port, | ||
572 | .verify_port = lqasc_verify_port, | ||
573 | }; | ||
574 | |||
575 | static void | ||
576 | lqasc_console_putchar(struct uart_port *port, int ch) | ||
577 | { | ||
578 | int fifofree; | ||
579 | |||
580 | if (!port->membase) | ||
581 | return; | ||
582 | |||
583 | do { | ||
584 | fifofree = (ltq_r32(port->membase + LTQ_ASC_FSTAT) | ||
585 | & ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF; | ||
586 | } while (fifofree == 0); | ||
587 | ltq_w8(ch, port->membase + LTQ_ASC_TBUF); | ||
588 | } | ||
589 | |||
590 | |||
591 | static void | ||
592 | lqasc_console_write(struct console *co, const char *s, u_int count) | ||
593 | { | ||
594 | struct ltq_uart_port *ltq_port; | ||
595 | struct uart_port *port; | ||
596 | unsigned long flags; | ||
597 | |||
598 | if (co->index >= MAXPORTS) | ||
599 | return; | ||
600 | |||
601 | ltq_port = lqasc_port[co->index]; | ||
602 | if (!ltq_port) | ||
603 | return; | ||
604 | |||
605 | port = <q_port->port; | ||
606 | |||
607 | spin_lock_irqsave(<q_asc_lock, flags); | ||
608 | uart_console_write(port, s, count, lqasc_console_putchar); | ||
609 | spin_unlock_irqrestore(<q_asc_lock, flags); | ||
610 | } | ||
611 | |||
612 | static int __init | ||
613 | lqasc_console_setup(struct console *co, char *options) | ||
614 | { | ||
615 | struct ltq_uart_port *ltq_port; | ||
616 | struct uart_port *port; | ||
617 | int baud = 115200; | ||
618 | int bits = 8; | ||
619 | int parity = 'n'; | ||
620 | int flow = 'n'; | ||
621 | |||
622 | if (co->index >= MAXPORTS) | ||
623 | return -ENODEV; | ||
624 | |||
625 | ltq_port = lqasc_port[co->index]; | ||
626 | if (!ltq_port) | ||
627 | return -ENODEV; | ||
628 | |||
629 | port = <q_port->port; | ||
630 | |||
631 | port->uartclk = clk_get_rate(ltq_port->clk); | ||
632 | |||
633 | if (options) | ||
634 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
635 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
636 | } | ||
637 | |||
638 | static struct console lqasc_console = { | ||
639 | .name = "ttyLTQ", | ||
640 | .write = lqasc_console_write, | ||
641 | .device = uart_console_device, | ||
642 | .setup = lqasc_console_setup, | ||
643 | .flags = CON_PRINTBUFFER, | ||
644 | .index = -1, | ||
645 | .data = &lqasc_reg, | ||
646 | }; | ||
647 | |||
648 | static int __init | ||
649 | lqasc_console_init(void) | ||
650 | { | ||
651 | register_console(&lqasc_console); | ||
652 | return 0; | ||
653 | } | ||
654 | console_initcall(lqasc_console_init); | ||
655 | |||
656 | static struct uart_driver lqasc_reg = { | ||
657 | .owner = THIS_MODULE, | ||
658 | .driver_name = DRVNAME, | ||
659 | .dev_name = "ttyLTQ", | ||
660 | .major = 0, | ||
661 | .minor = 0, | ||
662 | .nr = MAXPORTS, | ||
663 | .cons = &lqasc_console, | ||
664 | }; | ||
665 | |||
666 | static int __init | ||
667 | lqasc_probe(struct platform_device *pdev) | ||
668 | { | ||
669 | struct ltq_uart_port *ltq_port; | ||
670 | struct uart_port *port; | ||
671 | struct resource *mmres, *irqres; | ||
672 | int tx_irq, rx_irq, err_irq; | ||
673 | struct clk *clk; | ||
674 | int ret; | ||
675 | |||
676 | mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
677 | irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
678 | if (!mmres || !irqres) | ||
679 | return -ENODEV; | ||
680 | |||
681 | if (pdev->id >= MAXPORTS) | ||
682 | return -EBUSY; | ||
683 | |||
684 | if (lqasc_port[pdev->id] != NULL) | ||
685 | return -EBUSY; | ||
686 | |||
687 | clk = clk_get(&pdev->dev, "fpi"); | ||
688 | if (IS_ERR(clk)) { | ||
689 | pr_err("failed to get fpi clk\n"); | ||
690 | return -ENOENT; | ||
691 | } | ||
692 | |||
693 | tx_irq = platform_get_irq_byname(pdev, "tx"); | ||
694 | rx_irq = platform_get_irq_byname(pdev, "rx"); | ||
695 | err_irq = platform_get_irq_byname(pdev, "err"); | ||
696 | if ((tx_irq < 0) | (rx_irq < 0) | (err_irq < 0)) | ||
697 | return -ENODEV; | ||
698 | |||
699 | ltq_port = kzalloc(sizeof(struct ltq_uart_port), GFP_KERNEL); | ||
700 | if (!ltq_port) | ||
701 | return -ENOMEM; | ||
702 | |||
703 | port = <q_port->port; | ||
704 | |||
705 | port->iotype = SERIAL_IO_MEM; | ||
706 | port->flags = ASYNC_BOOT_AUTOCONF | UPF_IOREMAP; | ||
707 | port->ops = &lqasc_pops; | ||
708 | port->fifosize = 16; | ||
709 | port->type = PORT_LTQ_ASC, | ||
710 | port->line = pdev->id; | ||
711 | port->dev = &pdev->dev; | ||
712 | |||
713 | port->irq = tx_irq; /* unused, just to be backward-compatibe */ | ||
714 | port->mapbase = mmres->start; | ||
715 | |||
716 | ltq_port->clk = clk; | ||
717 | |||
718 | ltq_port->tx_irq = tx_irq; | ||
719 | ltq_port->rx_irq = rx_irq; | ||
720 | ltq_port->err_irq = err_irq; | ||
721 | |||
722 | lqasc_port[pdev->id] = ltq_port; | ||
723 | platform_set_drvdata(pdev, ltq_port); | ||
724 | |||
725 | ret = uart_add_one_port(&lqasc_reg, port); | ||
726 | |||
727 | return ret; | ||
728 | } | ||
729 | |||
730 | static struct platform_driver lqasc_driver = { | ||
731 | .driver = { | ||
732 | .name = DRVNAME, | ||
733 | .owner = THIS_MODULE, | ||
734 | }, | ||
735 | }; | ||
736 | |||
737 | int __init | ||
738 | init_lqasc(void) | ||
739 | { | ||
740 | int ret; | ||
741 | |||
742 | ret = uart_register_driver(&lqasc_reg); | ||
743 | if (ret != 0) | ||
744 | return ret; | ||
745 | |||
746 | ret = platform_driver_probe(&lqasc_driver, lqasc_probe); | ||
747 | if (ret != 0) | ||
748 | uart_unregister_driver(&lqasc_reg); | ||
749 | |||
750 | return ret; | ||
751 | } | ||
752 | |||
753 | module_init(init_lqasc); | ||
754 | |||
755 | MODULE_DESCRIPTION("Lantiq serial port driver"); | ||
756 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 1b0f98bc51b5..022f9eb0b7bf 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -990,6 +990,12 @@ config BCM63XX_WDT | |||
990 | To compile this driver as a loadable module, choose M here. | 990 | To compile this driver as a loadable module, choose M here. |
991 | The module will be called bcm63xx_wdt. | 991 | The module will be called bcm63xx_wdt. |
992 | 992 | ||
993 | config LANTIQ_WDT | ||
994 | tristate "Lantiq SoC watchdog" | ||
995 | depends on LANTIQ | ||
996 | help | ||
997 | Hardware driver for the Lantiq SoC Watchdog Timer. | ||
998 | |||
993 | # PARISC Architecture | 999 | # PARISC Architecture |
994 | 1000 | ||
995 | # POWERPC Architecture | 1001 | # POWERPC Architecture |
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 3f8608b922a7..ed26f7094e47 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
@@ -123,6 +123,7 @@ obj-$(CONFIG_AR7_WDT) += ar7_wdt.o | |||
123 | obj-$(CONFIG_TXX9_WDT) += txx9wdt.o | 123 | obj-$(CONFIG_TXX9_WDT) += txx9wdt.o |
124 | obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o | 124 | obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o |
125 | octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o | 125 | octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o |
126 | obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o | ||
126 | 127 | ||
127 | # PARISC Architecture | 128 | # PARISC Architecture |
128 | 129 | ||
diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c new file mode 100644 index 000000000000..7d82adac1cb2 --- /dev/null +++ b/drivers/watchdog/lantiq_wdt.c | |||
@@ -0,0 +1,261 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | * Based on EP93xx wdt driver | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/fs.h> | ||
12 | #include <linux/miscdevice.h> | ||
13 | #include <linux/watchdog.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/uaccess.h> | ||
16 | #include <linux/clk.h> | ||
17 | #include <linux/io.h> | ||
18 | |||
19 | #include <lantiq.h> | ||
20 | |||
21 | /* Section 3.4 of the datasheet | ||
22 | * The password sequence protects the WDT control register from unintended | ||
23 | * write actions, which might cause malfunction of the WDT. | ||
24 | * | ||
25 | * essentially the following two magic passwords need to be written to allow | ||
26 | * IO access to the WDT core | ||
27 | */ | ||
28 | #define LTQ_WDT_PW1 0x00BE0000 | ||
29 | #define LTQ_WDT_PW2 0x00DC0000 | ||
30 | |||
31 | #define LTQ_WDT_CR 0x0 /* watchdog control register */ | ||
32 | #define LTQ_WDT_SR 0x8 /* watchdog status register */ | ||
33 | |||
34 | #define LTQ_WDT_SR_EN (0x1 << 31) /* enable bit */ | ||
35 | #define LTQ_WDT_SR_PWD (0x3 << 26) /* turn on power */ | ||
36 | #define LTQ_WDT_SR_CLKDIV (0x3 << 24) /* turn on clock and set */ | ||
37 | /* divider to 0x40000 */ | ||
38 | #define LTQ_WDT_DIVIDER 0x40000 | ||
39 | #define LTQ_MAX_TIMEOUT ((1 << 16) - 1) /* the reload field is 16 bit */ | ||
40 | |||
41 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
42 | |||
43 | static void __iomem *ltq_wdt_membase; | ||
44 | static unsigned long ltq_io_region_clk_rate; | ||
45 | |||
46 | static unsigned long ltq_wdt_bootstatus; | ||
47 | static unsigned long ltq_wdt_in_use; | ||
48 | static int ltq_wdt_timeout = 30; | ||
49 | static int ltq_wdt_ok_to_close; | ||
50 | |||
51 | static void | ||
52 | ltq_wdt_enable(void) | ||
53 | { | ||
54 | ltq_wdt_timeout = ltq_wdt_timeout * | ||
55 | (ltq_io_region_clk_rate / LTQ_WDT_DIVIDER) + 0x1000; | ||
56 | if (ltq_wdt_timeout > LTQ_MAX_TIMEOUT) | ||
57 | ltq_wdt_timeout = LTQ_MAX_TIMEOUT; | ||
58 | |||
59 | /* write the first password magic */ | ||
60 | ltq_w32(LTQ_WDT_PW1, ltq_wdt_membase + LTQ_WDT_CR); | ||
61 | /* write the second magic plus the configuration and new timeout */ | ||
62 | ltq_w32(LTQ_WDT_SR_EN | LTQ_WDT_SR_PWD | LTQ_WDT_SR_CLKDIV | | ||
63 | LTQ_WDT_PW2 | ltq_wdt_timeout, ltq_wdt_membase + LTQ_WDT_CR); | ||
64 | } | ||
65 | |||
66 | static void | ||
67 | ltq_wdt_disable(void) | ||
68 | { | ||
69 | /* write the first password magic */ | ||
70 | ltq_w32(LTQ_WDT_PW1, ltq_wdt_membase + LTQ_WDT_CR); | ||
71 | /* write the second password magic with no config | ||
72 | * this turns the watchdog off | ||
73 | */ | ||
74 | ltq_w32(LTQ_WDT_PW2, ltq_wdt_membase + LTQ_WDT_CR); | ||
75 | } | ||
76 | |||
77 | static ssize_t | ||
78 | ltq_wdt_write(struct file *file, const char __user *data, | ||
79 | size_t len, loff_t *ppos) | ||
80 | { | ||
81 | if (len) { | ||
82 | if (!nowayout) { | ||
83 | size_t i; | ||
84 | |||
85 | ltq_wdt_ok_to_close = 0; | ||
86 | for (i = 0; i != len; i++) { | ||
87 | char c; | ||
88 | |||
89 | if (get_user(c, data + i)) | ||
90 | return -EFAULT; | ||
91 | if (c == 'V') | ||
92 | ltq_wdt_ok_to_close = 1; | ||
93 | else | ||
94 | ltq_wdt_ok_to_close = 0; | ||
95 | } | ||
96 | } | ||
97 | ltq_wdt_enable(); | ||
98 | } | ||
99 | |||
100 | return len; | ||
101 | } | ||
102 | |||
103 | static struct watchdog_info ident = { | ||
104 | .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | | ||
105 | WDIOF_CARDRESET, | ||
106 | .identity = "ltq_wdt", | ||
107 | }; | ||
108 | |||
109 | static long | ||
110 | ltq_wdt_ioctl(struct file *file, | ||
111 | unsigned int cmd, unsigned long arg) | ||
112 | { | ||
113 | int ret = -ENOTTY; | ||
114 | |||
115 | switch (cmd) { | ||
116 | case WDIOC_GETSUPPORT: | ||
117 | ret = copy_to_user((struct watchdog_info __user *)arg, &ident, | ||
118 | sizeof(ident)) ? -EFAULT : 0; | ||
119 | break; | ||
120 | |||
121 | case WDIOC_GETBOOTSTATUS: | ||
122 | ret = put_user(ltq_wdt_bootstatus, (int __user *)arg); | ||
123 | break; | ||
124 | |||
125 | case WDIOC_GETSTATUS: | ||
126 | ret = put_user(0, (int __user *)arg); | ||
127 | break; | ||
128 | |||
129 | case WDIOC_SETTIMEOUT: | ||
130 | ret = get_user(ltq_wdt_timeout, (int __user *)arg); | ||
131 | if (!ret) | ||
132 | ltq_wdt_enable(); | ||
133 | /* intentional drop through */ | ||
134 | case WDIOC_GETTIMEOUT: | ||
135 | ret = put_user(ltq_wdt_timeout, (int __user *)arg); | ||
136 | break; | ||
137 | |||
138 | case WDIOC_KEEPALIVE: | ||
139 | ltq_wdt_enable(); | ||
140 | ret = 0; | ||
141 | break; | ||
142 | } | ||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | static int | ||
147 | ltq_wdt_open(struct inode *inode, struct file *file) | ||
148 | { | ||
149 | if (test_and_set_bit(0, <q_wdt_in_use)) | ||
150 | return -EBUSY; | ||
151 | ltq_wdt_in_use = 1; | ||
152 | ltq_wdt_enable(); | ||
153 | |||
154 | return nonseekable_open(inode, file); | ||
155 | } | ||
156 | |||
157 | static int | ||
158 | ltq_wdt_release(struct inode *inode, struct file *file) | ||
159 | { | ||
160 | if (ltq_wdt_ok_to_close) | ||
161 | ltq_wdt_disable(); | ||
162 | else | ||
163 | pr_err("ltq_wdt: watchdog closed without warning\n"); | ||
164 | ltq_wdt_ok_to_close = 0; | ||
165 | clear_bit(0, <q_wdt_in_use); | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static const struct file_operations ltq_wdt_fops = { | ||
171 | .owner = THIS_MODULE, | ||
172 | .write = ltq_wdt_write, | ||
173 | .unlocked_ioctl = ltq_wdt_ioctl, | ||
174 | .open = ltq_wdt_open, | ||
175 | .release = ltq_wdt_release, | ||
176 | .llseek = no_llseek, | ||
177 | }; | ||
178 | |||
179 | static struct miscdevice ltq_wdt_miscdev = { | ||
180 | .minor = WATCHDOG_MINOR, | ||
181 | .name = "watchdog", | ||
182 | .fops = <q_wdt_fops, | ||
183 | }; | ||
184 | |||
185 | static int __init | ||
186 | ltq_wdt_probe(struct platform_device *pdev) | ||
187 | { | ||
188 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
189 | struct clk *clk; | ||
190 | |||
191 | if (!res) { | ||
192 | dev_err(&pdev->dev, "cannot obtain I/O memory region"); | ||
193 | return -ENOENT; | ||
194 | } | ||
195 | res = devm_request_mem_region(&pdev->dev, res->start, | ||
196 | resource_size(res), dev_name(&pdev->dev)); | ||
197 | if (!res) { | ||
198 | dev_err(&pdev->dev, "cannot request I/O memory region"); | ||
199 | return -EBUSY; | ||
200 | } | ||
201 | ltq_wdt_membase = devm_ioremap_nocache(&pdev->dev, res->start, | ||
202 | resource_size(res)); | ||
203 | if (!ltq_wdt_membase) { | ||
204 | dev_err(&pdev->dev, "cannot remap I/O memory region\n"); | ||
205 | return -ENOMEM; | ||
206 | } | ||
207 | |||
208 | /* we do not need to enable the clock as it is always running */ | ||
209 | clk = clk_get(&pdev->dev, "io"); | ||
210 | WARN_ON(!clk); | ||
211 | ltq_io_region_clk_rate = clk_get_rate(clk); | ||
212 | clk_put(clk); | ||
213 | |||
214 | if (ltq_reset_cause() == LTQ_RST_CAUSE_WDTRST) | ||
215 | ltq_wdt_bootstatus = WDIOF_CARDRESET; | ||
216 | |||
217 | return misc_register(<q_wdt_miscdev); | ||
218 | } | ||
219 | |||
220 | static int __devexit | ||
221 | ltq_wdt_remove(struct platform_device *pdev) | ||
222 | { | ||
223 | misc_deregister(<q_wdt_miscdev); | ||
224 | |||
225 | if (ltq_wdt_membase) | ||
226 | iounmap(ltq_wdt_membase); | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | |||
232 | static struct platform_driver ltq_wdt_driver = { | ||
233 | .remove = __devexit_p(ltq_wdt_remove), | ||
234 | .driver = { | ||
235 | .name = "ltq_wdt", | ||
236 | .owner = THIS_MODULE, | ||
237 | }, | ||
238 | }; | ||
239 | |||
240 | static int __init | ||
241 | init_ltq_wdt(void) | ||
242 | { | ||
243 | return platform_driver_probe(<q_wdt_driver, ltq_wdt_probe); | ||
244 | } | ||
245 | |||
246 | static void __exit | ||
247 | exit_ltq_wdt(void) | ||
248 | { | ||
249 | return platform_driver_unregister(<q_wdt_driver); | ||
250 | } | ||
251 | |||
252 | module_init(init_ltq_wdt); | ||
253 | module_exit(exit_ltq_wdt); | ||
254 | |||
255 | module_param(nowayout, int, 0); | ||
256 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); | ||
257 | |||
258 | MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); | ||
259 | MODULE_DESCRIPTION("Lantiq SoC Watchdog"); | ||
260 | MODULE_LICENSE("GPL"); | ||
261 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index 5ec5ac1f7878..1479dc4d6129 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c | |||
@@ -66,6 +66,7 @@ static struct { | |||
66 | int default_ticks; | 66 | int default_ticks; |
67 | unsigned long inuse; | 67 | unsigned long inuse; |
68 | unsigned gpio; | 68 | unsigned gpio; |
69 | int gstate; | ||
69 | } mtx1_wdt_device; | 70 | } mtx1_wdt_device; |
70 | 71 | ||
71 | static void mtx1_wdt_trigger(unsigned long unused) | 72 | static void mtx1_wdt_trigger(unsigned long unused) |
@@ -75,13 +76,13 @@ static void mtx1_wdt_trigger(unsigned long unused) | |||
75 | spin_lock(&mtx1_wdt_device.lock); | 76 | spin_lock(&mtx1_wdt_device.lock); |
76 | if (mtx1_wdt_device.running) | 77 | if (mtx1_wdt_device.running) |
77 | ticks--; | 78 | ticks--; |
78 | /* | 79 | |
79 | * toggle GPIO2_15 | 80 | /* toggle wdt gpio */ |
80 | */ | 81 | mtx1_wdt_device.gstate = ~mtx1_wdt_device.gstate; |
81 | tmp = au_readl(GPIO2_DIR); | 82 | if (mtx1_wdt_device.gstate) |
82 | tmp = (tmp & ~(1 << mtx1_wdt_device.gpio)) | | 83 | gpio_direction_output(mtx1_wdt_device.gpio, 1); |
83 | ((~tmp) & (1 << mtx1_wdt_device.gpio)); | 84 | else |
84 | au_writel(tmp, GPIO2_DIR); | 85 | gpio_direction_input(mtx1_wdt_device.gpio); |
85 | 86 | ||
86 | if (mtx1_wdt_device.queue && ticks) | 87 | if (mtx1_wdt_device.queue && ticks) |
87 | mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); | 88 | mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); |
@@ -103,7 +104,8 @@ static void mtx1_wdt_start(void) | |||
103 | spin_lock_irqsave(&mtx1_wdt_device.lock, flags); | 104 | spin_lock_irqsave(&mtx1_wdt_device.lock, flags); |
104 | if (!mtx1_wdt_device.queue) { | 105 | if (!mtx1_wdt_device.queue) { |
105 | mtx1_wdt_device.queue = 1; | 106 | mtx1_wdt_device.queue = 1; |
106 | gpio_set_value(mtx1_wdt_device.gpio, 1); | 107 | mtx1_wdt_device.gstate = 1; |
108 | gpio_direction_output(mtx1_wdt_device.gpio, 1); | ||
107 | mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); | 109 | mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); |
108 | } | 110 | } |
109 | mtx1_wdt_device.running++; | 111 | mtx1_wdt_device.running++; |
@@ -117,7 +119,8 @@ static int mtx1_wdt_stop(void) | |||
117 | spin_lock_irqsave(&mtx1_wdt_device.lock, flags); | 119 | spin_lock_irqsave(&mtx1_wdt_device.lock, flags); |
118 | if (mtx1_wdt_device.queue) { | 120 | if (mtx1_wdt_device.queue) { |
119 | mtx1_wdt_device.queue = 0; | 121 | mtx1_wdt_device.queue = 0; |
120 | gpio_set_value(mtx1_wdt_device.gpio, 0); | 122 | mtx1_wdt_device.gstate = 0; |
123 | gpio_direction_output(mtx1_wdt_device.gpio, 0); | ||
121 | } | 124 | } |
122 | ticks = mtx1_wdt_device.default_ticks; | 125 | ticks = mtx1_wdt_device.default_ticks; |
123 | spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags); | 126 | spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags); |
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 9659eff52ca2..045f72ab5dfd 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h | |||
@@ -404,7 +404,9 @@ extern bool ssb_is_sprom_available(struct ssb_bus *bus); | |||
404 | 404 | ||
405 | /* Set a fallback SPROM. | 405 | /* Set a fallback SPROM. |
406 | * See kdoc at the function definition for complete documentation. */ | 406 | * See kdoc at the function definition for complete documentation. */ |
407 | extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom); | 407 | extern int ssb_arch_register_fallback_sprom( |
408 | int (*sprom_callback)(struct ssb_bus *bus, | ||
409 | struct ssb_sprom *out)); | ||
408 | 410 | ||
409 | /* Suspend a SSB bus. | 411 | /* Suspend a SSB bus. |
410 | * Call this from the parent bus suspend routine. */ | 412 | * Call this from the parent bus suspend routine. */ |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index c768bcdda1b7..f0aa00ba3fac 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -398,7 +398,7 @@ config SLUB_STATS | |||
398 | config DEBUG_KMEMLEAK | 398 | config DEBUG_KMEMLEAK |
399 | bool "Kernel memory leak detector" | 399 | bool "Kernel memory leak detector" |
400 | depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \ | 400 | depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \ |
401 | (X86 || ARM || PPC || S390 || SPARC64 || SUPERH || MICROBLAZE || TILE) | 401 | (X86 || ARM || PPC || MIPS || S390 || SPARC64 || SUPERH || MICROBLAZE || TILE) |
402 | 402 | ||
403 | select DEBUG_FS if SYSFS | 403 | select DEBUG_FS if SYSFS |
404 | select STACKTRACE if STACKTRACE_SUPPORT | 404 | select STACKTRACE if STACKTRACE_SUPPORT |