Pull button into test branch
[linux-drm-fsl-dcu.git] / arch / powerpc / platforms / embedded6xx / linkstation.c
1 /*
2  * Board setup routines for the Buffalo Linkstation / Kurobox Platform.
3  *
4  * Copyright (C) 2006 G. Liakhovetski (g.liakhovetski@gmx.de)
5  *
6  * Based on sandpoint.c by Mark A. Greer
7  *
8  * This file is licensed under the terms of the GNU General Public License
9  * version 2.  This program is licensed "as is" without any warranty of
10  * any kind, whether express or implied.
11  */
12
13 #include <linux/kernel.h>
14 #include <linux/pci.h>
15 #include <linux/initrd.h>
16 #include <linux/root_dev.h>
17 #include <linux/mtd/physmap.h>
18
19 #include <asm/time.h>
20 #include <asm/prom.h>
21 #include <asm/mpic.h>
22 #include <asm/mpc10x.h>
23 #include <asm/pci-bridge.h>
24
25 static struct mtd_partition linkstation_physmap_partitions[] = {
26         {
27                 .name   = "mtd_firmimg",
28                 .offset = 0x000000,
29                 .size   = 0x300000,
30         },
31         {
32                 .name   = "mtd_bootcode",
33                 .offset = 0x300000,
34                 .size   = 0x070000,
35         },
36         {
37                 .name   = "mtd_status",
38                 .offset = 0x370000,
39                 .size   = 0x010000,
40         },
41         {
42                 .name   = "mtd_conf",
43                 .offset = 0x380000,
44                 .size   = 0x080000,
45         },
46         {
47                 .name   = "mtd_allflash",
48                 .offset = 0x000000,
49                 .size   = 0x400000,
50         },
51         {
52                 .name   = "mtd_data",
53                 .offset = 0x310000,
54                 .size   = 0x0f0000,
55         },
56 };
57
58 static int __init add_bridge(struct device_node *dev)
59 {
60         int len;
61         struct pci_controller *hose;
62         int *bus_range;
63
64         printk("Adding PCI host bridge %s\n", dev->full_name);
65
66         bus_range = (int *) get_property(dev, "bus-range", &len);
67         if (bus_range == NULL || len < 2 * sizeof(int))
68                 printk(KERN_WARNING "Can't get bus-range for %s, assume"
69                                 " bus 0\n", dev->full_name);
70
71         hose = pcibios_alloc_controller();
72         if (hose == NULL)
73                 return -ENOMEM;
74         hose->first_busno = bus_range ? bus_range[0] : 0;
75         hose->last_busno = bus_range ? bus_range[1] : 0xff;
76         hose->arch_data = dev;
77         setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
78
79         /* Interpret the "ranges" property */
80         /* This also maps the I/O region and sets isa_io/mem_base */
81         pci_process_bridge_OF_ranges(hose, dev, 1);
82
83         return 0;
84 }
85
86 static void __init linkstation_setup_arch(void)
87 {
88         struct device_node *np;
89 #ifdef CONFIG_MTD_PHYSMAP
90         physmap_set_partitions(linkstation_physmap_partitions,
91                                ARRAY_SIZE(linkstation_physmap_partitions));
92 #endif
93
94 #ifdef CONFIG_BLK_DEV_INITRD
95         if (initrd_start)
96                 ROOT_DEV = Root_RAM0;
97         else
98 #endif
99 #ifdef  CONFIG_ROOT_NFS
100                 ROOT_DEV = Root_NFS;
101 #else
102                 ROOT_DEV = Root_HDA1;
103 #endif
104
105         /* Lookup PCI host bridges */
106         for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
107                 add_bridge(np);
108
109         printk(KERN_INFO "BUFFALO Network Attached Storage Series\n");
110         printk(KERN_INFO "(C) 2002-2005 BUFFALO INC.\n");
111 }
112
113 /*
114  * Interrupt setup and service.  Interrrupts on the linkstation come
115  * from the four PCI slots plus onboard 8241 devices: I2C, DUART.
116  */
117 static void __init linkstation_init_IRQ(void)
118 {
119         struct mpic *mpic;
120         struct device_node *dnp;
121         void *prop;
122         int size;
123         phys_addr_t paddr;
124
125         dnp = of_find_node_by_type(NULL, "open-pic");
126         if (dnp == NULL)
127                 return;
128
129         prop = (struct device_node *)get_property(dnp, "reg", &size);
130         paddr = (phys_addr_t)of_translate_address(dnp, prop);
131
132         mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, 4, 32, " EPIC     ");
133         BUG_ON(mpic == NULL);
134
135         /* PCI IRQs */
136         mpic_assign_isu(mpic, 0, paddr + 0x10200);
137
138         /* I2C */
139         mpic_assign_isu(mpic, 1, paddr + 0x11000);
140
141         /* ttyS0, ttyS1 */
142         mpic_assign_isu(mpic, 2, paddr + 0x11100);
143
144         mpic_init(mpic);
145 }
146
147 extern void avr_uart_configure(void);
148 extern void avr_uart_send(const char);
149
150 static void linkstation_restart(char *cmd)
151 {
152         local_irq_disable();
153
154         /* Reset system via AVR */
155         avr_uart_configure();
156         /* Send reboot command */
157         avr_uart_send('C');
158
159         for(;;)  /* Spin until reset happens */
160                 avr_uart_send('G');     /* "kick" */
161 }
162
163 static void linkstation_power_off(void)
164 {
165         local_irq_disable();
166
167         /* Power down system via AVR */
168         avr_uart_configure();
169         /* send shutdown command */
170         avr_uart_send('E');
171
172         for(;;)  /* Spin until power-off happens */
173                 avr_uart_send('G');     /* "kick" */
174         /* NOTREACHED */
175 }
176
177 static void linkstation_halt(void)
178 {
179         linkstation_power_off();
180         /* NOTREACHED */
181 }
182
183 static void linkstation_show_cpuinfo(struct seq_file *m)
184 {
185         seq_printf(m, "vendor\t\t: Buffalo Technology\n");
186         seq_printf(m, "machine\t\t: Linkstation I/Kurobox(HG)\n");
187 }
188
189 static int __init linkstation_probe(void)
190 {
191         unsigned long root;
192
193         root = of_get_flat_dt_root();
194
195         if (!of_flat_dt_is_compatible(root, "linkstation"))
196                 return 0;
197         return 1;
198 }
199
200 define_machine(linkstation){
201         .name                   = "Buffalo Linkstation",
202         .probe                  = linkstation_probe,
203         .setup_arch             = linkstation_setup_arch,
204         .init_IRQ               = linkstation_init_IRQ,
205         .show_cpuinfo           = linkstation_show_cpuinfo,
206         .get_irq                = mpic_get_irq,
207         .restart                = linkstation_restart,
208         .power_off              = linkstation_power_off,
209         .halt                   = linkstation_halt,
210         .calibrate_decr         = generic_calibrate_decr,
211 };