2 * Architecture specific OF callbacks.
4 #include <linux/bootmem.h>
6 #include <linux/interrupt.h>
7 #include <linux/list.h>
9 #include <linux/of_fdt.h>
10 #include <linux/of_address.h>
11 #include <linux/of_platform.h>
12 #include <linux/slab.h>
15 #include <asm/irq_controller.h>
18 __initdata u64 initial_dtb
;
19 char __initdata cmd_line
[COMMAND_LINE_SIZE
];
20 static LIST_HEAD(irq_domains
);
21 static DEFINE_RAW_SPINLOCK(big_irq_lock
);
23 int __initdata of_ioapic
;
25 void add_interrupt_host(struct irq_domain
*ih
)
29 raw_spin_lock_irqsave(&big_irq_lock
, flags
);
30 list_add(&ih
->l
, &irq_domains
);
31 raw_spin_unlock_irqrestore(&big_irq_lock
, flags
);
34 static struct irq_domain
*get_ih_from_node(struct device_node
*controller
)
36 struct irq_domain
*ih
, *found
= NULL
;
39 raw_spin_lock_irqsave(&big_irq_lock
, flags
);
40 list_for_each_entry(ih
, &irq_domains
, l
) {
41 if (ih
->controller
== controller
) {
46 raw_spin_unlock_irqrestore(&big_irq_lock
, flags
);
50 unsigned int irq_create_of_mapping(struct device_node
*controller
,
51 const u32
*intspec
, unsigned int intsize
)
53 struct irq_domain
*ih
;
57 ih
= get_ih_from_node(controller
);
60 ret
= ih
->xlate(ih
, intspec
, intsize
, &virq
, &type
);
63 if (type
== IRQ_TYPE_NONE
)
65 /* set the mask if it is different from current */
66 if (type
== (irq_to_desc(virq
)->status
& IRQF_TRIGGER_MASK
))
67 set_irq_type(virq
, type
);
70 EXPORT_SYMBOL_GPL(irq_create_of_mapping
);
72 unsigned long pci_address_to_pio(phys_addr_t address
)
75 * The ioport address can be directly used by inX / outX
77 BUG_ON(address
>= (1 << 16));
78 return (unsigned long)address
;
80 EXPORT_SYMBOL_GPL(pci_address_to_pio
);
82 void __init
early_init_dt_scan_chosen_arch(unsigned long node
)
87 void __init
early_init_dt_add_memory_arch(u64 base
, u64 size
)
92 void * __init
early_init_dt_alloc_memory_arch(u64 size
, u64 align
)
94 return __alloc_bootmem(size
, align
, __pa(MAX_DMA_ADDRESS
));
97 void __init
add_dtb(u64 data
)
99 initial_dtb
= data
+ offsetof(struct setup_data
, data
);
102 static void __init
dtb_setup_hpet(void)
104 struct device_node
*dn
;
108 dn
= of_find_compatible_node(NULL
, NULL
, "intel,ce4100-hpet");
111 ret
= of_address_to_resource(dn
, 0, &r
);
116 hpet_address
= r
.start
;
119 static void __init
dtb_lapic_setup(void)
121 #ifdef CONFIG_X86_LOCAL_APIC
122 if (apic_force_enable())
125 smp_found_config
= 1;
127 /* Required for ioapic registration */
128 set_fixmap_nocache(FIX_APIC_BASE
, mp_lapic_addr
);
129 if (boot_cpu_physical_apicid
== -1U)
130 boot_cpu_physical_apicid
= read_apic_id();
132 generic_processor_info(boot_cpu_physical_apicid
,
133 GET_APIC_VERSION(apic_read(APIC_LVR
)));
137 #ifdef CONFIG_X86_IO_APIC
138 static unsigned int ioapic_id
;
140 static void __init
dtb_add_ioapic(struct device_node
*dn
)
145 ret
= of_address_to_resource(dn
, 0, &r
);
147 printk(KERN_ERR
"Can't obtain address from node %s.\n",
151 mp_register_ioapic(++ioapic_id
, r
.start
, gsi_top
);
154 static void __init
dtb_ioapic_setup(void)
156 struct device_node
*dn
;
158 if (!smp_found_config
)
161 for_each_compatible_node(dn
, NULL
, "intel,ce4100-ioapic")
168 printk(KERN_ERR
"Error: No information about IO-APIC in OF.\n");
169 smp_found_config
= 0;
172 static void __init
dtb_ioapic_setup(void) {}
175 static void __init
dtb_apic_setup(void)
181 void __init
x86_dtb_find_config(void)
184 smp_found_config
= 1;
186 printk(KERN_ERR
"Missing device tree!.\n");
189 void __init
x86_dtb_get_config(unsigned int unused
)
197 map_len
= max(PAGE_SIZE
- (initial_dtb
& ~PAGE_MASK
),
198 (u64
)sizeof(struct boot_param_header
));
200 initial_boot_params
= early_memremap(initial_dtb
, map_len
);
201 size
= be32_to_cpu(initial_boot_params
->totalsize
);
202 if (map_len
< size
) {
203 early_iounmap(initial_boot_params
, map_len
);
204 initial_boot_params
= early_memremap(initial_dtb
, size
);
208 new_dtb
= alloc_bootmem(size
);
209 memcpy(new_dtb
, initial_boot_params
, size
);
210 early_iounmap(initial_boot_params
, map_len
);
212 initial_boot_params
= new_dtb
;
214 /* root level address cells */
215 of_scan_flat_dt(early_init_dt_scan_root
, NULL
);
217 unflatten_device_tree();