2005-04-16 15:20:36 -07:00
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/pci.h>
# include <linux/slab.h>
# include <asm/oplib.h>
2006-06-29 15:07:37 -07:00
# include <asm/prom.h>
# include <asm/of_device.h>
2005-04-16 15:20:36 -07:00
# include <asm/isa.h>
struct sparc_isa_bridge * isa_chain ;
static void __init fatal_err ( const char * reason )
{
prom_printf ( " ISA: fatal error, %s. \n " , reason ) ;
}
static void __init report_dev ( struct sparc_isa_device * isa_dev , int child )
{
if ( child )
2006-06-22 19:12:03 -07:00
printk ( " (%s) " , isa_dev - > prom_node - > name ) ;
2005-04-16 15:20:36 -07:00
else
2006-06-22 19:12:03 -07:00
printk ( " [%s " , isa_dev - > prom_node - > name ) ;
2005-04-16 15:20:36 -07:00
}
2006-12-28 21:43:51 -08:00
static void __init isa_dev_get_resource ( struct sparc_isa_device * isa_dev )
2005-04-16 15:20:36 -07:00
{
2007-02-28 18:01:38 -08:00
struct of_device * op = of_find_device_by_node ( isa_dev - > prom_node ) ;
2005-04-16 15:20:36 -07:00
2007-02-28 18:01:38 -08:00
memcpy ( & isa_dev - > resource , & op - > resource [ 0 ] , sizeof ( struct resource ) ) ;
2005-04-16 15:20:36 -07:00
}
2006-12-28 21:43:51 -08:00
static void __init isa_dev_get_irq ( struct sparc_isa_device * isa_dev )
2005-04-16 15:20:36 -07:00
{
2006-06-29 15:07:37 -07:00
struct of_device * op = of_find_device_by_node ( isa_dev - > prom_node ) ;
2005-04-16 15:20:36 -07:00
2006-06-29 15:07:37 -07:00
if ( ! op | | ! op - > num_irqs ) {
isa_dev - > irq = PCI_IRQ_NONE ;
2005-04-16 15:20:36 -07:00
} else {
2006-06-29 15:07:37 -07:00
isa_dev - > irq = op - > irqs [ 0 ] ;
2005-04-16 15:20:36 -07:00
}
}
static void __init isa_fill_children ( struct sparc_isa_device * parent_isa_dev )
{
2006-06-22 19:12:03 -07:00
struct device_node * dp = parent_isa_dev - > prom_node - > child ;
2005-04-16 15:20:36 -07:00
2006-06-22 19:12:03 -07:00
if ( ! dp )
2005-04-16 15:20:36 -07:00
return ;
printk ( " -> " ) ;
2006-06-22 19:12:03 -07:00
while ( dp ) {
2005-04-16 15:20:36 -07:00
struct sparc_isa_device * isa_dev ;
2006-11-30 17:13:09 -08:00
isa_dev = kzalloc ( sizeof ( * isa_dev ) , GFP_KERNEL ) ;
2005-04-16 15:20:36 -07:00
if ( ! isa_dev ) {
fatal_err ( " cannot allocate child isa_dev " ) ;
prom_halt ( ) ;
}
/* Link it in to parent. */
isa_dev - > next = parent_isa_dev - > child ;
parent_isa_dev - > child = isa_dev ;
isa_dev - > bus = parent_isa_dev - > bus ;
2006-06-22 19:12:03 -07:00
isa_dev - > prom_node = dp ;
2005-04-16 15:20:36 -07:00
2006-12-28 21:43:51 -08:00
isa_dev_get_resource ( isa_dev ) ;
isa_dev_get_irq ( isa_dev ) ;
2005-04-16 15:20:36 -07:00
report_dev ( isa_dev , 1 ) ;
2006-06-22 19:12:03 -07:00
dp = dp - > sibling ;
2005-04-16 15:20:36 -07:00
}
}
static void __init isa_fill_devices ( struct sparc_isa_bridge * isa_br )
{
2006-06-22 19:12:03 -07:00
struct device_node * dp = isa_br - > prom_node - > child ;
2005-04-16 15:20:36 -07:00
2006-06-22 19:12:03 -07:00
while ( dp ) {
2005-04-16 15:20:36 -07:00
struct sparc_isa_device * isa_dev ;
2007-07-18 22:03:25 -07:00
struct dev_archdata * sd ;
2005-04-16 15:20:36 -07:00
2006-11-30 17:13:09 -08:00
isa_dev = kzalloc ( sizeof ( * isa_dev ) , GFP_KERNEL ) ;
2005-04-16 15:20:36 -07:00
if ( ! isa_dev ) {
2006-06-23 01:44:10 -07:00
printk ( KERN_DEBUG " ISA: cannot allocate isa_dev " ) ;
return ;
2005-04-16 15:20:36 -07:00
}
2007-07-18 22:03:25 -07:00
sd = & isa_dev - > ofdev . dev . archdata ;
sd - > prom_node = dp ;
sd - > op = & isa_dev - > ofdev ;
2007-07-27 22:39:14 -07:00
sd - > iommu = isa_br - > ofdev . dev . parent - > archdata . iommu ;
sd - > stc = isa_br - > ofdev . dev . parent - > archdata . stc ;
2007-07-18 22:03:25 -07:00
2006-06-23 01:44:10 -07:00
isa_dev - > ofdev . node = dp ;
isa_dev - > ofdev . dev . parent = & isa_br - > ofdev . dev ;
isa_dev - > ofdev . dev . bus = & isa_bus_type ;
2006-10-27 01:03:31 -07:00
sprintf ( isa_dev - > ofdev . dev . bus_id , " isa[%08x] " , dp - > node ) ;
2006-06-23 01:44:10 -07:00
/* Register with core */
if ( of_device_register ( & isa_dev - > ofdev ) ! = 0 ) {
printk ( KERN_DEBUG " isa: device registration error for %s! \n " ,
2006-10-27 01:03:31 -07:00
dp - > path_component_name ) ;
2006-06-23 01:44:10 -07:00
kfree ( isa_dev ) ;
goto next_sibling ;
}
2005-04-16 15:20:36 -07:00
/* Link it in. */
isa_dev - > next = NULL ;
if ( isa_br - > devices = = NULL ) {
isa_br - > devices = isa_dev ;
} else {
struct sparc_isa_device * tmp = isa_br - > devices ;
while ( tmp - > next )
tmp = tmp - > next ;
tmp - > next = isa_dev ;
}
isa_dev - > bus = isa_br ;
2006-06-22 19:12:03 -07:00
isa_dev - > prom_node = dp ;
2005-04-16 15:20:36 -07:00
2006-12-28 21:43:51 -08:00
isa_dev_get_resource ( isa_dev ) ;
isa_dev_get_irq ( isa_dev ) ;
2005-04-16 15:20:36 -07:00
report_dev ( isa_dev , 0 ) ;
isa_fill_children ( isa_dev ) ;
printk ( " ] " ) ;
2006-06-23 01:44:10 -07:00
next_sibling :
2006-06-22 19:12:03 -07:00
dp = dp - > sibling ;
2005-04-16 15:20:36 -07:00
}
}
void __init isa_init ( void )
{
struct pci_dev * pdev ;
unsigned short vendor , device ;
int index = 0 ;
vendor = PCI_VENDOR_ID_AL ;
device = PCI_DEVICE_ID_AL_M1533 ;
pdev = NULL ;
while ( ( pdev = pci_get_device ( vendor , device , pdev ) ) ! = NULL ) {
struct sparc_isa_bridge * isa_br ;
2006-06-23 01:44:10 -07:00
struct device_node * dp ;
2005-04-16 15:20:36 -07:00
2007-02-28 18:01:38 -08:00
dp = pci_device_to_OF_node ( pdev ) ;
2005-04-16 15:20:36 -07:00
2006-11-30 17:13:09 -08:00
isa_br = kzalloc ( sizeof ( * isa_br ) , GFP_KERNEL ) ;
2005-04-16 15:20:36 -07:00
if ( ! isa_br ) {
2006-06-23 01:44:10 -07:00
printk ( KERN_DEBUG " isa: cannot allocate sparc_isa_bridge " ) ;
2007-11-19 22:50:01 -08:00
pci_dev_put ( pdev ) ;
2006-06-23 01:44:10 -07:00
return ;
2005-04-16 15:20:36 -07:00
}
2006-06-23 01:44:10 -07:00
isa_br - > ofdev . node = dp ;
isa_br - > ofdev . dev . parent = & pdev - > dev ;
isa_br - > ofdev . dev . bus = & isa_bus_type ;
2006-10-27 01:03:31 -07:00
sprintf ( isa_br - > ofdev . dev . bus_id , " isa%d " , index ) ;
2006-06-23 01:44:10 -07:00
/* Register with core */
if ( of_device_register ( & isa_br - > ofdev ) ! = 0 ) {
printk ( KERN_DEBUG " isa: device registration error for %s! \n " ,
2006-10-27 01:03:31 -07:00
dp - > path_component_name ) ;
2006-06-23 01:44:10 -07:00
kfree ( isa_br ) ;
2007-11-19 22:50:01 -08:00
pci_dev_put ( pdev ) ;
2006-06-23 01:44:10 -07:00
return ;
}
2005-04-16 15:20:36 -07:00
/* Link it in. */
isa_br - > next = isa_chain ;
isa_chain = isa_br ;
isa_br - > self = pdev ;
isa_br - > index = index + + ;
2007-02-28 18:01:38 -08:00
isa_br - > prom_node = dp ;
2006-06-22 19:12:03 -07:00
2005-04-16 15:20:36 -07:00
printk ( " isa%d: " , isa_br - > index ) ;
isa_fill_devices ( isa_br ) ;
printk ( " \n " ) ;
}
}