aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-orion5x/ts209-setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-orion5x/ts209-setup.c')
-rw-r--r--arch/arm/mach-orion5x/ts209-setup.c125
1 files changed, 7 insertions, 118 deletions
diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c
index 80b62329f58..a9cef9703d5 100644
--- a/arch/arm/mach-orion5x/ts209-setup.c
+++ b/arch/arm/mach-orion5x/ts209-setup.c
@@ -29,6 +29,7 @@
29#include <asm/arch/orion5x.h> 29#include <asm/arch/orion5x.h>
30#include "common.h" 30#include "common.h"
31#include "mpp.h" 31#include "mpp.h"
32#include "tsx09-common.h"
32 33
33#define QNAP_TS209_NOR_BOOT_BASE 0xf4000000 34#define QNAP_TS209_NOR_BOOT_BASE 0xf4000000
34#define QNAP_TS209_NOR_BOOT_SIZE SZ_8M 35#define QNAP_TS209_NOR_BOOT_SIZE SZ_8M
@@ -186,95 +187,6 @@ static int __init qnap_ts209_pci_init(void)
186subsys_initcall(qnap_ts209_pci_init); 187subsys_initcall(qnap_ts209_pci_init);
187 188
188/***************************************************************************** 189/*****************************************************************************
189 * Ethernet
190 ****************************************************************************/
191
192static struct mv643xx_eth_platform_data qnap_ts209_eth_data = {
193 .phy_addr = 8,
194};
195
196static int __init parse_hex_nibble(char n)
197{
198 if (n >= '0' && n <= '9')
199 return n - '0';
200
201 if (n >= 'A' && n <= 'F')
202 return n - 'A' + 10;
203
204 if (n >= 'a' && n <= 'f')
205 return n - 'a' + 10;
206
207 return -1;
208}
209
210static int __init parse_hex_byte(const char *b)
211{
212 int hi;
213 int lo;
214
215 hi = parse_hex_nibble(b[0]);
216 lo = parse_hex_nibble(b[1]);
217
218 if (hi < 0 || lo < 0)
219 return -1;
220
221 return (hi << 4) | lo;
222}
223
224static int __init check_mac_addr(const char *addr_str)
225{
226 u_int8_t addr[6];
227 int i;
228
229 for (i = 0; i < 6; i++) {
230 int byte;
231
232 /*
233 * Enforce "xx:xx:xx:xx:xx:xx\n" format.
234 */
235 if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n'))
236 return -1;
237
238 byte = parse_hex_byte(addr_str + (i * 3));
239 if (byte < 0)
240 return -1;
241 addr[i] = byte;
242 }
243
244 printk(KERN_INFO "ts209: found ethernet mac address ");
245 for (i = 0; i < 6; i++)
246 printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n");
247
248 memcpy(qnap_ts209_eth_data.mac_addr, addr, 6);
249
250 return 0;
251}
252
253/*
254 * The 'NAS Config' flash partition has an ext2 filesystem which
255 * contains a file that has the ethernet MAC address in plain text
256 * (format "xx:xx:xx:xx:xx:xx\n".)
257 */
258static void __init ts209_find_mac_addr(void)
259{
260 unsigned long addr;
261
262 for (addr = 0x00700000; addr < 0x00760000; addr += 1024) {
263 char *nor_page;
264 int ret = 0;
265
266 nor_page = ioremap(QNAP_TS209_NOR_BOOT_BASE + addr, 1024);
267 if (nor_page != NULL) {
268 ret = check_mac_addr(nor_page);
269 iounmap(nor_page);
270 }
271
272 if (ret == 0)
273 break;
274 }
275}
276
277/*****************************************************************************
278 * RTC S35390A on I2C bus 190 * RTC S35390A on I2C bus
279 ****************************************************************************/ 191 ****************************************************************************/
280 192
@@ -356,31 +268,6 @@ static struct orion5x_mpp_mode ts209_mpp_modes[] __initdata = {
356 { -1 }, 268 { -1 },
357}; 269};
358 270
359/*
360 * QNAP TS-[12]09 specific power off method via UART1-attached PIC
361 */
362#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
363
364static void qnap_ts209_power_off(void)
365{
366 /* 19200 baud divisor */
367 const unsigned divisor = ((ORION5X_TCLK + (8 * 19200)) / (16 * 19200));
368
369 pr_info("%s: triggering power-off...\n", __func__);
370
371 /* hijack uart1 and reset into sane state (19200,8n1) */
372 orion5x_write(UART1_REG(LCR), 0x83);
373 orion5x_write(UART1_REG(DLL), divisor & 0xff);
374 orion5x_write(UART1_REG(DLM), (divisor >> 8) & 0xff);
375 orion5x_write(UART1_REG(LCR), 0x03);
376 orion5x_write(UART1_REG(IER), 0x00);
377 orion5x_write(UART1_REG(FCR), 0x00);
378 orion5x_write(UART1_REG(MCR), 0x00);
379
380 /* send the power-off command 'A' to PIC */
381 orion5x_write(UART1_REG(TX), 'A');
382}
383
384static void __init qnap_ts209_init(void) 271static void __init qnap_ts209_init(void)
385{ 272{
386 /* 273 /*
@@ -402,8 +289,10 @@ static void __init qnap_ts209_init(void)
402 */ 289 */
403 orion5x_ehci0_init(); 290 orion5x_ehci0_init();
404 orion5x_ehci1_init(); 291 orion5x_ehci1_init();
405 ts209_find_mac_addr(); 292 qnap_tsx09_find_mac_addr(QNAP_TS209_NOR_BOOT_BASE +
406 orion5x_eth_init(&qnap_ts209_eth_data); 293 qnap_ts209_partitions[5].offset,
294 qnap_ts209_partitions[5].size);
295 orion5x_eth_init(&qnap_tsx09_eth_data);
407 orion5x_i2c_init(); 296 orion5x_i2c_init();
408 orion5x_sata_init(&qnap_ts209_sata_data); 297 orion5x_sata_init(&qnap_ts209_sata_data);
409 orion5x_uart0_init(); 298 orion5x_uart0_init();
@@ -425,8 +314,8 @@ static void __init qnap_ts209_init(void)
425 pr_warning("qnap_ts209_init: failed to get RTC IRQ\n"); 314 pr_warning("qnap_ts209_init: failed to get RTC IRQ\n");
426 i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1); 315 i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1);
427 316
428 /* register ts209 specific power-off method */ 317 /* register tsx09 specific power-off method */
429 pm_power_off = qnap_ts209_power_off; 318 pm_power_off = qnap_tsx09_power_off;
430} 319}
431 320
432MACHINE_START(TS209, "QNAP TS-109/TS-209") 321MACHINE_START(TS209, "QNAP TS-109/TS-209")