2006-12-01 22:53:48 +01:00
/*
* Board setup routines for the Buffalo Linkstation / Kurobox Platform .
*
* Copyright ( C ) 2006 G . Liakhovetski ( g . liakhovetski @ gmx . de )
*
* Based on sandpoint . c by Mark A . Greer
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed " as is " without any warranty of
* any kind , whether express or implied .
*/
# include <linux/kernel.h>
# include <linux/initrd.h>
2008-10-24 01:05:56 +02:00
# include <linux/of_platform.h>
2006-12-01 22:53:48 +01:00
# include <asm/time.h>
# include <asm/prom.h>
# include <asm/mpic.h>
# include <asm/pci-bridge.h>
2007-08-20 08:50:28 -05:00
# include "mpc10x.h"
2008-10-24 01:05:56 +02:00
static __initdata struct of_device_id of_bus_ids [ ] = {
{ . type = " soc " , } ,
{ . compatible = " simple-bus " , } ,
{ } ,
} ;
static int __init declare_of_platform_devices ( void )
{
of_platform_bus_probe ( NULL , of_bus_ids , NULL ) ;
return 0 ;
}
machine_device_initcall ( linkstation , declare_of_platform_devices ) ;
2007-06-18 01:06:54 +02:00
static int __init linkstation_add_bridge ( struct device_node * dev )
2006-12-01 22:53:48 +01:00
{
2007-06-18 01:06:57 +02:00
# ifdef CONFIG_PCI
2006-12-01 22:53:48 +01:00
int len ;
struct pci_controller * hose ;
2007-04-03 22:26:41 +10:00
const int * bus_range ;
2006-12-01 22:53:48 +01:00
printk ( " Adding PCI host bridge %s \n " , dev - > full_name ) ;
2007-04-03 22:26:41 +10:00
bus_range = of_get_property ( dev , " bus-range " , & len ) ;
2006-12-01 22:53:48 +01:00
if ( bus_range = = NULL | | len < 2 * sizeof ( int ) )
printk ( KERN_WARNING " Can't get bus-range for %s, assume "
" bus 0 \n " , dev - > full_name ) ;
2007-06-27 01:56:50 -05:00
hose = pcibios_alloc_controller ( dev ) ;
2006-12-01 22:53:48 +01:00
if ( hose = = NULL )
return - ENOMEM ;
hose - > first_busno = bus_range ? bus_range [ 0 ] : 0 ;
hose - > last_busno = bus_range ? bus_range [ 1 ] : 0xff ;
2007-07-19 16:07:35 -05:00
setup_indirect_pci ( hose , 0xfec00000 , 0xfee00000 , 0 ) ;
2006-12-01 22:53:48 +01:00
/* Interpret the "ranges" property */
/* This also maps the I/O region and sets isa_io/mem_base */
pci_process_bridge_OF_ranges ( hose , dev , 1 ) ;
2007-06-18 01:06:57 +02:00
# endif
2006-12-01 22:53:48 +01:00
return 0 ;
}
static void __init linkstation_setup_arch ( void )
{
struct device_node * np ;
/* Lookup PCI host bridges */
2007-10-04 00:28:43 -05:00
for_each_compatible_node ( np , " pci " , " mpc10x-pci " )
2007-06-18 01:06:54 +02:00
linkstation_add_bridge ( np ) ;
2006-12-01 22:53:48 +01:00
printk ( KERN_INFO " BUFFALO Network Attached Storage Series \n " ) ;
printk ( KERN_INFO " (C) 2002-2005 BUFFALO INC. \n " ) ;
}
/*
2007-08-01 19:41:09 +10:00
* Interrupt setup and service . Interrupts on the linkstation come
2006-12-01 22:53:48 +01:00
* from the four PCI slots plus onboard 8241 devices : I2C , DUART .
*/
static void __init linkstation_init_IRQ ( void )
{
struct mpic * mpic ;
struct device_node * dnp ;
2007-04-03 22:26:41 +10:00
const u32 * prop ;
2006-12-01 22:53:48 +01:00
int size ;
phys_addr_t paddr ;
dnp = of_find_node_by_type ( NULL , " open-pic " ) ;
if ( dnp = = NULL )
return ;
2007-04-03 22:26:41 +10:00
prop = of_get_property ( dnp , " reg " , & size ) ;
2006-12-01 22:53:48 +01:00
paddr = ( phys_addr_t ) of_translate_address ( dnp , prop ) ;
mpic = mpic_alloc ( dnp , paddr , MPIC_PRIMARY | MPIC_WANTS_RESET , 4 , 32 , " EPIC " ) ;
BUG_ON ( mpic = = NULL ) ;
/* PCI IRQs */
mpic_assign_isu ( mpic , 0 , paddr + 0x10200 ) ;
/* I2C */
mpic_assign_isu ( mpic , 1 , paddr + 0x11000 ) ;
/* ttyS0, ttyS1 */
mpic_assign_isu ( mpic , 2 , paddr + 0x11100 ) ;
mpic_init ( mpic ) ;
}
extern void avr_uart_configure ( void ) ;
extern void avr_uart_send ( const char ) ;
static void linkstation_restart ( char * cmd )
{
local_irq_disable ( ) ;
/* Reset system via AVR */
avr_uart_configure ( ) ;
/* Send reboot command */
avr_uart_send ( ' C ' ) ;
for ( ; ; ) /* Spin until reset happens */
avr_uart_send ( ' G ' ) ; /* "kick" */
}
static void linkstation_power_off ( void )
{
local_irq_disable ( ) ;
/* Power down system via AVR */
avr_uart_configure ( ) ;
/* send shutdown command */
avr_uart_send ( ' E ' ) ;
for ( ; ; ) /* Spin until power-off happens */
avr_uart_send ( ' G ' ) ; /* "kick" */
/* NOTREACHED */
}
static void linkstation_halt ( void )
{
linkstation_power_off ( ) ;
/* NOTREACHED */
}
static void linkstation_show_cpuinfo ( struct seq_file * m )
{
seq_printf ( m , " vendor \t \t : Buffalo Technology \n " ) ;
seq_printf ( m , " machine \t \t : Linkstation I/Kurobox(HG) \n " ) ;
}
static int __init linkstation_probe ( void )
{
unsigned long root ;
root = of_get_flat_dt_root ( ) ;
if ( ! of_flat_dt_is_compatible ( root , " linkstation " ) )
return 0 ;
return 1 ;
}
define_machine ( linkstation ) {
. name = " Buffalo Linkstation " ,
. probe = linkstation_probe ,
. setup_arch = linkstation_setup_arch ,
. init_IRQ = linkstation_init_IRQ ,
. show_cpuinfo = linkstation_show_cpuinfo ,
. get_irq = mpic_get_irq ,
. restart = linkstation_restart ,
. power_off = linkstation_power_off ,
. halt = linkstation_halt ,
. calibrate_decr = generic_calibrate_decr ,
} ;