Commit | Line | Data |
---|---|---|
da6b737b SAS |
1 | /* |
2 | * Architecture specific OF callbacks. | |
3 | */ | |
4 | #include <linux/bootmem.h> | |
5 | #include <linux/io.h> | |
19c4f5f7 | 6 | #include <linux/interrupt.h> |
da6b737b SAS |
7 | #include <linux/list.h> |
8 | #include <linux/of.h> | |
9 | #include <linux/of_fdt.h> | |
10 | #include <linux/of_platform.h> | |
11 | #include <linux/slab.h> | |
12 | ||
19c4f5f7 SAS |
13 | #include <asm/irq_controller.h> |
14 | ||
da6b737b | 15 | char __initdata cmd_line[COMMAND_LINE_SIZE]; |
19c4f5f7 SAS |
16 | static LIST_HEAD(irq_domains); |
17 | static DEFINE_RAW_SPINLOCK(big_irq_lock); | |
18 | ||
19 | void add_interrupt_host(struct irq_domain *ih) | |
20 | { | |
21 | unsigned long flags; | |
22 | ||
23 | raw_spin_lock_irqsave(&big_irq_lock, flags); | |
24 | list_add(&ih->l, &irq_domains); | |
25 | raw_spin_unlock_irqrestore(&big_irq_lock, flags); | |
26 | } | |
27 | ||
28 | static struct irq_domain *get_ih_from_node(struct device_node *controller) | |
29 | { | |
30 | struct irq_domain *ih, *found = NULL; | |
31 | unsigned long flags; | |
32 | ||
33 | raw_spin_lock_irqsave(&big_irq_lock, flags); | |
34 | list_for_each_entry(ih, &irq_domains, l) { | |
35 | if (ih->controller == controller) { | |
36 | found = ih; | |
37 | break; | |
38 | } | |
39 | } | |
40 | raw_spin_unlock_irqrestore(&big_irq_lock, flags); | |
41 | return found; | |
42 | } | |
da6b737b SAS |
43 | |
44 | unsigned int irq_create_of_mapping(struct device_node *controller, | |
45 | const u32 *intspec, unsigned int intsize) | |
46 | { | |
19c4f5f7 SAS |
47 | struct irq_domain *ih; |
48 | u32 virq, type; | |
49 | int ret; | |
da6b737b | 50 | |
19c4f5f7 SAS |
51 | ih = get_ih_from_node(controller); |
52 | if (!ih) | |
53 | return 0; | |
54 | ret = ih->xlate(ih, intspec, intsize, &virq, &type); | |
55 | if (ret) | |
56 | return ret; | |
57 | if (type == IRQ_TYPE_NONE) | |
58 | return virq; | |
59 | /* set the mask if it is different from current */ | |
60 | if (type == (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK)) | |
61 | set_irq_type(virq, type); | |
62 | return virq; | |
da6b737b SAS |
63 | } |
64 | EXPORT_SYMBOL_GPL(irq_create_of_mapping); | |
65 | ||
66 | unsigned long pci_address_to_pio(phys_addr_t address) | |
67 | { | |
68 | /* | |
69 | * The ioport address can be directly used by inX / outX | |
70 | */ | |
71 | BUG_ON(address >= (1 << 16)); | |
72 | return (unsigned long)address; | |
73 | } | |
74 | EXPORT_SYMBOL_GPL(pci_address_to_pio); | |
75 | ||
76 | void __init early_init_dt_scan_chosen_arch(unsigned long node) | |
77 | { | |
78 | BUG(); | |
79 | } | |
80 | ||
81 | void __init early_init_dt_add_memory_arch(u64 base, u64 size) | |
82 | { | |
83 | BUG(); | |
84 | } | |
85 | ||
86 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | |
87 | { | |
88 | return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS)); | |
89 | } | |
90 | ||
91 | void __init add_dtb(u64 data) | |
92 | { | |
93 | initial_boot_params = phys_to_virt((u64) (u32) data + | |
94 | offsetof(struct setup_data, data)); | |
95 | } |