aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-exynos/common.c')
-rw-r--r--arch/arm/mach-exynos/common.c532
1 files changed, 20 insertions, 512 deletions
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 745e304ad0de..81e6320ca091 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -10,12 +10,14 @@
10 */ 10 */
11 11
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/bitops.h>
13#include <linux/interrupt.h> 14#include <linux/interrupt.h>
14#include <linux/irq.h> 15#include <linux/irq.h>
15#include <linux/irqchip.h> 16#include <linux/irqchip.h>
16#include <linux/io.h> 17#include <linux/io.h>
17#include <linux/device.h> 18#include <linux/device.h>
18#include <linux/gpio.h> 19#include <linux/gpio.h>
20#include <clocksource/samsung_pwm.h>
19#include <linux/sched.h> 21#include <linux/sched.h>
20#include <linux/serial_core.h> 22#include <linux/serial_core.h>
21#include <linux/of.h> 23#include <linux/of.h>
@@ -38,20 +40,9 @@
38 40
39#include <mach/regs-irq.h> 41#include <mach/regs-irq.h>
40#include <mach/regs-pmu.h> 42#include <mach/regs-pmu.h>
41#include <mach/regs-gpio.h>
42#include <mach/irqs.h>
43 43
44#include <plat/cpu.h> 44#include <plat/cpu.h>
45#include <plat/devs.h>
46#include <plat/pm.h> 45#include <plat/pm.h>
47#include <plat/sdhci.h>
48#include <plat/gpio-cfg.h>
49#include <plat/adc-core.h>
50#include <plat/fb-core.h>
51#include <plat/fimc-core.h>
52#include <plat/iic-core.h>
53#include <plat/tv-core.h>
54#include <plat/spi-core.h>
55#include <plat/regs-serial.h> 46#include <plat/regs-serial.h>
56 47
57#include "common.h" 48#include "common.h"
@@ -67,31 +58,25 @@ static const char name_exynos5440[] = "EXYNOS5440";
67static void exynos4_map_io(void); 58static void exynos4_map_io(void);
68static void exynos5_map_io(void); 59static void exynos5_map_io(void);
69static void exynos5440_map_io(void); 60static void exynos5440_map_io(void);
70static void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no);
71static int exynos_init(void); 61static int exynos_init(void);
72 62
73unsigned long xxti_f = 0, xusbxti_f = 0;
74
75static struct cpu_table cpu_ids[] __initdata = { 63static struct cpu_table cpu_ids[] __initdata = {
76 { 64 {
77 .idcode = EXYNOS4210_CPU_ID, 65 .idcode = EXYNOS4210_CPU_ID,
78 .idmask = EXYNOS4_CPU_MASK, 66 .idmask = EXYNOS4_CPU_MASK,
79 .map_io = exynos4_map_io, 67 .map_io = exynos4_map_io,
80 .init_uarts = exynos4_init_uarts,
81 .init = exynos_init, 68 .init = exynos_init,
82 .name = name_exynos4210, 69 .name = name_exynos4210,
83 }, { 70 }, {
84 .idcode = EXYNOS4212_CPU_ID, 71 .idcode = EXYNOS4212_CPU_ID,
85 .idmask = EXYNOS4_CPU_MASK, 72 .idmask = EXYNOS4_CPU_MASK,
86 .map_io = exynos4_map_io, 73 .map_io = exynos4_map_io,
87 .init_uarts = exynos4_init_uarts,
88 .init = exynos_init, 74 .init = exynos_init,
89 .name = name_exynos4212, 75 .name = name_exynos4212,
90 }, { 76 }, {
91 .idcode = EXYNOS4412_CPU_ID, 77 .idcode = EXYNOS4412_CPU_ID,
92 .idmask = EXYNOS4_CPU_MASK, 78 .idmask = EXYNOS4_CPU_MASK,
93 .map_io = exynos4_map_io, 79 .map_io = exynos4_map_io,
94 .init_uarts = exynos4_init_uarts,
95 .init = exynos_init, 80 .init = exynos_init,
96 .name = name_exynos4412, 81 .name = name_exynos4412,
97 }, { 82 }, {
@@ -111,15 +96,6 @@ static struct cpu_table cpu_ids[] __initdata = {
111 96
112/* Initial IO mappings */ 97/* Initial IO mappings */
113 98
114static struct map_desc exynos_iodesc[] __initdata = {
115 {
116 .virtual = (unsigned long)S5P_VA_CHIPID,
117 .pfn = __phys_to_pfn(EXYNOS_PA_CHIPID),
118 .length = SZ_4K,
119 .type = MT_DEVICE,
120 },
121};
122
123static struct map_desc exynos4_iodesc[] __initdata = { 99static struct map_desc exynos4_iodesc[] __initdata = {
124 { 100 {
125 .virtual = (unsigned long)S3C_VA_SYS, 101 .virtual = (unsigned long)S3C_VA_SYS,
@@ -317,9 +293,16 @@ void exynos5_restart(char mode, const char *cmd)
317 val = 0x1; 293 val = 0x1;
318 addr = EXYNOS_SWRESET; 294 addr = EXYNOS_SWRESET;
319 } else if (of_machine_is_compatible("samsung,exynos5440")) { 295 } else if (of_machine_is_compatible("samsung,exynos5440")) {
296 u32 status;
320 np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock"); 297 np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock");
298
299 addr = of_iomap(np, 0) + 0xbc;
300 status = __raw_readl(addr);
301
321 addr = of_iomap(np, 0) + 0xcc; 302 addr = of_iomap(np, 0) + 0xcc;
322 val = (0xfff << 20) | (0x1 << 16); 303 val = __raw_readl(addr);
304
305 val = (val & 0xffff0000) | (status & 0xffff);
323 } else { 306 } else {
324 pr_err("%s: cannot support non-DT\n", __func__); 307 pr_err("%s: cannot support non-DT\n", __func__);
325 return; 308 return;
@@ -337,8 +320,7 @@ void __init exynos_init_late(void)
337 exynos_pm_late_initcall(); 320 exynos_pm_late_initcall();
338} 321}
339 322
340#ifdef CONFIG_OF 323static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
341int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
342 int depth, void *data) 324 int depth, void *data)
343{ 325{
344 struct map_desc iodesc; 326 struct map_desc iodesc;
@@ -360,7 +342,6 @@ int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
360 iotable_init(&iodesc, 1); 342 iotable_init(&iodesc, 1);
361 return 1; 343 return 1;
362} 344}
363#endif
364 345
365/* 346/*
366 * exynos_map_io 347 * exynos_map_io
@@ -368,17 +349,11 @@ int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
368 * register the standard cpu IO areas 349 * register the standard cpu IO areas
369 */ 350 */
370 351
371void __init exynos_init_io(struct map_desc *mach_desc, int size) 352void __init exynos_init_io(void)
372{ 353{
373#ifdef CONFIG_OF 354 debug_ll_io_init();
374 if (initial_boot_params)
375 of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
376 else
377#endif
378 iotable_init(exynos_iodesc, ARRAY_SIZE(exynos_iodesc));
379 355
380 if (mach_desc) 356 of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
381 iotable_init(mach_desc, size);
382 357
383 /* detect cpu id and rev. */ 358 /* detect cpu id and rev. */
384 s5p_init_cpu(S5P_VA_CHIPID); 359 s5p_init_cpu(S5P_VA_CHIPID);
@@ -399,34 +374,6 @@ static void __init exynos4_map_io(void)
399 iotable_init(exynos4210_iodesc, ARRAY_SIZE(exynos4210_iodesc)); 374 iotable_init(exynos4210_iodesc, ARRAY_SIZE(exynos4210_iodesc));
400 if (soc_is_exynos4212() || soc_is_exynos4412()) 375 if (soc_is_exynos4212() || soc_is_exynos4412())
401 iotable_init(exynos4x12_iodesc, ARRAY_SIZE(exynos4x12_iodesc)); 376 iotable_init(exynos4x12_iodesc, ARRAY_SIZE(exynos4x12_iodesc));
402
403 /* initialize device information early */
404 exynos4_default_sdhci0();
405 exynos4_default_sdhci1();
406 exynos4_default_sdhci2();
407 exynos4_default_sdhci3();
408
409 s3c_adc_setname("samsung-adc-v3");
410
411 s3c_fimc_setname(0, "exynos4-fimc");
412 s3c_fimc_setname(1, "exynos4-fimc");
413 s3c_fimc_setname(2, "exynos4-fimc");
414 s3c_fimc_setname(3, "exynos4-fimc");
415
416 s3c_sdhci_setname(0, "exynos4-sdhci");
417 s3c_sdhci_setname(1, "exynos4-sdhci");
418 s3c_sdhci_setname(2, "exynos4-sdhci");
419 s3c_sdhci_setname(3, "exynos4-sdhci");
420
421 /* The I2C bus controllers are directly compatible with s3c2440 */
422 s3c_i2c0_setname("s3c2440-i2c");
423 s3c_i2c1_setname("s3c2440-i2c");
424 s3c_i2c2_setname("s3c2440-i2c");
425
426 s5p_fb_setname(0, "exynos4-fb");
427 s5p_hdmi_setname("exynos4-hdmi");
428
429 s3c64xx_spi_setname("exynos4210-spi");
430} 377}
431 378
432static void __init exynos5_map_io(void) 379static void __init exynos5_map_io(void)
@@ -444,60 +391,8 @@ static void __init exynos5440_map_io(void)
444 391
445void __init exynos_init_time(void) 392void __init exynos_init_time(void)
446{ 393{
447 if (of_have_populated_dt()) { 394 of_clk_init(NULL);
448#ifdef CONFIG_OF 395 clocksource_of_init();
449 of_clk_init(NULL);
450 clocksource_of_init();
451#endif
452 } else {
453 /* todo: remove after migrating legacy E4 platforms to dt */
454#ifdef CONFIG_ARCH_EXYNOS4
455 exynos4_clk_init(NULL, !soc_is_exynos4210(), S5P_VA_CMU, readl(S5P_VA_CHIPID + 8) & 1);
456 exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
457#endif
458 mct_init(S5P_VA_SYSTIMER, EXYNOS4_IRQ_MCT_G0, EXYNOS4_IRQ_MCT_L0, EXYNOS4_IRQ_MCT_L1);
459 }
460}
461
462static unsigned int max_combiner_nr(void)
463{
464 if (soc_is_exynos5250())
465 return EXYNOS5_MAX_COMBINER_NR;
466 else if (soc_is_exynos4412())
467 return EXYNOS4412_MAX_COMBINER_NR;
468 else if (soc_is_exynos4212())
469 return EXYNOS4212_MAX_COMBINER_NR;
470 else
471 return EXYNOS4210_MAX_COMBINER_NR;
472}
473
474
475void __init exynos4_init_irq(void)
476{
477 unsigned int gic_bank_offset;
478
479 gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
480
481 if (!of_have_populated_dt())
482 gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset, NULL);
483#ifdef CONFIG_OF
484 else
485 irqchip_init();
486#endif
487
488 if (!of_have_populated_dt())
489 combiner_init(S5P_VA_COMBINER_BASE, NULL,
490 max_combiner_nr(), COMBINER_IRQ(0, 0));
491
492 gic_arch_extn.irq_set_wake = s3c_irq_wake;
493}
494
495void __init exynos5_init_irq(void)
496{
497#ifdef CONFIG_OF
498 irqchip_init();
499#endif
500 gic_arch_extn.irq_set_wake = s3c_irq_wake;
501} 396}
502 397
503struct bus_type exynos_subsys = { 398struct bus_type exynos_subsys = {
@@ -515,59 +410,19 @@ static int __init exynos_core_init(void)
515} 410}
516core_initcall(exynos_core_init); 411core_initcall(exynos_core_init);
517 412
518#ifdef CONFIG_CACHE_L2X0
519static int __init exynos4_l2x0_cache_init(void) 413static int __init exynos4_l2x0_cache_init(void)
520{ 414{
521 int ret; 415 int ret;
522 416
523 if (soc_is_exynos5250() || soc_is_exynos5440())
524 return 0;
525
526 ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK); 417 ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
527 if (!ret) { 418 if (ret)
528 l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs); 419 return ret;
529 clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
530 return 0;
531 }
532
533 if (!(__raw_readl(S5P_VA_L2CC + L2X0_CTRL) & 0x1)) {
534 l2x0_saved_regs.phy_base = EXYNOS4_PA_L2CC;
535 /* TAG, Data Latency Control: 2 cycles */
536 l2x0_saved_regs.tag_latency = 0x110;
537
538 if (soc_is_exynos4212() || soc_is_exynos4412())
539 l2x0_saved_regs.data_latency = 0x120;
540 else
541 l2x0_saved_regs.data_latency = 0x110;
542
543 l2x0_saved_regs.prefetch_ctrl = 0x30000007;
544 l2x0_saved_regs.pwr_ctrl =
545 (L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN);
546
547 l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
548
549 __raw_writel(l2x0_saved_regs.tag_latency,
550 S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
551 __raw_writel(l2x0_saved_regs.data_latency,
552 S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
553
554 /* L2X0 Prefetch Control */
555 __raw_writel(l2x0_saved_regs.prefetch_ctrl,
556 S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
557 420
558 /* L2X0 Power Control */ 421 l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
559 __raw_writel(l2x0_saved_regs.pwr_ctrl, 422 clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
560 S5P_VA_L2CC + L2X0_POWER_CTRL);
561
562 clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
563 clean_dcache_area(&l2x0_saved_regs, sizeof(struct l2x0_regs));
564 }
565
566 l2x0_init(S5P_VA_L2CC, L2_AUX_VAL, L2_AUX_MASK);
567 return 0; 423 return 0;
568} 424}
569early_initcall(exynos4_l2x0_cache_init); 425early_initcall(exynos4_l2x0_cache_init);
570#endif
571 426
572static int __init exynos_init(void) 427static int __init exynos_init(void)
573{ 428{
@@ -575,350 +430,3 @@ static int __init exynos_init(void)
575 430
576 return device_register(&exynos4_dev); 431 return device_register(&exynos4_dev);
577} 432}
578
579/* uart registration process */
580
581static void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no)
582{
583 struct s3c2410_uartcfg *tcfg = cfg;
584 u32 ucnt;
585
586 for (ucnt = 0; ucnt < no; ucnt++, tcfg++)
587 tcfg->has_fracval = 1;
588
589 s3c24xx_init_uartdevs("exynos4210-uart", exynos4_uart_resources, cfg, no);
590}
591
592static void __iomem *exynos_eint_base;
593
594static DEFINE_SPINLOCK(eint_lock);
595
596static unsigned int eint0_15_data[16];
597
598static inline int exynos4_irq_to_gpio(unsigned int irq)
599{
600 if (irq < IRQ_EINT(0))
601 return -EINVAL;
602
603 irq -= IRQ_EINT(0);
604 if (irq < 8)
605 return EXYNOS4_GPX0(irq);
606
607 irq -= 8;
608 if (irq < 8)
609 return EXYNOS4_GPX1(irq);
610
611 irq -= 8;
612 if (irq < 8)
613 return EXYNOS4_GPX2(irq);
614
615 irq -= 8;
616 if (irq < 8)
617 return EXYNOS4_GPX3(irq);
618
619 return -EINVAL;
620}
621
622static inline int exynos5_irq_to_gpio(unsigned int irq)
623{
624 if (irq < IRQ_EINT(0))
625 return -EINVAL;
626
627 irq -= IRQ_EINT(0);
628 if (irq < 8)
629 return EXYNOS5_GPX0(irq);
630
631 irq -= 8;
632 if (irq < 8)
633 return EXYNOS5_GPX1(irq);
634
635 irq -= 8;
636 if (irq < 8)
637 return EXYNOS5_GPX2(irq);
638
639 irq -= 8;
640 if (irq < 8)
641 return EXYNOS5_GPX3(irq);
642
643 return -EINVAL;
644}
645
646static unsigned int exynos4_eint0_15_src_int[16] = {
647 EXYNOS4_IRQ_EINT0,
648 EXYNOS4_IRQ_EINT1,
649 EXYNOS4_IRQ_EINT2,
650 EXYNOS4_IRQ_EINT3,
651 EXYNOS4_IRQ_EINT4,
652 EXYNOS4_IRQ_EINT5,
653 EXYNOS4_IRQ_EINT6,
654 EXYNOS4_IRQ_EINT7,
655 EXYNOS4_IRQ_EINT8,
656 EXYNOS4_IRQ_EINT9,
657 EXYNOS4_IRQ_EINT10,
658 EXYNOS4_IRQ_EINT11,
659 EXYNOS4_IRQ_EINT12,
660 EXYNOS4_IRQ_EINT13,
661 EXYNOS4_IRQ_EINT14,
662 EXYNOS4_IRQ_EINT15,
663};
664
665static unsigned int exynos5_eint0_15_src_int[16] = {
666 EXYNOS5_IRQ_EINT0,
667 EXYNOS5_IRQ_EINT1,
668 EXYNOS5_IRQ_EINT2,
669 EXYNOS5_IRQ_EINT3,
670 EXYNOS5_IRQ_EINT4,
671 EXYNOS5_IRQ_EINT5,
672 EXYNOS5_IRQ_EINT6,
673 EXYNOS5_IRQ_EINT7,
674 EXYNOS5_IRQ_EINT8,
675 EXYNOS5_IRQ_EINT9,
676 EXYNOS5_IRQ_EINT10,
677 EXYNOS5_IRQ_EINT11,
678 EXYNOS5_IRQ_EINT12,
679 EXYNOS5_IRQ_EINT13,
680 EXYNOS5_IRQ_EINT14,
681 EXYNOS5_IRQ_EINT15,
682};
683static inline void exynos_irq_eint_mask(struct irq_data *data)
684{
685 u32 mask;
686
687 spin_lock(&eint_lock);
688 mask = __raw_readl(EINT_MASK(exynos_eint_base, data->irq));
689 mask |= EINT_OFFSET_BIT(data->irq);
690 __raw_writel(mask, EINT_MASK(exynos_eint_base, data->irq));
691 spin_unlock(&eint_lock);
692}
693
694static void exynos_irq_eint_unmask(struct irq_data *data)
695{
696 u32 mask;
697
698 spin_lock(&eint_lock);
699 mask = __raw_readl(EINT_MASK(exynos_eint_base, data->irq));
700 mask &= ~(EINT_OFFSET_BIT(data->irq));
701 __raw_writel(mask, EINT_MASK(exynos_eint_base, data->irq));
702 spin_unlock(&eint_lock);
703}
704
705static inline void exynos_irq_eint_ack(struct irq_data *data)
706{
707 __raw_writel(EINT_OFFSET_BIT(data->irq),
708 EINT_PEND(exynos_eint_base, data->irq));
709}
710
711static void exynos_irq_eint_maskack(struct irq_data *data)
712{
713 exynos_irq_eint_mask(data);
714 exynos_irq_eint_ack(data);
715}
716
717static int exynos_irq_eint_set_type(struct irq_data *data, unsigned int type)
718{
719 int offs = EINT_OFFSET(data->irq);
720 int shift;
721 u32 ctrl, mask;
722 u32 newvalue = 0;
723
724 switch (type) {
725 case IRQ_TYPE_EDGE_RISING:
726 newvalue = S5P_IRQ_TYPE_EDGE_RISING;
727 break;
728
729 case IRQ_TYPE_EDGE_FALLING:
730 newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
731 break;
732
733 case IRQ_TYPE_EDGE_BOTH:
734 newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
735 break;
736
737 case IRQ_TYPE_LEVEL_LOW:
738 newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
739 break;
740
741 case IRQ_TYPE_LEVEL_HIGH:
742 newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
743 break;
744
745 default:
746 printk(KERN_ERR "No such irq type %d", type);
747 return -EINVAL;
748 }
749
750 shift = (offs & 0x7) * 4;
751 mask = 0x7 << shift;
752
753 spin_lock(&eint_lock);
754 ctrl = __raw_readl(EINT_CON(exynos_eint_base, data->irq));
755 ctrl &= ~mask;
756 ctrl |= newvalue << shift;
757 __raw_writel(ctrl, EINT_CON(exynos_eint_base, data->irq));
758 spin_unlock(&eint_lock);
759
760 if (soc_is_exynos5250())
761 s3c_gpio_cfgpin(exynos5_irq_to_gpio(data->irq), S3C_GPIO_SFN(0xf));
762 else
763 s3c_gpio_cfgpin(exynos4_irq_to_gpio(data->irq), S3C_GPIO_SFN(0xf));
764
765 return 0;
766}
767
768static struct irq_chip exynos_irq_eint = {
769 .name = "exynos-eint",
770 .irq_mask = exynos_irq_eint_mask,
771 .irq_unmask = exynos_irq_eint_unmask,
772 .irq_mask_ack = exynos_irq_eint_maskack,
773 .irq_ack = exynos_irq_eint_ack,
774 .irq_set_type = exynos_irq_eint_set_type,
775#ifdef CONFIG_PM
776 .irq_set_wake = s3c_irqext_wake,
777#endif
778};
779
780/*
781 * exynos4_irq_demux_eint
782 *
783 * This function demuxes the IRQ from from EINTs 16 to 31.
784 * It is designed to be inlined into the specific handler
785 * s5p_irq_demux_eintX_Y.
786 *
787 * Each EINT pend/mask registers handle eight of them.
788 */
789static inline void exynos_irq_demux_eint(unsigned int start)
790{
791 unsigned int irq;
792
793 u32 status = __raw_readl(EINT_PEND(exynos_eint_base, start));
794 u32 mask = __raw_readl(EINT_MASK(exynos_eint_base, start));
795
796 status &= ~mask;
797 status &= 0xff;
798
799 while (status) {
800 irq = fls(status) - 1;
801 generic_handle_irq(irq + start);
802 status &= ~(1 << irq);
803 }
804}
805
806static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
807{
808 struct irq_chip *chip = irq_get_chip(irq);
809 chained_irq_enter(chip, desc);
810 exynos_irq_demux_eint(IRQ_EINT(16));
811 exynos_irq_demux_eint(IRQ_EINT(24));
812 chained_irq_exit(chip, desc);
813}
814
815static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
816{
817 u32 *irq_data = irq_get_handler_data(irq);
818 struct irq_chip *chip = irq_get_chip(irq);
819
820 chained_irq_enter(chip, desc);
821 generic_handle_irq(*irq_data);
822 chained_irq_exit(chip, desc);
823}
824
825static int __init exynos_init_irq_eint(void)
826{
827 int irq;
828
829#ifdef CONFIG_PINCTRL_SAMSUNG
830 /*
831 * The Samsung pinctrl driver provides an integrated gpio/pinmux/pinconf
832 * functionality along with support for external gpio and wakeup
833 * interrupts. If the samsung pinctrl driver is enabled and includes
834 * the wakeup interrupt support, then the setting up external wakeup
835 * interrupts here can be skipped. This check here is temporary to
836 * allow exynos4 platforms that do not use Samsung pinctrl driver to
837 * co-exist with platforms that do. When all of the Samsung Exynos4
838 * platforms switch over to using the pinctrl driver, the wakeup
839 * interrupt support code here can be completely removed.
840 */
841 static const struct of_device_id exynos_pinctrl_ids[] = {
842 { .compatible = "samsung,exynos4210-pinctrl", },
843 { .compatible = "samsung,exynos4x12-pinctrl", },
844 { .compatible = "samsung,exynos5250-pinctrl", },
845 };
846 struct device_node *pctrl_np, *wkup_np;
847 const char *wkup_compat = "samsung,exynos4210-wakeup-eint";
848
849 for_each_matching_node(pctrl_np, exynos_pinctrl_ids) {
850 if (of_device_is_available(pctrl_np)) {
851 wkup_np = of_find_compatible_node(pctrl_np, NULL,
852 wkup_compat);
853 if (wkup_np)
854 return -ENODEV;
855 }
856 }
857#endif
858 if (soc_is_exynos5440())
859 return 0;
860
861 if (soc_is_exynos5250())
862 exynos_eint_base = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
863 else
864 exynos_eint_base = ioremap(EXYNOS4_PA_GPIO2, SZ_4K);
865
866 if (exynos_eint_base == NULL) {
867 pr_err("unable to ioremap for EINT base address\n");
868 return -ENOMEM;
869 }
870
871 for (irq = 0 ; irq <= 31 ; irq++) {
872 irq_set_chip_and_handler(IRQ_EINT(irq), &exynos_irq_eint,
873 handle_level_irq);
874 set_irq_flags(IRQ_EINT(irq), IRQF_VALID);
875 }
876
877 irq_set_chained_handler(EXYNOS_IRQ_EINT16_31, exynos_irq_demux_eint16_31);
878
879 for (irq = 0 ; irq <= 15 ; irq++) {
880 eint0_15_data[irq] = IRQ_EINT(irq);
881
882 if (soc_is_exynos5250()) {
883 irq_set_handler_data(exynos5_eint0_15_src_int[irq],
884 &eint0_15_data[irq]);
885 irq_set_chained_handler(exynos5_eint0_15_src_int[irq],
886 exynos_irq_eint0_15);
887 } else {
888 irq_set_handler_data(exynos4_eint0_15_src_int[irq],
889 &eint0_15_data[irq]);
890 irq_set_chained_handler(exynos4_eint0_15_src_int[irq],
891 exynos_irq_eint0_15);
892 }
893 }
894
895 return 0;
896}
897arch_initcall(exynos_init_irq_eint);
898
899static struct resource exynos4_pmu_resource[] = {
900 DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU),
901 DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU1),
902#if defined(CONFIG_SOC_EXYNOS4412)
903 DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU2),
904 DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU3),
905#endif
906};
907
908static struct platform_device exynos4_device_pmu = {
909 .name = "arm-pmu",
910 .num_resources = ARRAY_SIZE(exynos4_pmu_resource),
911 .resource = exynos4_pmu_resource,
912};
913
914static int __init exynos_armpmu_init(void)
915{
916 if (!of_have_populated_dt()) {
917 if (soc_is_exynos4210() || soc_is_exynos4212())
918 exynos4_device_pmu.num_resources = 2;
919 platform_device_register(&exynos4_device_pmu);
920 }
921
922 return 0;
923}
924arch_initcall(exynos_armpmu_init);