162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * arch/arm/mach-orion5x/dns323-setup.c 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org> 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Support for HW Rev C1: 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Copyright (C) 2010 Benjamin Herrenschmidt <benh@kernel.crashing.org> 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * This program is free software; you can redistribute it and/or modify 1162306a36Sopenharmony_ci * it under the terms of the GNU Lesser General Public License as 1262306a36Sopenharmony_ci * published by the Free Software Foundation; either version 2 of the 1362306a36Sopenharmony_ci * License, or (at your option) any later version. 1462306a36Sopenharmony_ci * 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_ci#include <linux/gpio.h> 1762306a36Sopenharmony_ci#include <linux/kernel.h> 1862306a36Sopenharmony_ci#include <linux/init.h> 1962306a36Sopenharmony_ci#include <linux/delay.h> 2062306a36Sopenharmony_ci#include <linux/platform_device.h> 2162306a36Sopenharmony_ci#include <linux/pci.h> 2262306a36Sopenharmony_ci#include <linux/irq.h> 2362306a36Sopenharmony_ci#include <linux/mtd/physmap.h> 2462306a36Sopenharmony_ci#include <linux/mv643xx_eth.h> 2562306a36Sopenharmony_ci#include <linux/leds.h> 2662306a36Sopenharmony_ci#include <linux/gpio_keys.h> 2762306a36Sopenharmony_ci#include <linux/input.h> 2862306a36Sopenharmony_ci#include <linux/i2c.h> 2962306a36Sopenharmony_ci#include <linux/ata_platform.h> 3062306a36Sopenharmony_ci#include <linux/phy.h> 3162306a36Sopenharmony_ci#include <linux/marvell_phy.h> 3262306a36Sopenharmony_ci#include <asm/mach-types.h> 3362306a36Sopenharmony_ci#include <asm/mach/arch.h> 3462306a36Sopenharmony_ci#include <asm/mach/pci.h> 3562306a36Sopenharmony_ci#include <asm/system_info.h> 3662306a36Sopenharmony_ci#include <plat/orion-gpio.h> 3762306a36Sopenharmony_ci#include "orion5x.h" 3862306a36Sopenharmony_ci#include "common.h" 3962306a36Sopenharmony_ci#include "mpp.h" 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci/* Rev A1 and B1 */ 4262306a36Sopenharmony_ci#define DNS323_GPIO_LED_RIGHT_AMBER 1 4362306a36Sopenharmony_ci#define DNS323_GPIO_LED_LEFT_AMBER 2 4462306a36Sopenharmony_ci#define DNS323_GPIO_SYSTEM_UP 3 4562306a36Sopenharmony_ci#define DNS323_GPIO_LED_POWER1 4 4662306a36Sopenharmony_ci#define DNS323_GPIO_LED_POWER2 5 4762306a36Sopenharmony_ci#define DNS323_GPIO_OVERTEMP 6 4862306a36Sopenharmony_ci#define DNS323_GPIO_RTC 7 4962306a36Sopenharmony_ci#define DNS323_GPIO_POWER_OFF 8 5062306a36Sopenharmony_ci#define DNS323_GPIO_KEY_POWER 9 5162306a36Sopenharmony_ci#define DNS323_GPIO_KEY_RESET 10 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/* Rev C1 */ 5462306a36Sopenharmony_ci#define DNS323C_GPIO_KEY_POWER 1 5562306a36Sopenharmony_ci#define DNS323C_GPIO_POWER_OFF 2 5662306a36Sopenharmony_ci#define DNS323C_GPIO_LED_RIGHT_AMBER 8 5762306a36Sopenharmony_ci#define DNS323C_GPIO_LED_LEFT_AMBER 9 5862306a36Sopenharmony_ci#define DNS323C_GPIO_LED_POWER 17 5962306a36Sopenharmony_ci#define DNS323C_GPIO_FAN_BIT1 18 6062306a36Sopenharmony_ci#define DNS323C_GPIO_FAN_BIT0 19 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci/* Exposed to userspace, do not change */ 6362306a36Sopenharmony_cienum { 6462306a36Sopenharmony_ci DNS323_REV_A1, /* 0 */ 6562306a36Sopenharmony_ci DNS323_REV_B1, /* 1 */ 6662306a36Sopenharmony_ci DNS323_REV_C1, /* 2 */ 6762306a36Sopenharmony_ci}; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci/**************************************************************************** 7162306a36Sopenharmony_ci * PCI setup 7262306a36Sopenharmony_ci */ 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic int __init dns323_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 7562306a36Sopenharmony_ci{ 7662306a36Sopenharmony_ci int irq; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci /* 7962306a36Sopenharmony_ci * Check for devices with hard-wired IRQs. 8062306a36Sopenharmony_ci */ 8162306a36Sopenharmony_ci irq = orion5x_pci_map_irq(dev, slot, pin); 8262306a36Sopenharmony_ci if (irq != -1) 8362306a36Sopenharmony_ci return irq; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci return -1; 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistatic struct hw_pci dns323_pci __initdata = { 8962306a36Sopenharmony_ci .nr_controllers = 2, 9062306a36Sopenharmony_ci .setup = orion5x_pci_sys_setup, 9162306a36Sopenharmony_ci .scan = orion5x_pci_sys_scan_bus, 9262306a36Sopenharmony_ci .map_irq = dns323_pci_map_irq, 9362306a36Sopenharmony_ci}; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_cistatic int __init dns323_pci_init(void) 9662306a36Sopenharmony_ci{ 9762306a36Sopenharmony_ci /* Rev B1 and C1 doesn't really use its PCI bus, and initialising PCI 9862306a36Sopenharmony_ci * gets in the way of initialising the SATA controller. 9962306a36Sopenharmony_ci */ 10062306a36Sopenharmony_ci if (machine_is_dns323() && system_rev == DNS323_REV_A1) 10162306a36Sopenharmony_ci pci_common_init(&dns323_pci); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci return 0; 10462306a36Sopenharmony_ci} 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cisubsys_initcall(dns323_pci_init); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci/**************************************************************************** 10962306a36Sopenharmony_ci * 8MiB NOR flash (Spansion S29GL064M90TFIR4) 11062306a36Sopenharmony_ci * 11162306a36Sopenharmony_ci * Layout as used by D-Link: 11262306a36Sopenharmony_ci * 0x00000000-0x00010000 : "MTD1" 11362306a36Sopenharmony_ci * 0x00010000-0x00020000 : "MTD2" 11462306a36Sopenharmony_ci * 0x00020000-0x001a0000 : "Linux Kernel" 11562306a36Sopenharmony_ci * 0x001a0000-0x007d0000 : "File System" 11662306a36Sopenharmony_ci * 0x007d0000-0x00800000 : "u-boot" 11762306a36Sopenharmony_ci */ 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci#define DNS323_NOR_BOOT_BASE 0xf4000000 12062306a36Sopenharmony_ci#define DNS323_NOR_BOOT_SIZE SZ_8M 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_cistatic struct mtd_partition dns323_partitions[] = { 12362306a36Sopenharmony_ci { 12462306a36Sopenharmony_ci .name = "MTD1", 12562306a36Sopenharmony_ci .size = 0x00010000, 12662306a36Sopenharmony_ci .offset = 0, 12762306a36Sopenharmony_ci }, { 12862306a36Sopenharmony_ci .name = "MTD2", 12962306a36Sopenharmony_ci .size = 0x00010000, 13062306a36Sopenharmony_ci .offset = 0x00010000, 13162306a36Sopenharmony_ci }, { 13262306a36Sopenharmony_ci .name = "Linux Kernel", 13362306a36Sopenharmony_ci .size = 0x00180000, 13462306a36Sopenharmony_ci .offset = 0x00020000, 13562306a36Sopenharmony_ci }, { 13662306a36Sopenharmony_ci .name = "File System", 13762306a36Sopenharmony_ci .size = 0x00630000, 13862306a36Sopenharmony_ci .offset = 0x001A0000, 13962306a36Sopenharmony_ci }, { 14062306a36Sopenharmony_ci .name = "u-boot", 14162306a36Sopenharmony_ci .size = 0x00030000, 14262306a36Sopenharmony_ci .offset = 0x007d0000, 14362306a36Sopenharmony_ci }, 14462306a36Sopenharmony_ci}; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_cistatic struct physmap_flash_data dns323_nor_flash_data = { 14762306a36Sopenharmony_ci .width = 1, 14862306a36Sopenharmony_ci .parts = dns323_partitions, 14962306a36Sopenharmony_ci .nr_parts = ARRAY_SIZE(dns323_partitions) 15062306a36Sopenharmony_ci}; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_cistatic struct resource dns323_nor_flash_resource = { 15362306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 15462306a36Sopenharmony_ci .start = DNS323_NOR_BOOT_BASE, 15562306a36Sopenharmony_ci .end = DNS323_NOR_BOOT_BASE + DNS323_NOR_BOOT_SIZE - 1, 15662306a36Sopenharmony_ci}; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_cistatic struct platform_device dns323_nor_flash = { 15962306a36Sopenharmony_ci .name = "physmap-flash", 16062306a36Sopenharmony_ci .id = 0, 16162306a36Sopenharmony_ci .dev = { 16262306a36Sopenharmony_ci .platform_data = &dns323_nor_flash_data, 16362306a36Sopenharmony_ci }, 16462306a36Sopenharmony_ci .resource = &dns323_nor_flash_resource, 16562306a36Sopenharmony_ci .num_resources = 1, 16662306a36Sopenharmony_ci}; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci/**************************************************************************** 16962306a36Sopenharmony_ci * Ethernet 17062306a36Sopenharmony_ci */ 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_cistatic struct mv643xx_eth_platform_data dns323_eth_data = { 17362306a36Sopenharmony_ci .phy_addr = MV643XX_ETH_PHY_ADDR(8), 17462306a36Sopenharmony_ci}; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci/* dns323_parse_hex_*() taken from tsx09-common.c; should a common copy of these 17762306a36Sopenharmony_ci * functions be kept somewhere? 17862306a36Sopenharmony_ci */ 17962306a36Sopenharmony_cistatic int __init dns323_parse_hex_nibble(char n) 18062306a36Sopenharmony_ci{ 18162306a36Sopenharmony_ci if (n >= '0' && n <= '9') 18262306a36Sopenharmony_ci return n - '0'; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci if (n >= 'A' && n <= 'F') 18562306a36Sopenharmony_ci return n - 'A' + 10; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci if (n >= 'a' && n <= 'f') 18862306a36Sopenharmony_ci return n - 'a' + 10; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci return -1; 19162306a36Sopenharmony_ci} 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_cistatic int __init dns323_parse_hex_byte(const char *b) 19462306a36Sopenharmony_ci{ 19562306a36Sopenharmony_ci int hi; 19662306a36Sopenharmony_ci int lo; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci hi = dns323_parse_hex_nibble(b[0]); 19962306a36Sopenharmony_ci lo = dns323_parse_hex_nibble(b[1]); 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci if (hi < 0 || lo < 0) 20262306a36Sopenharmony_ci return -1; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci return (hi << 4) | lo; 20562306a36Sopenharmony_ci} 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_cistatic int __init dns323_read_mac_addr(void) 20862306a36Sopenharmony_ci{ 20962306a36Sopenharmony_ci u_int8_t addr[6]; 21062306a36Sopenharmony_ci int i; 21162306a36Sopenharmony_ci char *mac_page; 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci /* MAC address is stored as a regular ol' string in /dev/mtdblock4 21462306a36Sopenharmony_ci * (0x007d0000-0x00800000) starting at offset 196480 (0x2ff80). 21562306a36Sopenharmony_ci */ 21662306a36Sopenharmony_ci mac_page = ioremap(DNS323_NOR_BOOT_BASE + 0x7d0000 + 196480, 1024); 21762306a36Sopenharmony_ci if (!mac_page) 21862306a36Sopenharmony_ci return -ENOMEM; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci /* Sanity check the string we're looking at */ 22162306a36Sopenharmony_ci for (i = 0; i < 5; i++) { 22262306a36Sopenharmony_ci if (*(mac_page + (i * 3) + 2) != ':') { 22362306a36Sopenharmony_ci goto error_fail; 22462306a36Sopenharmony_ci } 22562306a36Sopenharmony_ci } 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 22862306a36Sopenharmony_ci int byte; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci byte = dns323_parse_hex_byte(mac_page + (i * 3)); 23162306a36Sopenharmony_ci if (byte < 0) { 23262306a36Sopenharmony_ci goto error_fail; 23362306a36Sopenharmony_ci } 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci addr[i] = byte; 23662306a36Sopenharmony_ci } 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci iounmap(mac_page); 23962306a36Sopenharmony_ci printk("DNS-323: Found ethernet MAC address: %pM\n", addr); 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci memcpy(dns323_eth_data.mac_addr, addr, 6); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci return 0; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_cierror_fail: 24662306a36Sopenharmony_ci iounmap(mac_page); 24762306a36Sopenharmony_ci return -EINVAL; 24862306a36Sopenharmony_ci} 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci/**************************************************************************** 25162306a36Sopenharmony_ci * GPIO LEDs (simple - doesn't use hardware blinking support) 25262306a36Sopenharmony_ci */ 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_cistatic struct gpio_led dns323ab_leds[] = { 25562306a36Sopenharmony_ci { 25662306a36Sopenharmony_ci .name = "power:blue", 25762306a36Sopenharmony_ci .gpio = DNS323_GPIO_LED_POWER2, 25862306a36Sopenharmony_ci .default_trigger = "default-on", 25962306a36Sopenharmony_ci }, { 26062306a36Sopenharmony_ci .name = "right:amber", 26162306a36Sopenharmony_ci .gpio = DNS323_GPIO_LED_RIGHT_AMBER, 26262306a36Sopenharmony_ci .active_low = 1, 26362306a36Sopenharmony_ci }, { 26462306a36Sopenharmony_ci .name = "left:amber", 26562306a36Sopenharmony_ci .gpio = DNS323_GPIO_LED_LEFT_AMBER, 26662306a36Sopenharmony_ci .active_low = 1, 26762306a36Sopenharmony_ci }, 26862306a36Sopenharmony_ci}; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_cistatic struct gpio_led dns323c_leds[] = { 27262306a36Sopenharmony_ci { 27362306a36Sopenharmony_ci .name = "power:blue", 27462306a36Sopenharmony_ci .gpio = DNS323C_GPIO_LED_POWER, 27562306a36Sopenharmony_ci .default_trigger = "timer", 27662306a36Sopenharmony_ci .active_low = 1, 27762306a36Sopenharmony_ci }, { 27862306a36Sopenharmony_ci .name = "right:amber", 27962306a36Sopenharmony_ci .gpio = DNS323C_GPIO_LED_RIGHT_AMBER, 28062306a36Sopenharmony_ci .active_low = 1, 28162306a36Sopenharmony_ci }, { 28262306a36Sopenharmony_ci .name = "left:amber", 28362306a36Sopenharmony_ci .gpio = DNS323C_GPIO_LED_LEFT_AMBER, 28462306a36Sopenharmony_ci .active_low = 1, 28562306a36Sopenharmony_ci }, 28662306a36Sopenharmony_ci}; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_cistatic struct gpio_led_platform_data dns323ab_led_data = { 29062306a36Sopenharmony_ci .num_leds = ARRAY_SIZE(dns323ab_leds), 29162306a36Sopenharmony_ci .leds = dns323ab_leds, 29262306a36Sopenharmony_ci .gpio_blink_set = orion_gpio_led_blink_set, 29362306a36Sopenharmony_ci}; 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_cistatic struct gpio_led_platform_data dns323c_led_data = { 29662306a36Sopenharmony_ci .num_leds = ARRAY_SIZE(dns323c_leds), 29762306a36Sopenharmony_ci .leds = dns323c_leds, 29862306a36Sopenharmony_ci .gpio_blink_set = orion_gpio_led_blink_set, 29962306a36Sopenharmony_ci}; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_cistatic struct platform_device dns323_gpio_leds = { 30262306a36Sopenharmony_ci .name = "leds-gpio", 30362306a36Sopenharmony_ci .id = -1, 30462306a36Sopenharmony_ci .dev = { 30562306a36Sopenharmony_ci .platform_data = &dns323ab_led_data, 30662306a36Sopenharmony_ci }, 30762306a36Sopenharmony_ci}; 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci/**************************************************************************** 31062306a36Sopenharmony_ci * GPIO Attached Keys 31162306a36Sopenharmony_ci */ 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_cistatic struct gpio_keys_button dns323ab_buttons[] = { 31462306a36Sopenharmony_ci { 31562306a36Sopenharmony_ci .code = KEY_RESTART, 31662306a36Sopenharmony_ci .gpio = DNS323_GPIO_KEY_RESET, 31762306a36Sopenharmony_ci .desc = "Reset Button", 31862306a36Sopenharmony_ci .active_low = 1, 31962306a36Sopenharmony_ci }, { 32062306a36Sopenharmony_ci .code = KEY_POWER, 32162306a36Sopenharmony_ci .gpio = DNS323_GPIO_KEY_POWER, 32262306a36Sopenharmony_ci .desc = "Power Button", 32362306a36Sopenharmony_ci .active_low = 1, 32462306a36Sopenharmony_ci }, 32562306a36Sopenharmony_ci}; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_cistatic struct gpio_keys_platform_data dns323ab_button_data = { 32862306a36Sopenharmony_ci .buttons = dns323ab_buttons, 32962306a36Sopenharmony_ci .nbuttons = ARRAY_SIZE(dns323ab_buttons), 33062306a36Sopenharmony_ci}; 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_cistatic struct gpio_keys_button dns323c_buttons[] = { 33362306a36Sopenharmony_ci { 33462306a36Sopenharmony_ci .code = KEY_POWER, 33562306a36Sopenharmony_ci .gpio = DNS323C_GPIO_KEY_POWER, 33662306a36Sopenharmony_ci .desc = "Power Button", 33762306a36Sopenharmony_ci .active_low = 1, 33862306a36Sopenharmony_ci }, 33962306a36Sopenharmony_ci}; 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_cistatic struct gpio_keys_platform_data dns323c_button_data = { 34262306a36Sopenharmony_ci .buttons = dns323c_buttons, 34362306a36Sopenharmony_ci .nbuttons = ARRAY_SIZE(dns323c_buttons), 34462306a36Sopenharmony_ci}; 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_cistatic struct platform_device dns323_button_device = { 34762306a36Sopenharmony_ci .name = "gpio-keys", 34862306a36Sopenharmony_ci .id = -1, 34962306a36Sopenharmony_ci .num_resources = 0, 35062306a36Sopenharmony_ci .dev = { 35162306a36Sopenharmony_ci .platform_data = &dns323ab_button_data, 35262306a36Sopenharmony_ci }, 35362306a36Sopenharmony_ci}; 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci/***************************************************************************** 35662306a36Sopenharmony_ci * SATA 35762306a36Sopenharmony_ci */ 35862306a36Sopenharmony_cistatic struct mv_sata_platform_data dns323_sata_data = { 35962306a36Sopenharmony_ci .n_ports = 2, 36062306a36Sopenharmony_ci}; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci/**************************************************************************** 36362306a36Sopenharmony_ci * General Setup 36462306a36Sopenharmony_ci */ 36562306a36Sopenharmony_cistatic unsigned int dns323a_mpp_modes[] __initdata = { 36662306a36Sopenharmony_ci MPP0_PCIE_RST_OUTn, 36762306a36Sopenharmony_ci MPP1_GPIO, /* right amber LED (sata ch0) */ 36862306a36Sopenharmony_ci MPP2_GPIO, /* left amber LED (sata ch1) */ 36962306a36Sopenharmony_ci MPP3_UNUSED, 37062306a36Sopenharmony_ci MPP4_GPIO, /* power button LED */ 37162306a36Sopenharmony_ci MPP5_GPIO, /* power button LED */ 37262306a36Sopenharmony_ci MPP6_GPIO, /* GMT G751-2f overtemp */ 37362306a36Sopenharmony_ci MPP7_GPIO, /* M41T80 nIRQ/OUT/SQW */ 37462306a36Sopenharmony_ci MPP8_GPIO, /* triggers power off */ 37562306a36Sopenharmony_ci MPP9_GPIO, /* power button switch */ 37662306a36Sopenharmony_ci MPP10_GPIO, /* reset button switch */ 37762306a36Sopenharmony_ci MPP11_UNUSED, 37862306a36Sopenharmony_ci MPP12_UNUSED, 37962306a36Sopenharmony_ci MPP13_UNUSED, 38062306a36Sopenharmony_ci MPP14_UNUSED, 38162306a36Sopenharmony_ci MPP15_UNUSED, 38262306a36Sopenharmony_ci MPP16_UNUSED, 38362306a36Sopenharmony_ci MPP17_UNUSED, 38462306a36Sopenharmony_ci MPP18_UNUSED, 38562306a36Sopenharmony_ci MPP19_UNUSED, 38662306a36Sopenharmony_ci 0, 38762306a36Sopenharmony_ci}; 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_cistatic unsigned int dns323b_mpp_modes[] __initdata = { 39062306a36Sopenharmony_ci MPP0_UNUSED, 39162306a36Sopenharmony_ci MPP1_GPIO, /* right amber LED (sata ch0) */ 39262306a36Sopenharmony_ci MPP2_GPIO, /* left amber LED (sata ch1) */ 39362306a36Sopenharmony_ci MPP3_GPIO, /* system up flag */ 39462306a36Sopenharmony_ci MPP4_GPIO, /* power button LED */ 39562306a36Sopenharmony_ci MPP5_GPIO, /* power button LED */ 39662306a36Sopenharmony_ci MPP6_GPIO, /* GMT G751-2f overtemp */ 39762306a36Sopenharmony_ci MPP7_GPIO, /* M41T80 nIRQ/OUT/SQW */ 39862306a36Sopenharmony_ci MPP8_GPIO, /* triggers power off */ 39962306a36Sopenharmony_ci MPP9_GPIO, /* power button switch */ 40062306a36Sopenharmony_ci MPP10_GPIO, /* reset button switch */ 40162306a36Sopenharmony_ci MPP11_UNUSED, 40262306a36Sopenharmony_ci MPP12_SATA_LED, 40362306a36Sopenharmony_ci MPP13_SATA_LED, 40462306a36Sopenharmony_ci MPP14_SATA_LED, 40562306a36Sopenharmony_ci MPP15_SATA_LED, 40662306a36Sopenharmony_ci MPP16_UNUSED, 40762306a36Sopenharmony_ci MPP17_UNUSED, 40862306a36Sopenharmony_ci MPP18_UNUSED, 40962306a36Sopenharmony_ci MPP19_UNUSED, 41062306a36Sopenharmony_ci 0, 41162306a36Sopenharmony_ci}; 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_cistatic unsigned int dns323c_mpp_modes[] __initdata = { 41462306a36Sopenharmony_ci MPP0_GPIO, /* ? input */ 41562306a36Sopenharmony_ci MPP1_GPIO, /* input power switch (0 = pressed) */ 41662306a36Sopenharmony_ci MPP2_GPIO, /* output power off */ 41762306a36Sopenharmony_ci MPP3_UNUSED, /* ? output */ 41862306a36Sopenharmony_ci MPP4_UNUSED, /* ? output */ 41962306a36Sopenharmony_ci MPP5_UNUSED, /* ? output */ 42062306a36Sopenharmony_ci MPP6_UNUSED, /* ? output */ 42162306a36Sopenharmony_ci MPP7_UNUSED, /* ? output */ 42262306a36Sopenharmony_ci MPP8_GPIO, /* i/o right amber LED */ 42362306a36Sopenharmony_ci MPP9_GPIO, /* i/o left amber LED */ 42462306a36Sopenharmony_ci MPP10_GPIO, /* input */ 42562306a36Sopenharmony_ci MPP11_UNUSED, 42662306a36Sopenharmony_ci MPP12_SATA_LED, 42762306a36Sopenharmony_ci MPP13_SATA_LED, 42862306a36Sopenharmony_ci MPP14_SATA_LED, 42962306a36Sopenharmony_ci MPP15_SATA_LED, 43062306a36Sopenharmony_ci MPP16_UNUSED, 43162306a36Sopenharmony_ci MPP17_GPIO, /* power button LED */ 43262306a36Sopenharmony_ci MPP18_GPIO, /* fan speed bit 0 */ 43362306a36Sopenharmony_ci MPP19_GPIO, /* fan speed bit 1 */ 43462306a36Sopenharmony_ci 0, 43562306a36Sopenharmony_ci}; 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ci/* Rev C1 Fan speed notes: 43862306a36Sopenharmony_ci * 43962306a36Sopenharmony_ci * The fan is controlled by 2 GPIOs on this board. The settings 44062306a36Sopenharmony_ci * of the bits is as follow: 44162306a36Sopenharmony_ci * 44262306a36Sopenharmony_ci * GPIO 18 GPIO 19 Fan 44362306a36Sopenharmony_ci * 44462306a36Sopenharmony_ci * 0 0 stopped 44562306a36Sopenharmony_ci * 0 1 low speed 44662306a36Sopenharmony_ci * 1 0 high speed 44762306a36Sopenharmony_ci * 1 1 don't do that (*) 44862306a36Sopenharmony_ci * 44962306a36Sopenharmony_ci * (*) I think the two bits control two feed-in resistors into a fixed 45062306a36Sopenharmony_ci * PWN circuit, setting both bits will basically go a 'bit' faster 45162306a36Sopenharmony_ci * than high speed, but d-link doesn't do it and you may get out of 45262306a36Sopenharmony_ci * HW spec so don't do it. 45362306a36Sopenharmony_ci */ 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci/* 45662306a36Sopenharmony_ci * On the DNS-323 A1 and B1 the following devices are attached via I2C: 45762306a36Sopenharmony_ci * 45862306a36Sopenharmony_ci * i2c addr | chip | description 45962306a36Sopenharmony_ci * 0x3e | GMT G760Af | fan speed PWM controller 46062306a36Sopenharmony_ci * 0x48 | GMT G751-2f | temp. sensor and therm. watchdog (LM75 compatible) 46162306a36Sopenharmony_ci * 0x68 | ST M41T80 | RTC w/ alarm 46262306a36Sopenharmony_ci */ 46362306a36Sopenharmony_cistatic struct i2c_board_info __initdata dns323ab_i2c_devices[] = { 46462306a36Sopenharmony_ci { 46562306a36Sopenharmony_ci I2C_BOARD_INFO("g760a", 0x3e), 46662306a36Sopenharmony_ci }, { 46762306a36Sopenharmony_ci I2C_BOARD_INFO("lm75", 0x48), 46862306a36Sopenharmony_ci }, { 46962306a36Sopenharmony_ci I2C_BOARD_INFO("m41t80", 0x68), 47062306a36Sopenharmony_ci }, 47162306a36Sopenharmony_ci}; 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci/* 47462306a36Sopenharmony_ci * On the DNS-323 C1 the following devices are attached via I2C: 47562306a36Sopenharmony_ci * 47662306a36Sopenharmony_ci * i2c addr | chip | description 47762306a36Sopenharmony_ci * 0x48 | GMT G751-2f | temp. sensor and therm. watchdog (LM75 compatible) 47862306a36Sopenharmony_ci * 0x68 | ST M41T80 | RTC w/ alarm 47962306a36Sopenharmony_ci */ 48062306a36Sopenharmony_cistatic struct i2c_board_info __initdata dns323c_i2c_devices[] = { 48162306a36Sopenharmony_ci { 48262306a36Sopenharmony_ci I2C_BOARD_INFO("lm75", 0x48), 48362306a36Sopenharmony_ci }, { 48462306a36Sopenharmony_ci I2C_BOARD_INFO("m41t80", 0x68), 48562306a36Sopenharmony_ci }, 48662306a36Sopenharmony_ci}; 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci/* DNS-323 rev. A specific power off method */ 48962306a36Sopenharmony_cistatic void dns323a_power_off(void) 49062306a36Sopenharmony_ci{ 49162306a36Sopenharmony_ci pr_info("DNS-323: Triggering power-off...\n"); 49262306a36Sopenharmony_ci gpio_set_value(DNS323_GPIO_POWER_OFF, 1); 49362306a36Sopenharmony_ci} 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci/* DNS-323 rev B specific power off method */ 49662306a36Sopenharmony_cistatic void dns323b_power_off(void) 49762306a36Sopenharmony_ci{ 49862306a36Sopenharmony_ci pr_info("DNS-323: Triggering power-off...\n"); 49962306a36Sopenharmony_ci /* Pin has to be changed to 1 and back to 0 to do actual power off. */ 50062306a36Sopenharmony_ci gpio_set_value(DNS323_GPIO_POWER_OFF, 1); 50162306a36Sopenharmony_ci mdelay(100); 50262306a36Sopenharmony_ci gpio_set_value(DNS323_GPIO_POWER_OFF, 0); 50362306a36Sopenharmony_ci} 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci/* DNS-323 rev. C specific power off method */ 50662306a36Sopenharmony_cistatic void dns323c_power_off(void) 50762306a36Sopenharmony_ci{ 50862306a36Sopenharmony_ci pr_info("DNS-323: Triggering power-off...\n"); 50962306a36Sopenharmony_ci gpio_set_value(DNS323C_GPIO_POWER_OFF, 1); 51062306a36Sopenharmony_ci} 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_cistatic int dns323c_phy_fixup(struct phy_device *phy) 51362306a36Sopenharmony_ci{ 51462306a36Sopenharmony_ci phy->dev_flags |= MARVELL_PHY_M1118_DNS323_LEDS; 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_ci return 0; 51762306a36Sopenharmony_ci} 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_cistatic int __init dns323_identify_rev(void) 52062306a36Sopenharmony_ci{ 52162306a36Sopenharmony_ci u32 dev, rev, i, reg; 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci pr_debug("DNS-323: Identifying board ... \n"); 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci /* Rev A1 has a 5181 */ 52662306a36Sopenharmony_ci orion5x_pcie_id(&dev, &rev); 52762306a36Sopenharmony_ci if (dev == MV88F5181_DEV_ID) { 52862306a36Sopenharmony_ci pr_debug("DNS-323: 5181 found, board is A1\n"); 52962306a36Sopenharmony_ci return DNS323_REV_A1; 53062306a36Sopenharmony_ci } 53162306a36Sopenharmony_ci pr_debug("DNS-323: 5182 found, board is B1 or C1, checking PHY...\n"); 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci /* Rev B1 and C1 both have 5182, let's poke at the eth PHY. This is 53462306a36Sopenharmony_ci * a bit gross but we want to do that without links into the eth 53562306a36Sopenharmony_ci * driver so let's poke at it directly. We default to rev B1 in 53662306a36Sopenharmony_ci * case the accesses fail 53762306a36Sopenharmony_ci */ 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_ci#define ETH_SMI_REG (ORION5X_ETH_VIRT_BASE + 0x2000 + 0x004) 54062306a36Sopenharmony_ci#define SMI_BUSY 0x10000000 54162306a36Sopenharmony_ci#define SMI_READ_VALID 0x08000000 54262306a36Sopenharmony_ci#define SMI_OPCODE_READ 0x04000000 54362306a36Sopenharmony_ci#define SMI_OPCODE_WRITE 0x00000000 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci for (i = 0; i < 1000; i++) { 54662306a36Sopenharmony_ci reg = readl(ETH_SMI_REG); 54762306a36Sopenharmony_ci if (!(reg & SMI_BUSY)) 54862306a36Sopenharmony_ci break; 54962306a36Sopenharmony_ci } 55062306a36Sopenharmony_ci if (i >= 1000) { 55162306a36Sopenharmony_ci pr_warn("DNS-323: Timeout accessing PHY, assuming rev B1\n"); 55262306a36Sopenharmony_ci return DNS323_REV_B1; 55362306a36Sopenharmony_ci } 55462306a36Sopenharmony_ci writel((3 << 21) /* phy ID reg */ | 55562306a36Sopenharmony_ci (8 << 16) /* phy addr */ | 55662306a36Sopenharmony_ci SMI_OPCODE_READ, ETH_SMI_REG); 55762306a36Sopenharmony_ci for (i = 0; i < 1000; i++) { 55862306a36Sopenharmony_ci reg = readl(ETH_SMI_REG); 55962306a36Sopenharmony_ci if (reg & SMI_READ_VALID) 56062306a36Sopenharmony_ci break; 56162306a36Sopenharmony_ci } 56262306a36Sopenharmony_ci if (i >= 1000) { 56362306a36Sopenharmony_ci pr_warn("DNS-323: Timeout reading PHY, assuming rev B1\n"); 56462306a36Sopenharmony_ci return DNS323_REV_B1; 56562306a36Sopenharmony_ci } 56662306a36Sopenharmony_ci pr_debug("DNS-323: Ethernet PHY ID 0x%x\n", reg & 0xffff); 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ci /* Note: the Marvell tools mask the ID with 0x3f0 before comparison 56962306a36Sopenharmony_ci * but I don't see that making a difference here, at least with 57062306a36Sopenharmony_ci * any known Marvell PHY ID 57162306a36Sopenharmony_ci */ 57262306a36Sopenharmony_ci switch(reg & 0xfff0) { 57362306a36Sopenharmony_ci case 0x0cc0: /* MV88E1111 */ 57462306a36Sopenharmony_ci return DNS323_REV_B1; 57562306a36Sopenharmony_ci case 0x0e10: /* MV88E1118 */ 57662306a36Sopenharmony_ci return DNS323_REV_C1; 57762306a36Sopenharmony_ci default: 57862306a36Sopenharmony_ci pr_warn("DNS-323: Unknown PHY ID 0x%04x, assuming rev B1\n", 57962306a36Sopenharmony_ci reg & 0xffff); 58062306a36Sopenharmony_ci } 58162306a36Sopenharmony_ci return DNS323_REV_B1; 58262306a36Sopenharmony_ci} 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_cistatic void __init dns323_init(void) 58562306a36Sopenharmony_ci{ 58662306a36Sopenharmony_ci /* Setup basic Orion functions. Need to be called early. */ 58762306a36Sopenharmony_ci orion5x_init(); 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci /* Identify revision */ 59062306a36Sopenharmony_ci system_rev = dns323_identify_rev(); 59162306a36Sopenharmony_ci pr_info("DNS-323: Identified HW revision %c1\n", 'A' + system_rev); 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci /* Just to be tricky, the 5182 has a completely different 59462306a36Sopenharmony_ci * set of MPP modes to the 5181. 59562306a36Sopenharmony_ci */ 59662306a36Sopenharmony_ci switch(system_rev) { 59762306a36Sopenharmony_ci case DNS323_REV_A1: 59862306a36Sopenharmony_ci orion5x_mpp_conf(dns323a_mpp_modes); 59962306a36Sopenharmony_ci writel(0, MPP_DEV_CTRL); /* DEV_D[31:16] */ 60062306a36Sopenharmony_ci break; 60162306a36Sopenharmony_ci case DNS323_REV_B1: 60262306a36Sopenharmony_ci orion5x_mpp_conf(dns323b_mpp_modes); 60362306a36Sopenharmony_ci break; 60462306a36Sopenharmony_ci case DNS323_REV_C1: 60562306a36Sopenharmony_ci orion5x_mpp_conf(dns323c_mpp_modes); 60662306a36Sopenharmony_ci break; 60762306a36Sopenharmony_ci } 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci /* setup flash mapping 61062306a36Sopenharmony_ci * CS3 holds a 8 MB Spansion S29GL064M90TFIR4 61162306a36Sopenharmony_ci */ 61262306a36Sopenharmony_ci mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET, 61362306a36Sopenharmony_ci ORION_MBUS_DEVBUS_BOOT_ATTR, 61462306a36Sopenharmony_ci DNS323_NOR_BOOT_BASE, 61562306a36Sopenharmony_ci DNS323_NOR_BOOT_SIZE); 61662306a36Sopenharmony_ci platform_device_register(&dns323_nor_flash); 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci /* Sort out LEDs, Buttons and i2c devices */ 61962306a36Sopenharmony_ci switch(system_rev) { 62062306a36Sopenharmony_ci case DNS323_REV_A1: 62162306a36Sopenharmony_ci /* The 5181 power LED is active low and requires 62262306a36Sopenharmony_ci * DNS323_GPIO_LED_POWER1 to also be low. 62362306a36Sopenharmony_ci */ 62462306a36Sopenharmony_ci dns323ab_leds[0].active_low = 1; 62562306a36Sopenharmony_ci gpio_request(DNS323_GPIO_LED_POWER1, "Power Led Enable"); 62662306a36Sopenharmony_ci gpio_direction_output(DNS323_GPIO_LED_POWER1, 0); 62762306a36Sopenharmony_ci fallthrough; 62862306a36Sopenharmony_ci case DNS323_REV_B1: 62962306a36Sopenharmony_ci i2c_register_board_info(0, dns323ab_i2c_devices, 63062306a36Sopenharmony_ci ARRAY_SIZE(dns323ab_i2c_devices)); 63162306a36Sopenharmony_ci break; 63262306a36Sopenharmony_ci case DNS323_REV_C1: 63362306a36Sopenharmony_ci /* Hookup LEDs & Buttons */ 63462306a36Sopenharmony_ci dns323_gpio_leds.dev.platform_data = &dns323c_led_data; 63562306a36Sopenharmony_ci dns323_button_device.dev.platform_data = &dns323c_button_data; 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_ci /* Hookup i2c devices and fan driver */ 63862306a36Sopenharmony_ci i2c_register_board_info(0, dns323c_i2c_devices, 63962306a36Sopenharmony_ci ARRAY_SIZE(dns323c_i2c_devices)); 64062306a36Sopenharmony_ci platform_device_register_simple("dns323c-fan", 0, NULL, 0); 64162306a36Sopenharmony_ci 64262306a36Sopenharmony_ci /* Register fixup for the PHY LEDs */ 64362306a36Sopenharmony_ci if (!IS_BUILTIN(CONFIG_PHYLIB)) 64462306a36Sopenharmony_ci break; 64562306a36Sopenharmony_ci phy_register_fixup_for_uid(MARVELL_PHY_ID_88E1118, 64662306a36Sopenharmony_ci MARVELL_PHY_ID_MASK, 64762306a36Sopenharmony_ci dns323c_phy_fixup); 64862306a36Sopenharmony_ci } 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci platform_device_register(&dns323_gpio_leds); 65162306a36Sopenharmony_ci platform_device_register(&dns323_button_device); 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_ci /* 65462306a36Sopenharmony_ci * Configure peripherals. 65562306a36Sopenharmony_ci */ 65662306a36Sopenharmony_ci if (dns323_read_mac_addr() < 0) 65762306a36Sopenharmony_ci printk("DNS-323: Failed to read MAC address\n"); 65862306a36Sopenharmony_ci orion5x_ehci0_init(); 65962306a36Sopenharmony_ci orion5x_eth_init(&dns323_eth_data); 66062306a36Sopenharmony_ci orion5x_i2c_init(); 66162306a36Sopenharmony_ci orion5x_uart0_init(); 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci /* Remaining GPIOs */ 66462306a36Sopenharmony_ci switch(system_rev) { 66562306a36Sopenharmony_ci case DNS323_REV_A1: 66662306a36Sopenharmony_ci /* Poweroff GPIO */ 66762306a36Sopenharmony_ci if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 || 66862306a36Sopenharmony_ci gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0) 66962306a36Sopenharmony_ci pr_err("DNS-323: failed to setup power-off GPIO\n"); 67062306a36Sopenharmony_ci pm_power_off = dns323a_power_off; 67162306a36Sopenharmony_ci break; 67262306a36Sopenharmony_ci case DNS323_REV_B1: 67362306a36Sopenharmony_ci /* 5182 built-in SATA init */ 67462306a36Sopenharmony_ci orion5x_sata_init(&dns323_sata_data); 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci /* The DNS323 rev B1 has flag to indicate the system is up. 67762306a36Sopenharmony_ci * Without this flag set, power LED will flash and cannot be 67862306a36Sopenharmony_ci * controlled via leds-gpio. 67962306a36Sopenharmony_ci */ 68062306a36Sopenharmony_ci if (gpio_request(DNS323_GPIO_SYSTEM_UP, "SYS_READY") == 0) 68162306a36Sopenharmony_ci gpio_direction_output(DNS323_GPIO_SYSTEM_UP, 1); 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci /* Poweroff GPIO */ 68462306a36Sopenharmony_ci if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 || 68562306a36Sopenharmony_ci gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0) 68662306a36Sopenharmony_ci pr_err("DNS-323: failed to setup power-off GPIO\n"); 68762306a36Sopenharmony_ci pm_power_off = dns323b_power_off; 68862306a36Sopenharmony_ci break; 68962306a36Sopenharmony_ci case DNS323_REV_C1: 69062306a36Sopenharmony_ci /* 5182 built-in SATA init */ 69162306a36Sopenharmony_ci orion5x_sata_init(&dns323_sata_data); 69262306a36Sopenharmony_ci 69362306a36Sopenharmony_ci /* Poweroff GPIO */ 69462306a36Sopenharmony_ci if (gpio_request(DNS323C_GPIO_POWER_OFF, "POWEROFF") != 0 || 69562306a36Sopenharmony_ci gpio_direction_output(DNS323C_GPIO_POWER_OFF, 0) != 0) 69662306a36Sopenharmony_ci pr_err("DNS-323: failed to setup power-off GPIO\n"); 69762306a36Sopenharmony_ci pm_power_off = dns323c_power_off; 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci /* Now, -this- should theoretically be done by the sata_mv driver 70062306a36Sopenharmony_ci * once I figure out what's going on there. Maybe the behaviour 70162306a36Sopenharmony_ci * of the LEDs should be somewhat passed via the platform_data. 70262306a36Sopenharmony_ci * for now, just whack the register and make the LEDs happy 70362306a36Sopenharmony_ci * 70462306a36Sopenharmony_ci * Note: AFAIK, rev B1 needs the same treatment but I'll let 70562306a36Sopenharmony_ci * somebody else test it. 70662306a36Sopenharmony_ci */ 70762306a36Sopenharmony_ci writel(0x5, ORION5X_SATA_VIRT_BASE + 0x2c); 70862306a36Sopenharmony_ci break; 70962306a36Sopenharmony_ci } 71062306a36Sopenharmony_ci} 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_ci/* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */ 71362306a36Sopenharmony_ciMACHINE_START(DNS323, "D-Link DNS-323") 71462306a36Sopenharmony_ci /* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */ 71562306a36Sopenharmony_ci .atag_offset = 0x100, 71662306a36Sopenharmony_ci .nr_irqs = ORION5X_NR_IRQS, 71762306a36Sopenharmony_ci .init_machine = dns323_init, 71862306a36Sopenharmony_ci .map_io = orion5x_map_io, 71962306a36Sopenharmony_ci .init_early = orion5x_init_early, 72062306a36Sopenharmony_ci .init_irq = orion5x_init_irq, 72162306a36Sopenharmony_ci .init_time = orion5x_timer_init, 72262306a36Sopenharmony_ci .fixup = tag_fixup_mem32, 72362306a36Sopenharmony_ci .restart = orion5x_restart, 72462306a36Sopenharmony_ciMACHINE_END 725