2005-10-06 12:06:20 +10: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>
2006-10-19 19:52:26 -05:00
# include <linux/platform_device.h>
2007-02-17 18:17:16 -07:00
# include <asm/irq.h>
2005-10-06 12:06:20 +10:00
# include <asm/atomic.h>
2007-05-01 16:26:07 +10:00
# define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
# define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
2007-08-21 02:36:59 +10:00
# define of_compat_cmp(s1, s2, l) strcasecmp((s1), (s2))
2007-04-24 16:46:53 +10:00
# define of_prop_cmp(s1, s2) strcmp((s1), (s2))
2007-04-24 17:57:33 +10:00
# define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
2007-05-01 16:29:19 +10:00
2005-10-06 12:06:20 +10:00
/* 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 */
2007-03-14 11:50:40 +11:00
/* version 17 fields below */
u32 dt_struct_size ; /* size of the DT structure block */
2005-10-06 12:06:20 +10:00
} ;
typedef u32 phandle ;
typedef u32 ihandle ;
struct property {
char * name ;
int length ;
2007-04-03 10:58:52 +10:00
void * value ;
2005-10-06 12:06:20 +10:00
struct property * next ;
} ;
struct device_node {
2006-07-12 15:35:54 +10:00
const char * name ;
const char * type ;
2005-10-06 12:06:20 +10:00
phandle node ;
phandle linux_phandle ;
char * full_name ;
struct property * properties ;
2006-01-12 16:08:27 -06:00
struct property * deadprops ; /* removed properties */
2005-10-06 12:06:20 +10: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 ;
2007-06-19 16:07:58 +10:00
static inline int of_node_check_flag ( struct device_node * n , unsigned long flag )
{
return test_bit ( flag , & n - > _flags ) ;
}
static inline void of_node_set_flag ( struct device_node * n , unsigned long flag )
{
set_bit ( flag , & n - > _flags ) ;
}
2005-10-06 12:06:20 +10:00
# define HAVE_ARCH_DEVTREE_FIXUPS
static inline void set_node_proc_entry ( struct device_node * dn , struct proc_dir_entry * de )
{
dn - > pde = de ;
}
extern struct device_node * of_find_all_nodes ( struct device_node * prev ) ;
extern struct device_node * of_node_get ( struct device_node * node ) ;
extern void of_node_put ( struct device_node * node ) ;
2005-11-07 11:06:55 +11:00
/* For scanning the flat device-tree at boot time */
2006-03-28 23:15:54 +11: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 11:06:55 +11:00
2005-10-06 12:06:20 +10:00
/* For updating the device tree at runtime */
extern void of_attach_node ( struct device_node * ) ;
2007-07-20 15:58:38 +10:00
extern void of_detach_node ( struct device_node * ) ;
2005-10-06 12:06:20 +10:00
/* Other Prototypes */
extern void finish_device_tree ( void ) ;
extern void unflatten_device_tree ( void ) ;
extern void early_init_devtree ( void * ) ;
extern int machine_is_compatible ( const char * compat ) ;
extern void print_properties ( struct device_node * node ) ;
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 14:29:02 +11:00
extern int prom_add_property ( struct device_node * np , struct property * prop ) ;
2006-01-12 16:08:27 -06: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 12:06:20 +10:00
2005-10-10 22:50:37 +10:00
# ifdef CONFIG_PPC32
2005-10-06 12:06:20 +10: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 22:50:37 +10:00
# endif
2005-10-06 12:06:20 +10: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 16:57:28 +11:00
2005-11-23 17:53:42 +11:00
/*
2005-11-30 16:57:28 +11:00
* OF address retreival & translation
*/
2006-09-19 14:06:27 +10:00
/* Helper to read a big number; size is in cells (not bytes) */
2006-07-04 16:46:44 +10:00
static inline u64 of_read_number ( const u32 * cell , int size )
2006-07-03 19:35:17 +10:00
{
u64 r = 0 ;
while ( size - - )
r = ( r < < 32 ) | * ( cell + + ) ;
return r ;
}
2006-09-19 14:06:27 +10: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 16:57:28 +11:00
/* Translate an OF address block into a CPU physical address
2005-11-23 17:53:42 +11:00
*/
2006-07-12 15:35:54 +10:00
extern u64 of_translate_address ( struct device_node * np , const u32 * addr ) ;
2005-11-23 17:53:42 +11:00
2007-12-11 14:48:22 +11:00
/* Translate a DMA address from device space to CPU space */
extern u64 of_translate_dma_address ( struct device_node * dev ,
const u32 * in_addr ) ;
2005-11-30 16:57:28 +11: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 15:35:54 +10:00
extern const u32 * of_get_address ( struct device_node * dev , int index ,
2005-11-30 16:57:28 +11:00
u64 * size , unsigned int * flags ) ;
2008-06-11 08:31:00 +10:00
# ifdef CONFIG_PCI
2006-07-12 15:35:54 +10:00
extern const u32 * of_get_pci_address ( struct device_node * dev , int bar_no ,
2005-11-30 16:57:28 +11:00
u64 * size , unsigned int * flags ) ;
2008-06-11 08:31:00 +10:00
# else
static inline const u32 * of_get_pci_address ( struct device_node * dev ,
int bar_no , u64 * size , unsigned int * flags )
{
return NULL ;
}
# endif /* CONFIG_PCI */
2005-11-30 16:57:28 +11:00
/* 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 ) ;
2008-06-11 08:31:00 +10:00
# ifdef CONFIG_PCI
2005-11-30 16:57:28 +11:00
extern int of_pci_address_to_resource ( struct device_node * dev , int bar ,
struct resource * r ) ;
2008-06-11 08:31:00 +10:00
# else
static inline int of_pci_address_to_resource ( struct device_node * dev , int bar ,
struct resource * r )
{
return - ENOSYS ;
}
# endif /* CONFIG_PCI */
2005-11-23 17:53:42 +11:00
2006-05-18 18:05:15 +10:00
/* Parse the ibm,dma-window property of an OF node into the busno, phys and
* size parameters .
*/
2006-07-12 15:35:54 +10:00
void of_parse_dma_window ( struct device_node * dn , const void * dma_window_prop ,
2006-05-18 18:05:15 +10:00
unsigned long * busno , unsigned long * phys , unsigned long * size ) ;
2006-02-03 19:05:47 +11:00
extern void kdump_move_device_tree ( void ) ;
2006-06-19 20:33:16 +02:00
/* CPU OF node matching */
struct device_node * of_get_cpu_node ( int cpu , unsigned int * thread ) ;
2007-02-16 12:01:29 -06:00
/* Get the MAC address */
extern const void * of_get_mac_address ( struct device_node * np ) ;
2006-07-03 19:35:17 +10: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 11:13:50 +10:00
/**
2006-07-03 19:35:17 +10: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 11:13:50 +10:00
/**
2006-07-03 19:35:17 +10: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 14:46:23 +10:00
* @ ointsize : size of the passed in interrupt specifier
2006-07-03 19:35:17 +10: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 15:35:54 +10:00
extern int of_irq_map_raw ( struct device_node * parent , const u32 * intspec ,
2006-08-31 15:45:48 +10:00
u32 ointsize , const u32 * addr ,
2006-07-03 19:35:17 +10:00
struct of_irq * out_irq ) ;
2006-08-02 11:13:50 +10:00
/**
2006-07-03 19:35:17 +10: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 11:13:50 +10:00
/**
2006-07-03 19:35:17 +10: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 ) ;
2007-02-06 12:03:31 +11:00
extern int of_irq_to_resource ( struct device_node * dev , int index ,
struct resource * r ) ;
2006-10-19 19:52:26 -05:00
2007-04-25 01:32:02 +10:00
/**
* of_iomap - Maps the memory mapped IO for a given device_node
* @ device : the device whose io range will be mapped
* @ index : index of the io range
*
* Returns a pointer to the mapped memory
*/
extern void __iomem * of_iomap ( struct device_node * device , int index ) ;
2006-07-03 19:35:17 +10:00
2007-05-01 16:19:07 +10:00
/*
* NB : This is here while we transition from using asm / prom . h
* to linux / of . h
*/
# include <linux/of.h>
2005-10-06 12:06:20 +10:00
# endif /* __KERNEL__ */
# endif /* _POWERPC_PROM_H */