2005-10-06 06:06:20 +04:00
# ifndef _POWERPC_PROM_H
# define _POWERPC_PROM_H
# ifdef __KERNEL__
/*
* Definitions for talking to the Open Firmware PROM on
* Power Macintosh computers .
*
* Copyright ( C ) 1996 - 2005 Paul Mackerras .
*
* Updates for PPC64 by Peter Bergner & David Engebretsen , IBM Corp .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version
* 2 of the License , or ( at your option ) any later version .
*/
# include <linux/types.h>
# include <linux/proc_fs.h>
# include <asm/atomic.h>
/* Definitions used by the flattened device tree */
# define OF_DT_HEADER 0xd00dfeed /* marker */
# define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
# define OF_DT_END_NODE 0x2 /* End node */
# define OF_DT_PROP 0x3 / * Property: name off, size,
* content */
# define OF_DT_NOP 0x4 /* nop */
# define OF_DT_END 0x9
# define OF_DT_VERSION 0x10
/*
* This is what gets passed to the kernel by prom_init or kexec
*
* The dt struct contains the device tree structure , full pathes and
* property contents . The dt strings contain a separate block with just
* the strings for the property names , and is fully page aligned and
* self contained in a page , so that it can be kept around by the kernel ,
* each property name appears only once in this page ( cheap compression )
*
* the mem_rsvmap contains a map of reserved ranges of physical memory ,
* passing it here instead of in the device - tree itself greatly simplifies
* the job of everybody . It ' s just a list of u64 pairs ( base / size ) that
* ends when size is 0
*/
struct boot_param_header
{
u32 magic ; /* magic word OF_DT_HEADER */
u32 totalsize ; /* total size of DT block */
u32 off_dt_struct ; /* offset to structure */
u32 off_dt_strings ; /* offset to strings */
u32 off_mem_rsvmap ; /* offset to memory reserve map */
u32 version ; /* format version */
u32 last_comp_version ; /* last compatible version */
/* version 2 fields below */
u32 boot_cpuid_phys ; /* Physical CPU id we're booting on */
/* version 3 fields below */
u32 dt_strings_size ; /* size of the DT strings block */
} ;
typedef u32 phandle ;
typedef u32 ihandle ;
struct property {
char * name ;
int length ;
unsigned char * value ;
struct property * next ;
} ;
struct device_node {
2006-07-12 09:35:54 +04:00
const char * name ;
const char * type ;
2005-10-06 06:06:20 +04:00
phandle node ;
phandle linux_phandle ;
char * full_name ;
struct property * properties ;
2006-01-13 01:08:27 +03:00
struct property * deadprops ; /* removed properties */
2005-10-06 06:06:20 +04:00
struct device_node * parent ;
struct device_node * child ;
struct device_node * sibling ;
struct device_node * next ; /* next device of same type */
struct device_node * allnext ; /* next in list of all nodes */
struct proc_dir_entry * pde ; /* this node's proc directory */
struct kref kref ;
unsigned long _flags ;
void * data ;
} ;
extern struct device_node * of_chosen ;
/* flag descriptions */
# define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
# define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
# define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
# define HAVE_ARCH_DEVTREE_FIXUPS
static inline void set_node_proc_entry ( struct device_node * dn , struct proc_dir_entry * de )
{
dn - > pde = de ;
}
/* OBSOLETE: Old style node lookup */
2005-10-27 10:45:29 +04:00
extern struct device_node * find_devices ( const char * name ) ;
extern struct device_node * find_type_devices ( const char * type ) ;
extern struct device_node * find_path_device ( const char * path ) ;
extern struct device_node * find_compatible_devices ( const char * type ,
2005-10-06 06:06:20 +04:00
const char * compat ) ;
2005-10-27 10:45:29 +04:00
extern struct device_node * find_all_nodes ( void ) ;
2005-10-06 06:06:20 +04:00
/* New style node lookup */
extern struct device_node * of_find_node_by_name ( struct device_node * from ,
const char * name ) ;
2006-03-08 18:47:00 +03:00
# define for_each_node_by_name(dn, name) \
for ( dn = of_find_node_by_name ( NULL , name ) ; dn ; \
dn = of_find_node_by_name ( dn , name ) )
2005-10-06 06:06:20 +04:00
extern struct device_node * of_find_node_by_type ( struct device_node * from ,
const char * type ) ;
2006-03-08 18:47:00 +03:00
# define for_each_node_by_type(dn, type) \
for ( dn = of_find_node_by_type ( NULL , type ) ; dn ; \
dn = of_find_node_by_type ( dn , type ) )
2005-10-06 06:06:20 +04:00
extern struct device_node * of_find_compatible_node ( struct device_node * from ,
const char * type , const char * compat ) ;
extern struct device_node * of_find_node_by_path ( const char * path ) ;
extern struct device_node * of_find_node_by_phandle ( phandle handle ) ;
extern struct device_node * of_find_all_nodes ( struct device_node * prev ) ;
extern struct device_node * of_get_parent ( const struct device_node * node ) ;
extern struct device_node * of_get_next_child ( const struct device_node * node ,
struct device_node * prev ) ;
2006-10-20 05:49:54 +04:00
extern struct property * of_find_property ( const struct device_node * np ,
2006-01-13 01:09:29 +03:00
const char * name ,
int * lenp ) ;
2005-10-06 06:06:20 +04:00
extern struct device_node * of_node_get ( struct device_node * node ) ;
extern void of_node_put ( struct device_node * node ) ;
2005-11-07 03:06:55 +03:00
/* For scanning the flat device-tree at boot time */
2006-03-28 16:15:54 +04:00
extern int __init of_scan_flat_dt ( int ( * it ) ( unsigned long node ,
const char * uname , int depth ,
void * data ) ,
void * data ) ;
extern void * __init of_get_flat_dt_prop ( unsigned long node , const char * name ,
unsigned long * size ) ;
extern int __init of_flat_dt_is_compatible ( unsigned long node , const char * name ) ;
extern unsigned long __init of_get_flat_dt_root ( void ) ;
2005-11-07 03:06:55 +03:00
2005-10-06 06:06:20 +04:00
/* For updating the device tree at runtime */
extern void of_attach_node ( struct device_node * ) ;
extern void of_detach_node ( const struct device_node * ) ;
/* Other Prototypes */
extern void finish_device_tree ( void ) ;
extern void unflatten_device_tree ( void ) ;
extern void early_init_devtree ( void * ) ;
2006-10-20 05:49:54 +04:00
extern int device_is_compatible ( const struct device_node * device ,
const char * ) ;
2005-10-06 06:06:20 +04:00
extern int machine_is_compatible ( const char * compat ) ;
2006-10-20 05:49:54 +04:00
extern const void * get_property ( const struct device_node * node ,
const char * name ,
int * lenp ) ;
2005-10-06 06:06:20 +04:00
extern void print_properties ( struct device_node * node ) ;
extern int prom_n_addr_cells ( struct device_node * np ) ;
extern int prom_n_size_cells ( struct device_node * np ) ;
extern int prom_n_intr_cells ( struct device_node * np ) ;
extern void prom_get_irq_senses ( unsigned char * senses , int off , int max ) ;
2005-11-07 06:29:02 +03:00
extern int prom_add_property ( struct device_node * np , struct property * prop ) ;
2006-01-13 01:08:27 +03:00
extern int prom_remove_property ( struct device_node * np , struct property * prop ) ;
extern int prom_update_property ( struct device_node * np ,
struct property * newprop ,
struct property * oldprop ) ;
2005-10-06 06:06:20 +04:00
2005-10-10 16:50:37 +04:00
# ifdef CONFIG_PPC32
2005-10-06 06:06:20 +04:00
/*
* PCI < - > OF matching functions
* ( XXX should these be here ? )
*/
struct pci_bus ;
struct pci_dev ;
extern int pci_device_from_OF_node ( struct device_node * node ,
u8 * bus , u8 * devfn ) ;
extern struct device_node * pci_busdev_to_OF_node ( struct pci_bus * , int ) ;
extern struct device_node * pci_device_to_OF_node ( struct pci_dev * ) ;
extern void pci_create_OF_bus_map ( void ) ;
2005-10-10 16:50:37 +04:00
# endif
2005-10-06 06:06:20 +04:00
extern struct resource * request_OF_resource ( struct device_node * node ,
int index , const char * name_postfix ) ;
extern int release_OF_resource ( struct device_node * node , int index ) ;
2005-11-30 08:57:28 +03:00
2005-11-23 09:53:42 +03:00
/*
2005-11-30 08:57:28 +03:00
* OF address retreival & translation
*/
2006-09-19 08:06:27 +04:00
/* Helper to read a big number; size is in cells (not bytes) */
2006-07-04 10:46:44 +04:00
static inline u64 of_read_number ( const u32 * cell , int size )
2006-07-03 13:35:17 +04:00
{
u64 r = 0 ;
while ( size - - )
r = ( r < < 32 ) | * ( cell + + ) ;
return r ;
}
2006-09-19 08:06:27 +04:00
/* Like of_read_number, but we want an unsigned long result */
# ifdef CONFIG_PPC32
static inline unsigned long of_read_ulong ( const u32 * cell , int size )
{
return cell [ size - 1 ] ;
}
# else
# define of_read_ulong(cell, size) of_read_number(cell, size)
# endif
2005-11-30 08:57:28 +03:00
/* Translate an OF address block into a CPU physical address
2005-11-23 09:53:42 +03:00
*/
# define OF_BAD_ADDR ((u64)-1)
2006-07-12 09:35:54 +04:00
extern u64 of_translate_address ( struct device_node * np , const u32 * addr ) ;
2005-11-23 09:53:42 +03:00
2005-11-30 08:57:28 +03:00
/* Extract an address from a device, returns the region size and
* the address space flags too . The PCI version uses a BAR number
* instead of an absolute index
*/
2006-07-12 09:35:54 +04:00
extern const u32 * of_get_address ( struct device_node * dev , int index ,
2005-11-30 08:57:28 +03:00
u64 * size , unsigned int * flags ) ;
2006-07-12 09:35:54 +04:00
extern const u32 * of_get_pci_address ( struct device_node * dev , int bar_no ,
2005-11-30 08:57:28 +03:00
u64 * size , unsigned int * flags ) ;
/* Get an address as a resource. Note that if your address is
* a PIO address , the conversion will fail if the physical address
* can ' t be internally converted to an IO token with
* pci_address_to_pio ( ) , that is because it ' s either called to early
* or it can ' t be matched to any host bridge IO space
*/
extern int of_address_to_resource ( struct device_node * dev , int index ,
struct resource * r ) ;
extern int of_pci_address_to_resource ( struct device_node * dev , int bar ,
struct resource * r ) ;
2005-11-23 09:53:42 +03:00
2006-05-18 12:05:15 +04:00
/* Parse the ibm,dma-window property of an OF node into the busno, phys and
* size parameters .
*/
2006-07-12 09:35:54 +04:00
void of_parse_dma_window ( struct device_node * dn , const void * dma_window_prop ,
2006-05-18 12:05:15 +04:00
unsigned long * busno , unsigned long * phys , unsigned long * size ) ;
2006-02-03 11:05:47 +03:00
extern void kdump_move_device_tree ( void ) ;
2006-06-19 22:33:16 +04:00
/* CPU OF node matching */
struct device_node * of_get_cpu_node ( int cpu , unsigned int * thread ) ;
2006-07-03 13:35:17 +04:00
/*
* OF interrupt mapping
*/
/* This structure is returned when an interrupt is mapped. The controller
* field needs to be put ( ) after use
*/
# define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */
struct of_irq {
struct device_node * controller ; /* Interrupt controller node */
u32 size ; /* Specifier size */
u32 specifier [ OF_MAX_IRQ_SPEC ] ; /* Specifier copy */
} ;
2006-08-02 05:13:50 +04:00
/**
2006-07-03 13:35:17 +04:00
* of_irq_map_init - Initialize the irq remapper
* @ flags : flags defining workarounds to enable
*
* Some machines have bugs in the device - tree which require certain workarounds
* to be applied . Call this before any interrupt mapping attempts to enable
* those workarounds .
*/
# define OF_IMAP_OLDWORLD_MAC 0x00000001
# define OF_IMAP_NO_PHANDLE 0x00000002
extern void of_irq_map_init ( unsigned int flags ) ;
2006-08-02 05:13:50 +04:00
/**
2006-07-03 13:35:17 +04:00
* of_irq_map_raw - Low level interrupt tree parsing
* @ parent : the device interrupt parent
* @ intspec : interrupt specifier ( " interrupts " property of the device )
2006-08-25 08:46:23 +04:00
* @ ointsize : size of the passed in interrupt specifier
2006-07-03 13:35:17 +04:00
* @ addr : address specifier ( start of " reg " property of the device )
* @ out_irq : structure of_irq filled by this function
*
* Returns 0 on success and a negative number on error
*
* This function is a low - level interrupt tree walking function . It
* can be used to do a partial walk with synthetized reg and interrupts
* properties , for example when resolving PCI interrupts when no device
* node exist for the parent .
*
*/
2006-07-12 09:35:54 +04:00
extern int of_irq_map_raw ( struct device_node * parent , const u32 * intspec ,
2006-08-31 09:45:48 +04:00
u32 ointsize , const u32 * addr ,
2006-07-03 13:35:17 +04:00
struct of_irq * out_irq ) ;
2006-08-02 05:13:50 +04:00
/**
2006-07-03 13:35:17 +04:00
* of_irq_map_one - Resolve an interrupt for a device
* @ device : the device whose interrupt is to be resolved
* @ index : index of the interrupt to resolve
* @ out_irq : structure of_irq filled by this function
*
* This function resolves an interrupt , walking the tree , for a given
* device - tree node . It ' s the high level pendant to of_irq_map_raw ( ) .
* It also implements the workarounds for OldWolrd Macs .
*/
extern int of_irq_map_one ( struct device_node * device , int index ,
struct of_irq * out_irq ) ;
2006-08-02 05:13:50 +04:00
/**
2006-07-03 13:35:17 +04:00
* of_irq_map_pci - Resolve the interrupt for a PCI device
* @ pdev : the device whose interrupt is to be resolved
* @ out_irq : structure of_irq filled by this function
*
* This function resolves the PCI interrupt for a given PCI device . If a
* device - node exists for a given pci_dev , it will use normal OF tree
* walking . If not , it will implement standard swizzling and walk up the
* PCI tree until an device - node is found , at which point it will finish
* resolving using the OF tree walking .
*/
struct pci_dev ;
extern int of_irq_map_pci ( struct pci_dev * pdev , struct of_irq * out_irq ) ;
2005-10-06 06:06:20 +04:00
# endif /* __KERNEL__ */
# endif /* _POWERPC_PROM_H */