diff options
author | Jiang Liu <jiang.liu@linux.intel.com> | 2014-06-09 04:19:57 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2014-06-21 17:05:43 -0400 |
commit | facd8fdb25fc4d041a283446cfb040cbfe2c3723 (patch) | |
tree | 090f50218fca1de695eb7ebdf8ce5894971d8691 /arch/x86/kernel/devicetree.c | |
parent | 1b5d3e00d45e093fa0551c588034c3355b362f66 (diff) |
x86, devicetree, irq: Use common mechanism to support irqdomain
Now the ioapic driver provides a common interface to create irqdomain,
so replace the private implementation.
Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Tony Lindgren <tony@atomide.com>
Link: http://lkml.kernel.org/r/1402302011-23642-29-git-send-email-jiang.liu@linux.intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/devicetree.c')
-rw-r--r-- | arch/x86/kernel/devicetree.c | 191 |
1 files changed, 59 insertions, 132 deletions
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index d2c53feacd77..ee26feca93d9 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c | |||
@@ -166,82 +166,6 @@ static void __init dtb_lapic_setup(void) | |||
166 | #ifdef CONFIG_X86_IO_APIC | 166 | #ifdef CONFIG_X86_IO_APIC |
167 | static unsigned int ioapic_id; | 167 | static unsigned int ioapic_id; |
168 | 168 | ||
169 | static void __init dtb_add_ioapic(struct device_node *dn) | ||
170 | { | ||
171 | struct resource r; | ||
172 | int ret; | ||
173 | |||
174 | ret = of_address_to_resource(dn, 0, &r); | ||
175 | if (ret) { | ||
176 | printk(KERN_ERR "Can't obtain address from node %s.\n", | ||
177 | dn->full_name); | ||
178 | return; | ||
179 | } | ||
180 | mp_register_ioapic(++ioapic_id, r.start, gsi_top, NULL); | ||
181 | } | ||
182 | |||
183 | static void __init dtb_ioapic_setup(void) | ||
184 | { | ||
185 | struct device_node *dn; | ||
186 | |||
187 | for_each_compatible_node(dn, NULL, "intel,ce4100-ioapic") | ||
188 | dtb_add_ioapic(dn); | ||
189 | |||
190 | if (nr_ioapics) { | ||
191 | of_ioapic = 1; | ||
192 | return; | ||
193 | } | ||
194 | printk(KERN_ERR "Error: No information about IO-APIC in OF.\n"); | ||
195 | } | ||
196 | #else | ||
197 | static void __init dtb_ioapic_setup(void) {} | ||
198 | #endif | ||
199 | |||
200 | static void __init dtb_apic_setup(void) | ||
201 | { | ||
202 | dtb_lapic_setup(); | ||
203 | dtb_ioapic_setup(); | ||
204 | } | ||
205 | |||
206 | #ifdef CONFIG_OF_FLATTREE | ||
207 | static void __init x86_flattree_get_config(void) | ||
208 | { | ||
209 | u32 size, map_len; | ||
210 | void *dt; | ||
211 | |||
212 | if (!initial_dtb) | ||
213 | return; | ||
214 | |||
215 | map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128); | ||
216 | |||
217 | initial_boot_params = dt = early_memremap(initial_dtb, map_len); | ||
218 | size = of_get_flat_dt_size(); | ||
219 | if (map_len < size) { | ||
220 | early_iounmap(dt, map_len); | ||
221 | initial_boot_params = dt = early_memremap(initial_dtb, size); | ||
222 | map_len = size; | ||
223 | } | ||
224 | |||
225 | unflatten_and_copy_device_tree(); | ||
226 | early_iounmap(dt, map_len); | ||
227 | } | ||
228 | #else | ||
229 | static inline void x86_flattree_get_config(void) { } | ||
230 | #endif | ||
231 | |||
232 | void __init x86_dtb_init(void) | ||
233 | { | ||
234 | x86_flattree_get_config(); | ||
235 | |||
236 | if (!of_have_populated_dt()) | ||
237 | return; | ||
238 | |||
239 | dtb_setup_hpet(); | ||
240 | dtb_apic_setup(); | ||
241 | } | ||
242 | |||
243 | #ifdef CONFIG_X86_IO_APIC | ||
244 | |||
245 | struct of_ioapic_type { | 169 | struct of_ioapic_type { |
246 | u32 out_type; | 170 | u32 out_type; |
247 | u32 trigger; | 171 | u32 trigger; |
@@ -292,7 +216,7 @@ static int ioapic_xlate(struct irq_domain *domain, | |||
292 | 216 | ||
293 | it = &of_ioapic_type[intspec[1]]; | 217 | it = &of_ioapic_type[intspec[1]]; |
294 | 218 | ||
295 | idx = (u32) domain->host_data; | 219 | idx = (u32)(long)domain->host_data; |
296 | set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity); | 220 | set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity); |
297 | 221 | ||
298 | rc = io_apic_setup_irq_pin_once(irq_find_mapping(domain, line), | 222 | rc = io_apic_setup_irq_pin_once(irq_find_mapping(domain, line), |
@@ -309,78 +233,81 @@ const struct irq_domain_ops ioapic_irq_domain_ops = { | |||
309 | .xlate = ioapic_xlate, | 233 | .xlate = ioapic_xlate, |
310 | }; | 234 | }; |
311 | 235 | ||
312 | static void dt_add_ioapic_domain(unsigned int ioapic_num, | 236 | static void __init dtb_add_ioapic(struct device_node *dn) |
313 | struct device_node *np) | ||
314 | { | 237 | { |
315 | struct irq_domain *id; | 238 | struct resource r; |
316 | struct mp_ioapic_gsi *gsi_cfg; | ||
317 | int ret; | 239 | int ret; |
318 | int num, legacy_irqs = nr_legacy_irqs(); | 240 | struct ioapic_domain_cfg cfg = { |
319 | 241 | .type = IOAPIC_DOMAIN_DYNAMIC, | |
320 | gsi_cfg = mp_ioapic_gsi_routing(ioapic_num); | 242 | .ops = &ioapic_irq_domain_ops, |
321 | num = gsi_cfg->gsi_end - gsi_cfg->gsi_base + 1; | 243 | .dev = dn, |
322 | 244 | }; | |
323 | id = irq_domain_add_linear(np, num, &ioapic_irq_domain_ops, | 245 | |
324 | (void *)ioapic_num); | 246 | ret = of_address_to_resource(dn, 0, &r); |
325 | BUG_ON(!id); | 247 | if (ret) { |
326 | if (gsi_cfg->gsi_base == 0) { | 248 | printk(KERN_ERR "Can't obtain address from node %s.\n", |
327 | /* | 249 | dn->full_name); |
328 | * The first nr_legacy_irqs() irq descs are allocated in | 250 | return; |
329 | * early_irq_init() and need just a mapping. The | ||
330 | * remaining irqs need both. All of them are preallocated | ||
331 | * and assigned so we can keep the 1:1 mapping which the ioapic | ||
332 | * is having. | ||
333 | */ | ||
334 | irq_domain_associate_many(id, 0, 0, legacy_irqs); | ||
335 | |||
336 | if (num > legacy_irqs) { | ||
337 | ret = irq_create_strict_mappings(id, legacy_irqs, | ||
338 | legacy_irqs, num - legacy_irqs); | ||
339 | if (ret) | ||
340 | pr_err("Error creating mapping for the " | ||
341 | "remaining IRQs: %d\n", ret); | ||
342 | } | ||
343 | irq_set_default_host(id); | ||
344 | } else { | ||
345 | ret = irq_create_strict_mappings(id, gsi_cfg->gsi_base, 0, num); | ||
346 | if (ret) | ||
347 | pr_err("Error creating IRQ mapping: %d\n", ret); | ||
348 | } | 251 | } |
252 | mp_register_ioapic(++ioapic_id, r.start, gsi_top, &cfg); | ||
349 | } | 253 | } |
350 | 254 | ||
351 | static void __init ioapic_add_ofnode(struct device_node *np) | 255 | static void __init dtb_ioapic_setup(void) |
352 | { | 256 | { |
353 | struct resource r; | 257 | struct device_node *dn; |
354 | int i, ret; | ||
355 | 258 | ||
356 | ret = of_address_to_resource(np, 0, &r); | 259 | for_each_compatible_node(dn, NULL, "intel,ce4100-ioapic") |
357 | if (ret) { | 260 | dtb_add_ioapic(dn); |
358 | printk(KERN_ERR "Failed to obtain address for %s\n", | 261 | |
359 | np->full_name); | 262 | if (nr_ioapics) { |
263 | of_ioapic = 1; | ||
360 | return; | 264 | return; |
361 | } | 265 | } |
266 | printk(KERN_ERR "Error: No information about IO-APIC in OF.\n"); | ||
267 | } | ||
268 | #else | ||
269 | static void __init dtb_ioapic_setup(void) {} | ||
270 | #endif | ||
362 | 271 | ||
363 | for (i = 0; i < nr_ioapics; i++) { | 272 | static void __init dtb_apic_setup(void) |
364 | if (r.start == mpc_ioapic_addr(i)) { | 273 | { |
365 | dt_add_ioapic_domain(i, np); | 274 | dtb_lapic_setup(); |
366 | return; | 275 | dtb_ioapic_setup(); |
367 | } | ||
368 | } | ||
369 | printk(KERN_ERR "IOxAPIC at %s is not registered.\n", np->full_name); | ||
370 | } | 276 | } |
371 | 277 | ||
372 | void __init x86_add_irq_domains(void) | 278 | #ifdef CONFIG_OF_FLATTREE |
279 | static void __init x86_flattree_get_config(void) | ||
373 | { | 280 | { |
374 | struct device_node *dp; | 281 | u32 size, map_len; |
282 | void *dt; | ||
375 | 283 | ||
376 | if (!of_have_populated_dt()) | 284 | if (!initial_dtb) |
377 | return; | 285 | return; |
378 | 286 | ||
379 | for_each_node_with_property(dp, "interrupt-controller") { | 287 | map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128); |
380 | if (of_device_is_compatible(dp, "intel,ce4100-ioapic")) | 288 | |
381 | ioapic_add_ofnode(dp); | 289 | initial_boot_params = dt = early_memremap(initial_dtb, map_len); |
290 | size = of_get_flat_dt_size(); | ||
291 | if (map_len < size) { | ||
292 | early_iounmap(dt, map_len); | ||
293 | initial_boot_params = dt = early_memremap(initial_dtb, size); | ||
294 | map_len = size; | ||
382 | } | 295 | } |
296 | |||
297 | unflatten_and_copy_device_tree(); | ||
298 | early_iounmap(dt, map_len); | ||
383 | } | 299 | } |
384 | #else | 300 | #else |
385 | void __init x86_add_irq_domains(void) { } | 301 | static inline void x86_flattree_get_config(void) { } |
386 | #endif | 302 | #endif |
303 | |||
304 | void __init x86_dtb_init(void) | ||
305 | { | ||
306 | x86_flattree_get_config(); | ||
307 | |||
308 | if (!of_have_populated_dt()) | ||
309 | return; | ||
310 | |||
311 | dtb_setup_hpet(); | ||
312 | dtb_apic_setup(); | ||
313 | } | ||