diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-11 22:21:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-11 22:21:23 -0400 |
commit | dd6d1844af33acb4edd0a40b1770d091a22c94be (patch) | |
tree | e6bd3549919773a13b770324a4dddb51b194b452 /arch/mips/bcm47xx | |
parent | 19f71153b9be219756c6b2757921433a69b7975c (diff) | |
parent | aaf76a3245c02faba51c96b9a340c14d6bb0dcc0 (diff) |
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (80 commits)
[MIPS] tlbex.c: Cleanup __init usage.
[MIPS] WRPPMC serial support move to platform device
[MIPS] R1: Fix hazard barriers to make kernels work on R2 also.
[MIPS] VPE: reimplement ELF loader.
[MIPS] cleanup WRPPMC include files
[MIPS] Add BUG_ON assertion for attempt to run kernel on the wrong CPU type.
[MIPS] SMP: Use ISO C struct initializer for local structs.
[MIPS] SMP: Kill useless casts.
[MIPS] Kill num_online_cpus() loops.
[MIPS] SMP: Implement smp_call_function_mask().
[MIPS] Make facility to convert CPU types to strings generally available.
[MIPS] Convert list of CPU types from #define to enum.
[MIPS] Optimize get_unaligned / put_unaligned implementations.
[MIPS] checkfiles: Fix "need space after that ','" errors.
[MIPS] Fix "no space between function name and open parenthesis" warnings.
[MIPS] Allow hardwiring of the CPU type to a single type for optimization.
[MIPS] tlbex: Size optimize code by declaring a few functions inline.
[MIPS] pg-r4k.c: Dump the generated code
[MIPS] Cobalt: Remove cobalt_machine_power_off()
[MIPS] Cobalt: Move reset port definition to arch/mips/cobalt/reset.c
...
Diffstat (limited to 'arch/mips/bcm47xx')
-rw-r--r-- | arch/mips/bcm47xx/Makefile | 6 | ||||
-rw-r--r-- | arch/mips/bcm47xx/gpio.c | 79 | ||||
-rw-r--r-- | arch/mips/bcm47xx/irq.c | 55 | ||||
-rw-r--r-- | arch/mips/bcm47xx/prom.c | 158 | ||||
-rw-r--r-- | arch/mips/bcm47xx/serial.c | 52 | ||||
-rw-r--r-- | arch/mips/bcm47xx/setup.c | 123 | ||||
-rw-r--r-- | arch/mips/bcm47xx/time.c | 55 | ||||
-rw-r--r-- | arch/mips/bcm47xx/wgt634u.c | 64 |
8 files changed, 592 insertions, 0 deletions
diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile new file mode 100644 index 000000000000..35294b12d638 --- /dev/null +++ b/arch/mips/bcm47xx/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | # | ||
2 | # Makefile for the BCM47XX specific kernel interface routines | ||
3 | # under Linux. | ||
4 | # | ||
5 | |||
6 | obj-y := gpio.o irq.o prom.o serial.o setup.o time.o wgt634u.o | ||
diff --git a/arch/mips/bcm47xx/gpio.c b/arch/mips/bcm47xx/gpio.c new file mode 100644 index 000000000000..f5a53acf995a --- /dev/null +++ b/arch/mips/bcm47xx/gpio.c | |||
@@ -0,0 +1,79 @@ | |||
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) 2007 Aurelien Jarno <aurelien@aurel32.net> | ||
7 | */ | ||
8 | |||
9 | #include <linux/ssb/ssb.h> | ||
10 | #include <linux/ssb/ssb_driver_chipcommon.h> | ||
11 | #include <linux/ssb/ssb_driver_extif.h> | ||
12 | #include <asm/mach-bcm47xx/bcm47xx.h> | ||
13 | #include <asm/mach-bcm47xx/gpio.h> | ||
14 | |||
15 | int bcm47xx_gpio_to_irq(unsigned gpio) | ||
16 | { | ||
17 | if (ssb_bcm47xx.chipco.dev) | ||
18 | return ssb_mips_irq(ssb_bcm47xx.chipco.dev) + 2; | ||
19 | else if (ssb_bcm47xx.extif.dev) | ||
20 | return ssb_mips_irq(ssb_bcm47xx.extif.dev) + 2; | ||
21 | else | ||
22 | return -EINVAL; | ||
23 | } | ||
24 | EXPORT_SYMBOL_GPL(bcm47xx_gpio_to_irq); | ||
25 | |||
26 | int bcm47xx_gpio_get_value(unsigned gpio) | ||
27 | { | ||
28 | if (ssb_bcm47xx.chipco.dev) | ||
29 | return ssb_chipco_gpio_in(&ssb_bcm47xx.chipco, 1 << gpio); | ||
30 | else if (ssb_bcm47xx.extif.dev) | ||
31 | return ssb_extif_gpio_in(&ssb_bcm47xx.extif, 1 << gpio); | ||
32 | else | ||
33 | return 0; | ||
34 | } | ||
35 | EXPORT_SYMBOL_GPL(bcm47xx_gpio_get_value); | ||
36 | |||
37 | void bcm47xx_gpio_set_value(unsigned gpio, int value) | ||
38 | { | ||
39 | if (ssb_bcm47xx.chipco.dev) | ||
40 | ssb_chipco_gpio_out(&ssb_bcm47xx.chipco, | ||
41 | 1 << gpio, | ||
42 | value ? 1 << gpio : 0); | ||
43 | else if (ssb_bcm47xx.extif.dev) | ||
44 | ssb_extif_gpio_out(&ssb_bcm47xx.extif, | ||
45 | 1 << gpio, | ||
46 | value ? 1 << gpio : 0); | ||
47 | } | ||
48 | EXPORT_SYMBOL_GPL(bcm47xx_gpio_set_value); | ||
49 | |||
50 | int bcm47xx_gpio_direction_input(unsigned gpio) | ||
51 | { | ||
52 | if (ssb_bcm47xx.chipco.dev && (gpio < BCM47XX_CHIPCO_GPIO_LINES)) | ||
53 | ssb_chipco_gpio_outen(&ssb_bcm47xx.chipco, | ||
54 | 1 << gpio, 0); | ||
55 | else if (ssb_bcm47xx.extif.dev && (gpio < BCM47XX_EXTIF_GPIO_LINES)) | ||
56 | ssb_extif_gpio_outen(&ssb_bcm47xx.extif, | ||
57 | 1 << gpio, 0); | ||
58 | else | ||
59 | return -EINVAL; | ||
60 | return 0; | ||
61 | } | ||
62 | EXPORT_SYMBOL_GPL(bcm47xx_gpio_direction_input); | ||
63 | |||
64 | int bcm47xx_gpio_direction_output(unsigned gpio, int value) | ||
65 | { | ||
66 | bcm47xx_gpio_set_value(gpio, value); | ||
67 | |||
68 | if (ssb_bcm47xx.chipco.dev && (gpio < BCM47XX_CHIPCO_GPIO_LINES)) | ||
69 | ssb_chipco_gpio_outen(&ssb_bcm47xx.chipco, | ||
70 | 1 << gpio, 1 << gpio); | ||
71 | else if (ssb_bcm47xx.extif.dev && (gpio < BCM47XX_EXTIF_GPIO_LINES)) | ||
72 | ssb_extif_gpio_outen(&ssb_bcm47xx.extif, | ||
73 | 1 << gpio, 1 << gpio); | ||
74 | else | ||
75 | return -EINVAL; | ||
76 | return 0; | ||
77 | } | ||
78 | EXPORT_SYMBOL_GPL(bcm47xx_gpio_direction_output); | ||
79 | |||
diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c new file mode 100644 index 000000000000..325757acd020 --- /dev/null +++ b/arch/mips/bcm47xx/irq.c | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> | ||
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 as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | * | ||
9 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
10 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
12 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
13 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
14 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
15 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
16 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
17 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
18 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along | ||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | #include <linux/types.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/irq.h> | ||
28 | #include <asm/irq_cpu.h> | ||
29 | |||
30 | void plat_irq_dispatch(void) | ||
31 | { | ||
32 | u32 cause; | ||
33 | |||
34 | cause = read_c0_cause() & read_c0_status() & CAUSEF_IP; | ||
35 | |||
36 | clear_c0_status(cause); | ||
37 | |||
38 | if (cause & CAUSEF_IP7) | ||
39 | do_IRQ(7); | ||
40 | if (cause & CAUSEF_IP2) | ||
41 | do_IRQ(2); | ||
42 | if (cause & CAUSEF_IP3) | ||
43 | do_IRQ(3); | ||
44 | if (cause & CAUSEF_IP4) | ||
45 | do_IRQ(4); | ||
46 | if (cause & CAUSEF_IP5) | ||
47 | do_IRQ(5); | ||
48 | if (cause & CAUSEF_IP6) | ||
49 | do_IRQ(6); | ||
50 | } | ||
51 | |||
52 | void __init arch_init_irq(void) | ||
53 | { | ||
54 | mips_cpu_irq_init(); | ||
55 | } | ||
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c new file mode 100644 index 000000000000..079e33d52783 --- /dev/null +++ b/arch/mips/bcm47xx/prom.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> | ||
3 | * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | * | ||
10 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
11 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
12 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
13 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
14 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
15 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
16 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
17 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
18 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
19 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License along | ||
22 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
23 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | */ | ||
25 | |||
26 | #include <linux/init.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <asm/bootinfo.h> | ||
31 | #include <asm/fw/cfe/cfe_api.h> | ||
32 | #include <asm/fw/cfe/cfe_error.h> | ||
33 | |||
34 | static int cfe_cons_handle; | ||
35 | |||
36 | const char *get_system_type(void) | ||
37 | { | ||
38 | return "Broadcom BCM47XX"; | ||
39 | } | ||
40 | |||
41 | void prom_putchar(char c) | ||
42 | { | ||
43 | while (cfe_write(cfe_cons_handle, &c, 1) == 0) | ||
44 | ; | ||
45 | } | ||
46 | |||
47 | static __init void prom_init_cfe(void) | ||
48 | { | ||
49 | uint32_t cfe_ept; | ||
50 | uint32_t cfe_handle; | ||
51 | uint32_t cfe_eptseal; | ||
52 | int argc = fw_arg0; | ||
53 | char **envp = (char **) fw_arg2; | ||
54 | int *prom_vec = (int *) fw_arg3; | ||
55 | |||
56 | /* | ||
57 | * Check if a loader was used; if NOT, the 4 arguments are | ||
58 | * what CFE gives us (handle, 0, EPT and EPTSEAL) | ||
59 | */ | ||
60 | if (argc < 0) { | ||
61 | cfe_handle = (uint32_t)argc; | ||
62 | cfe_ept = (uint32_t)envp; | ||
63 | cfe_eptseal = (uint32_t)prom_vec; | ||
64 | } else { | ||
65 | if ((int)prom_vec < 0) { | ||
66 | /* | ||
67 | * Old loader; all it gives us is the handle, | ||
68 | * so use the "known" entrypoint and assume | ||
69 | * the seal. | ||
70 | */ | ||
71 | cfe_handle = (uint32_t)prom_vec; | ||
72 | cfe_ept = 0xBFC00500; | ||
73 | cfe_eptseal = CFE_EPTSEAL; | ||
74 | } else { | ||
75 | /* | ||
76 | * Newer loaders bundle the handle/ept/eptseal | ||
77 | * Note: prom_vec is in the loader's useg | ||
78 | * which is still alive in the TLB. | ||
79 | */ | ||
80 | cfe_handle = prom_vec[0]; | ||
81 | cfe_ept = prom_vec[2]; | ||
82 | cfe_eptseal = prom_vec[3]; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | if (cfe_eptseal != CFE_EPTSEAL) { | ||
87 | /* too early for panic to do any good */ | ||
88 | printk(KERN_ERR "CFE's entrypoint seal doesn't match."); | ||
89 | while (1) ; | ||
90 | } | ||
91 | |||
92 | cfe_init(cfe_handle, cfe_ept); | ||
93 | } | ||
94 | |||
95 | static __init void prom_init_console(void) | ||
96 | { | ||
97 | /* Initialize CFE console */ | ||
98 | cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); | ||
99 | } | ||
100 | |||
101 | static __init void prom_init_cmdline(void) | ||
102 | { | ||
103 | char buf[CL_SIZE]; | ||
104 | |||
105 | /* Get the kernel command line from CFE */ | ||
106 | if (cfe_getenv("LINUX_CMDLINE", buf, CL_SIZE) >= 0) { | ||
107 | buf[CL_SIZE-1] = 0; | ||
108 | strcpy(arcs_cmdline, buf); | ||
109 | } | ||
110 | |||
111 | /* Force a console handover by adding a console= argument if needed, | ||
112 | * as CFE is not available anymore later in the boot process. */ | ||
113 | if ((strstr(arcs_cmdline, "console=")) == NULL) { | ||
114 | /* Try to read the default serial port used by CFE */ | ||
115 | if ((cfe_getenv("BOOT_CONSOLE", buf, CL_SIZE) < 0) | ||
116 | || (strncmp("uart", buf, 4))) | ||
117 | /* Default to uart0 */ | ||
118 | strcpy(buf, "uart0"); | ||
119 | |||
120 | /* Compute the new command line */ | ||
121 | snprintf(arcs_cmdline, CL_SIZE, "%s console=ttyS%c,115200", | ||
122 | arcs_cmdline, buf[4]); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | static __init void prom_init_mem(void) | ||
127 | { | ||
128 | unsigned long mem; | ||
129 | |||
130 | /* Figure out memory size by finding aliases. | ||
131 | * | ||
132 | * We should theoretically use the mapping from CFE using cfe_enummem(). | ||
133 | * However as the BCM47XX is mostly used on low-memory systems, we | ||
134 | * want to reuse the memory used by CFE (around 4MB). That means cfe_* | ||
135 | * functions stop to work at some point during the boot, we should only | ||
136 | * call them at the beginning of the boot. | ||
137 | */ | ||
138 | for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) { | ||
139 | if (*(unsigned long *)((unsigned long)(prom_init) + mem) == | ||
140 | *(unsigned long *)(prom_init)) | ||
141 | break; | ||
142 | } | ||
143 | |||
144 | add_memory_region(0, mem, BOOT_MEM_RAM); | ||
145 | } | ||
146 | |||
147 | void __init prom_init(void) | ||
148 | { | ||
149 | prom_init_cfe(); | ||
150 | prom_init_console(); | ||
151 | prom_init_cmdline(); | ||
152 | prom_init_mem(); | ||
153 | } | ||
154 | |||
155 | void __init prom_free_prom_memory(void) | ||
156 | { | ||
157 | } | ||
158 | |||
diff --git a/arch/mips/bcm47xx/serial.c b/arch/mips/bcm47xx/serial.c new file mode 100644 index 000000000000..59c11afdb2ab --- /dev/null +++ b/arch/mips/bcm47xx/serial.c | |||
@@ -0,0 +1,52 @@ | |||
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) 2007 Aurelien Jarno <aurelien@aurel32.net> | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/serial.h> | ||
12 | #include <linux/serial_8250.h> | ||
13 | #include <linux/ssb/ssb.h> | ||
14 | #include <bcm47xx.h> | ||
15 | |||
16 | static struct plat_serial8250_port uart8250_data[5]; | ||
17 | |||
18 | static struct platform_device uart8250_device = { | ||
19 | .name = "serial8250", | ||
20 | .id = PLAT8250_DEV_PLATFORM, | ||
21 | .dev = { | ||
22 | .platform_data = uart8250_data, | ||
23 | }, | ||
24 | }; | ||
25 | |||
26 | static int __init uart8250_init(void) | ||
27 | { | ||
28 | int i; | ||
29 | struct ssb_mipscore *mcore = &(ssb_bcm47xx.mipscore); | ||
30 | |||
31 | memset(&uart8250_data, 0, sizeof(uart8250_data)); | ||
32 | |||
33 | for (i = 0; i < mcore->nr_serial_ports; i++) { | ||
34 | struct plat_serial8250_port *p = &(uart8250_data[i]); | ||
35 | struct ssb_serial_port *ssb_port = &(mcore->serial_ports[i]); | ||
36 | |||
37 | p->mapbase = (unsigned int) ssb_port->regs; | ||
38 | p->membase = (void *) ssb_port->regs; | ||
39 | p->irq = ssb_port->irq + 2; | ||
40 | p->uartclk = ssb_port->baud_base; | ||
41 | p->regshift = ssb_port->reg_shift; | ||
42 | p->iotype = UPIO_MEM; | ||
43 | p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; | ||
44 | } | ||
45 | return platform_device_register(&uart8250_device); | ||
46 | } | ||
47 | |||
48 | module_init(uart8250_init); | ||
49 | |||
50 | MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>"); | ||
51 | MODULE_LICENSE("GPL"); | ||
52 | MODULE_DESCRIPTION("8250 UART probe driver for the BCM47XX platforms"); | ||
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c new file mode 100644 index 000000000000..1b6b0fa5028f --- /dev/null +++ b/arch/mips/bcm47xx/setup.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> | ||
3 | * Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org> | ||
4 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | ||
5 | * Copyright (C) 2006 Michael Buesch <mb@bu3sch.de> | ||
6 | * | ||
7 | * 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 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
13 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
14 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
15 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
16 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
17 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
18 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
19 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
20 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
21 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License along | ||
24 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
25 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | */ | ||
27 | |||
28 | #include <linux/types.h> | ||
29 | #include <linux/ssb/ssb.h> | ||
30 | #include <asm/bootinfo.h> | ||
31 | #include <asm/reboot.h> | ||
32 | #include <asm/time.h> | ||
33 | #include <bcm47xx.h> | ||
34 | #include <asm/fw/cfe/cfe_api.h> | ||
35 | |||
36 | struct ssb_bus ssb_bcm47xx; | ||
37 | EXPORT_SYMBOL(ssb_bcm47xx); | ||
38 | |||
39 | static void bcm47xx_machine_restart(char *command) | ||
40 | { | ||
41 | printk(KERN_ALERT "Please stand by while rebooting the system...\n"); | ||
42 | local_irq_disable(); | ||
43 | /* Set the watchdog timer to reset immediately */ | ||
44 | ssb_chipco_watchdog_timer_set(&ssb_bcm47xx.chipco, 1); | ||
45 | while (1) | ||
46 | cpu_relax(); | ||
47 | } | ||
48 | |||
49 | static void bcm47xx_machine_halt(void) | ||
50 | { | ||
51 | /* Disable interrupts and watchdog and spin forever */ | ||
52 | local_irq_disable(); | ||
53 | ssb_chipco_watchdog_timer_set(&ssb_bcm47xx.chipco, 0); | ||
54 | while (1) | ||
55 | cpu_relax(); | ||
56 | } | ||
57 | |||
58 | static void str2eaddr(char *str, char *dest) | ||
59 | { | ||
60 | int i = 0; | ||
61 | |||
62 | if (str == NULL) { | ||
63 | memset(dest, 0, 6); | ||
64 | return; | ||
65 | } | ||
66 | |||
67 | for (;;) { | ||
68 | dest[i++] = (char) simple_strtoul(str, NULL, 16); | ||
69 | str += 2; | ||
70 | if (!*str++ || i == 6) | ||
71 | break; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | static int bcm47xx_get_invariants(struct ssb_bus *bus, | ||
76 | struct ssb_init_invariants *iv) | ||
77 | { | ||
78 | char buf[100]; | ||
79 | |||
80 | /* Fill boardinfo structure */ | ||
81 | memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo)); | ||
82 | |||
83 | if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0) | ||
84 | iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); | ||
85 | if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0) | ||
86 | iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); | ||
87 | if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0) | ||
88 | iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0); | ||
89 | |||
90 | /* Fill sprom structure */ | ||
91 | memset(&(iv->sprom), 0, sizeof(struct ssb_sprom)); | ||
92 | iv->sprom.revision = 3; | ||
93 | |||
94 | if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0) | ||
95 | str2eaddr(buf, iv->sprom.r1.et0mac); | ||
96 | if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0) | ||
97 | str2eaddr(buf, iv->sprom.r1.et1mac); | ||
98 | if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0) | ||
99 | iv->sprom.r1.et0phyaddr = simple_strtoul(buf, NULL, 10); | ||
100 | if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0) | ||
101 | iv->sprom.r1.et1phyaddr = simple_strtoul(buf, NULL, 10); | ||
102 | if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0) | ||
103 | iv->sprom.r1.et0mdcport = simple_strtoul(buf, NULL, 10); | ||
104 | if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0) | ||
105 | iv->sprom.r1.et1mdcport = simple_strtoul(buf, NULL, 10); | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | void __init plat_mem_setup(void) | ||
111 | { | ||
112 | int err; | ||
113 | |||
114 | err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, | ||
115 | bcm47xx_get_invariants); | ||
116 | if (err) | ||
117 | panic("Failed to initialize SSB bus (err %d)\n", err); | ||
118 | |||
119 | _machine_restart = bcm47xx_machine_restart; | ||
120 | _machine_halt = bcm47xx_machine_halt; | ||
121 | pm_power_off = bcm47xx_machine_halt; | ||
122 | } | ||
123 | |||
diff --git a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c new file mode 100644 index 000000000000..0ab4676c8bd3 --- /dev/null +++ b/arch/mips/bcm47xx/time.c | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> | ||
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 as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | * | ||
9 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
10 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
12 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
13 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
14 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
15 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
16 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
17 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
18 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along | ||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | |||
26 | #include <linux/init.h> | ||
27 | #include <linux/ssb/ssb.h> | ||
28 | #include <asm/time.h> | ||
29 | #include <bcm47xx.h> | ||
30 | |||
31 | void __init plat_time_init(void) | ||
32 | { | ||
33 | unsigned long hz; | ||
34 | |||
35 | /* | ||
36 | * Use deterministic values for initial counter interrupt | ||
37 | * so that calibrate delay avoids encountering a counter wrap. | ||
38 | */ | ||
39 | write_c0_count(0); | ||
40 | write_c0_compare(0xffff); | ||
41 | |||
42 | hz = ssb_cpu_clock(&ssb_bcm47xx.mipscore) / 2; | ||
43 | if (!hz) | ||
44 | hz = 100000000; | ||
45 | |||
46 | /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */ | ||
47 | mips_hpt_frequency = hz; | ||
48 | } | ||
49 | |||
50 | void __init | ||
51 | plat_timer_setup(struct irqaction *irq) | ||
52 | { | ||
53 | /* Enable the timer interrupt */ | ||
54 | setup_irq(7, irq); | ||
55 | } | ||
diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c new file mode 100644 index 000000000000..5a017eaee712 --- /dev/null +++ b/arch/mips/bcm47xx/wgt634u.c | |||
@@ -0,0 +1,64 @@ | |||
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) 2007 Aurelien Jarno <aurelien@aurel32.net> | ||
7 | */ | ||
8 | |||
9 | #include <linux/platform_device.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/leds.h> | ||
12 | #include <linux/ssb/ssb.h> | ||
13 | #include <asm/mach-bcm47xx/bcm47xx.h> | ||
14 | |||
15 | /* GPIO definitions for the WGT634U */ | ||
16 | #define WGT634U_GPIO_LED 3 | ||
17 | #define WGT634U_GPIO_RESET 2 | ||
18 | #define WGT634U_GPIO_TP1 7 | ||
19 | #define WGT634U_GPIO_TP2 6 | ||
20 | #define WGT634U_GPIO_TP3 5 | ||
21 | #define WGT634U_GPIO_TP4 4 | ||
22 | #define WGT634U_GPIO_TP5 1 | ||
23 | |||
24 | static struct gpio_led wgt634u_leds[] = { | ||
25 | { | ||
26 | .name = "power", | ||
27 | .gpio = WGT634U_GPIO_LED, | ||
28 | .active_low = 1, | ||
29 | .default_trigger = "heartbeat", | ||
30 | }, | ||
31 | }; | ||
32 | |||
33 | static struct gpio_led_platform_data wgt634u_led_data = { | ||
34 | .num_leds = ARRAY_SIZE(wgt634u_leds), | ||
35 | .leds = wgt634u_leds, | ||
36 | }; | ||
37 | |||
38 | static struct platform_device wgt634u_gpio_leds = { | ||
39 | .name = "leds-gpio", | ||
40 | .id = -1, | ||
41 | .dev = { | ||
42 | .platform_data = &wgt634u_led_data, | ||
43 | } | ||
44 | }; | ||
45 | |||
46 | static int __init wgt634u_init(void) | ||
47 | { | ||
48 | /* There is no easy way to detect that we are running on a WGT634U | ||
49 | * machine. Use the MAC address as an heuristic. Netgear Inc. has | ||
50 | * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx. | ||
51 | */ | ||
52 | |||
53 | u8 *et0mac = ssb_bcm47xx.sprom.r1.et0mac; | ||
54 | |||
55 | if (et0mac[0] == 0x00 && | ||
56 | ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) || | ||
57 | (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) | ||
58 | return platform_device_register(&wgt634u_gpio_leds); | ||
59 | else | ||
60 | return -ENODEV; | ||
61 | } | ||
62 | |||
63 | module_init(wgt634u_init); | ||
64 | |||