diff options
-rw-r--r-- | drivers/gpio/gpio-samsung.c | 403 |
1 files changed, 215 insertions, 188 deletions
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index 19d6fc0229c3..5d49aff3bb9e 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c | |||
@@ -2714,12 +2714,224 @@ static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip, | |||
2714 | } | 2714 | } |
2715 | #endif /* defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) */ | 2715 | #endif /* defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) */ |
2716 | 2716 | ||
2717 | static __init void exynos4_gpiolib_init(void) | ||
2718 | { | ||
2719 | #ifdef CONFIG_CPU_EXYNOS4210 | ||
2720 | struct samsung_gpio_chip *chip; | ||
2721 | int i, nr_chips; | ||
2722 | void __iomem *gpio_base1, *gpio_base2, *gpio_base3; | ||
2723 | int group = 0; | ||
2724 | void __iomem *gpx_base; | ||
2725 | |||
2726 | /* gpio part1 */ | ||
2727 | gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K); | ||
2728 | if (gpio_base1 == NULL) { | ||
2729 | pr_err("unable to ioremap for gpio_base1\n"); | ||
2730 | goto err_ioremap1; | ||
2731 | } | ||
2732 | |||
2733 | chip = exynos4_gpios_1; | ||
2734 | nr_chips = ARRAY_SIZE(exynos4_gpios_1); | ||
2735 | |||
2736 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2737 | if (!chip->config) { | ||
2738 | chip->config = &exynos_gpio_cfg; | ||
2739 | chip->group = group++; | ||
2740 | } | ||
2741 | exynos_gpiolib_attach_ofnode(chip, | ||
2742 | EXYNOS4_PA_GPIO1, i * 0x20); | ||
2743 | } | ||
2744 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, | ||
2745 | nr_chips, gpio_base1); | ||
2746 | |||
2747 | /* gpio part2 */ | ||
2748 | gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K); | ||
2749 | if (gpio_base2 == NULL) { | ||
2750 | pr_err("unable to ioremap for gpio_base2\n"); | ||
2751 | goto err_ioremap2; | ||
2752 | } | ||
2753 | |||
2754 | /* need to set base address for gpx */ | ||
2755 | chip = &exynos4_gpios_2[16]; | ||
2756 | gpx_base = gpio_base2 + 0xC00; | ||
2757 | for (i = 0; i < 4; i++, chip++, gpx_base += 0x20) | ||
2758 | chip->base = gpx_base; | ||
2759 | |||
2760 | chip = exynos4_gpios_2; | ||
2761 | nr_chips = ARRAY_SIZE(exynos4_gpios_2); | ||
2762 | |||
2763 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2764 | if (!chip->config) { | ||
2765 | chip->config = &exynos_gpio_cfg; | ||
2766 | chip->group = group++; | ||
2767 | } | ||
2768 | exynos_gpiolib_attach_ofnode(chip, | ||
2769 | EXYNOS4_PA_GPIO2, i * 0x20); | ||
2770 | } | ||
2771 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, | ||
2772 | nr_chips, gpio_base2); | ||
2773 | |||
2774 | /* gpio part3 */ | ||
2775 | gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256); | ||
2776 | if (gpio_base3 == NULL) { | ||
2777 | pr_err("unable to ioremap for gpio_base3\n"); | ||
2778 | goto err_ioremap3; | ||
2779 | } | ||
2780 | |||
2781 | chip = exynos4_gpios_3; | ||
2782 | nr_chips = ARRAY_SIZE(exynos4_gpios_3); | ||
2783 | |||
2784 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2785 | if (!chip->config) { | ||
2786 | chip->config = &exynos_gpio_cfg; | ||
2787 | chip->group = group++; | ||
2788 | } | ||
2789 | exynos_gpiolib_attach_ofnode(chip, | ||
2790 | EXYNOS4_PA_GPIO3, i * 0x20); | ||
2791 | } | ||
2792 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, | ||
2793 | nr_chips, gpio_base3); | ||
2794 | |||
2795 | #if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT) | ||
2796 | s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS); | ||
2797 | s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS); | ||
2798 | #endif | ||
2799 | |||
2800 | return; | ||
2801 | |||
2802 | err_ioremap3: | ||
2803 | iounmap(gpio_base2); | ||
2804 | err_ioremap2: | ||
2805 | iounmap(gpio_base1); | ||
2806 | err_ioremap1: | ||
2807 | return; | ||
2808 | #endif /* CONFIG_CPU_EXYNOS4210 */ | ||
2809 | } | ||
2810 | |||
2811 | static __init void exynos5_gpiolib_init(void) | ||
2812 | { | ||
2813 | #ifdef CONFIG_SOC_EXYNOS5250 | ||
2814 | struct samsung_gpio_chip *chip; | ||
2815 | int i, nr_chips; | ||
2816 | void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4; | ||
2817 | int group = 0; | ||
2818 | void __iomem *gpx_base; | ||
2819 | |||
2820 | /* gpio part1 */ | ||
2821 | gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K); | ||
2822 | if (gpio_base1 == NULL) { | ||
2823 | pr_err("unable to ioremap for gpio_base1\n"); | ||
2824 | goto err_ioremap1; | ||
2825 | } | ||
2826 | |||
2827 | /* need to set base address for gpx */ | ||
2828 | chip = &exynos5_gpios_1[20]; | ||
2829 | gpx_base = gpio_base1 + 0xC00; | ||
2830 | for (i = 0; i < 4; i++, chip++, gpx_base += 0x20) | ||
2831 | chip->base = gpx_base; | ||
2832 | |||
2833 | chip = exynos5_gpios_1; | ||
2834 | nr_chips = ARRAY_SIZE(exynos5_gpios_1); | ||
2835 | |||
2836 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2837 | if (!chip->config) { | ||
2838 | chip->config = &exynos_gpio_cfg; | ||
2839 | chip->group = group++; | ||
2840 | } | ||
2841 | exynos_gpiolib_attach_ofnode(chip, | ||
2842 | EXYNOS5_PA_GPIO1, i * 0x20); | ||
2843 | } | ||
2844 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_1, | ||
2845 | nr_chips, gpio_base1); | ||
2846 | |||
2847 | /* gpio part2 */ | ||
2848 | gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K); | ||
2849 | if (gpio_base2 == NULL) { | ||
2850 | pr_err("unable to ioremap for gpio_base2\n"); | ||
2851 | goto err_ioremap2; | ||
2852 | } | ||
2853 | |||
2854 | chip = exynos5_gpios_2; | ||
2855 | nr_chips = ARRAY_SIZE(exynos5_gpios_2); | ||
2856 | |||
2857 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2858 | if (!chip->config) { | ||
2859 | chip->config = &exynos_gpio_cfg; | ||
2860 | chip->group = group++; | ||
2861 | } | ||
2862 | exynos_gpiolib_attach_ofnode(chip, | ||
2863 | EXYNOS5_PA_GPIO2, i * 0x20); | ||
2864 | } | ||
2865 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_2, | ||
2866 | nr_chips, gpio_base2); | ||
2867 | |||
2868 | /* gpio part3 */ | ||
2869 | gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K); | ||
2870 | if (gpio_base3 == NULL) { | ||
2871 | pr_err("unable to ioremap for gpio_base3\n"); | ||
2872 | goto err_ioremap3; | ||
2873 | } | ||
2874 | |||
2875 | /* need to set base address for gpv */ | ||
2876 | exynos5_gpios_3[0].base = gpio_base3; | ||
2877 | exynos5_gpios_3[1].base = gpio_base3 + 0x20; | ||
2878 | exynos5_gpios_3[2].base = gpio_base3 + 0x60; | ||
2879 | exynos5_gpios_3[3].base = gpio_base3 + 0x80; | ||
2880 | exynos5_gpios_3[4].base = gpio_base3 + 0xC0; | ||
2881 | |||
2882 | chip = exynos5_gpios_3; | ||
2883 | nr_chips = ARRAY_SIZE(exynos5_gpios_3); | ||
2884 | |||
2885 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2886 | if (!chip->config) { | ||
2887 | chip->config = &exynos_gpio_cfg; | ||
2888 | chip->group = group++; | ||
2889 | } | ||
2890 | exynos_gpiolib_attach_ofnode(chip, | ||
2891 | EXYNOS5_PA_GPIO3, i * 0x20); | ||
2892 | } | ||
2893 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_3, | ||
2894 | nr_chips, gpio_base3); | ||
2895 | |||
2896 | /* gpio part4 */ | ||
2897 | gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K); | ||
2898 | if (gpio_base4 == NULL) { | ||
2899 | pr_err("unable to ioremap for gpio_base4\n"); | ||
2900 | goto err_ioremap4; | ||
2901 | } | ||
2902 | |||
2903 | chip = exynos5_gpios_4; | ||
2904 | nr_chips = ARRAY_SIZE(exynos5_gpios_4); | ||
2905 | |||
2906 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2907 | if (!chip->config) { | ||
2908 | chip->config = &exynos_gpio_cfg; | ||
2909 | chip->group = group++; | ||
2910 | } | ||
2911 | exynos_gpiolib_attach_ofnode(chip, | ||
2912 | EXYNOS5_PA_GPIO4, i * 0x20); | ||
2913 | } | ||
2914 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_4, | ||
2915 | nr_chips, gpio_base4); | ||
2916 | return; | ||
2917 | |||
2918 | err_ioremap4: | ||
2919 | iounmap(gpio_base3); | ||
2920 | err_ioremap3: | ||
2921 | iounmap(gpio_base2); | ||
2922 | err_ioremap2: | ||
2923 | iounmap(gpio_base1); | ||
2924 | err_ioremap1: | ||
2925 | return; | ||
2926 | |||
2927 | #endif /* CONFIG_SOC_EXYNOS5250 */ | ||
2928 | } | ||
2929 | |||
2717 | /* TODO: cleanup soc_is_* */ | 2930 | /* TODO: cleanup soc_is_* */ |
2718 | static __init int samsung_gpiolib_init(void) | 2931 | static __init int samsung_gpiolib_init(void) |
2719 | { | 2932 | { |
2720 | struct samsung_gpio_chip *chip; | 2933 | struct samsung_gpio_chip *chip; |
2721 | int i, nr_chips; | 2934 | int i, nr_chips; |
2722 | void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4; | ||
2723 | int group = 0; | 2935 | int group = 0; |
2724 | 2936 | ||
2725 | samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); | 2937 | samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); |
@@ -2785,200 +2997,15 @@ static __init int samsung_gpiolib_init(void) | |||
2785 | s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR); | 2997 | s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR); |
2786 | #endif | 2998 | #endif |
2787 | } else if (soc_is_exynos4210()) { | 2999 | } else if (soc_is_exynos4210()) { |
2788 | #ifdef CONFIG_CPU_EXYNOS4210 | 3000 | exynos4_gpiolib_init(); |
2789 | void __iomem *gpx_base; | ||
2790 | |||
2791 | /* gpio part1 */ | ||
2792 | gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K); | ||
2793 | if (gpio_base1 == NULL) { | ||
2794 | pr_err("unable to ioremap for gpio_base1\n"); | ||
2795 | goto err_ioremap1; | ||
2796 | } | ||
2797 | |||
2798 | chip = exynos4_gpios_1; | ||
2799 | nr_chips = ARRAY_SIZE(exynos4_gpios_1); | ||
2800 | |||
2801 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2802 | if (!chip->config) { | ||
2803 | chip->config = &exynos_gpio_cfg; | ||
2804 | chip->group = group++; | ||
2805 | } | ||
2806 | exynos_gpiolib_attach_ofnode(chip, | ||
2807 | EXYNOS4_PA_GPIO1, i * 0x20); | ||
2808 | } | ||
2809 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, | ||
2810 | nr_chips, gpio_base1); | ||
2811 | |||
2812 | /* gpio part2 */ | ||
2813 | gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K); | ||
2814 | if (gpio_base2 == NULL) { | ||
2815 | pr_err("unable to ioremap for gpio_base2\n"); | ||
2816 | goto err_ioremap2; | ||
2817 | } | ||
2818 | |||
2819 | /* need to set base address for gpx */ | ||
2820 | chip = &exynos4_gpios_2[16]; | ||
2821 | gpx_base = gpio_base2 + 0xC00; | ||
2822 | for (i = 0; i < 4; i++, chip++, gpx_base += 0x20) | ||
2823 | chip->base = gpx_base; | ||
2824 | |||
2825 | chip = exynos4_gpios_2; | ||
2826 | nr_chips = ARRAY_SIZE(exynos4_gpios_2); | ||
2827 | |||
2828 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2829 | if (!chip->config) { | ||
2830 | chip->config = &exynos_gpio_cfg; | ||
2831 | chip->group = group++; | ||
2832 | } | ||
2833 | exynos_gpiolib_attach_ofnode(chip, | ||
2834 | EXYNOS4_PA_GPIO2, i * 0x20); | ||
2835 | } | ||
2836 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, | ||
2837 | nr_chips, gpio_base2); | ||
2838 | |||
2839 | /* gpio part3 */ | ||
2840 | gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256); | ||
2841 | if (gpio_base3 == NULL) { | ||
2842 | pr_err("unable to ioremap for gpio_base3\n"); | ||
2843 | goto err_ioremap3; | ||
2844 | } | ||
2845 | |||
2846 | chip = exynos4_gpios_3; | ||
2847 | nr_chips = ARRAY_SIZE(exynos4_gpios_3); | ||
2848 | |||
2849 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2850 | if (!chip->config) { | ||
2851 | chip->config = &exynos_gpio_cfg; | ||
2852 | chip->group = group++; | ||
2853 | } | ||
2854 | exynos_gpiolib_attach_ofnode(chip, | ||
2855 | EXYNOS4_PA_GPIO3, i * 0x20); | ||
2856 | } | ||
2857 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, | ||
2858 | nr_chips, gpio_base3); | ||
2859 | |||
2860 | #if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT) | ||
2861 | s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS); | ||
2862 | s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS); | ||
2863 | #endif | ||
2864 | |||
2865 | #endif /* CONFIG_CPU_EXYNOS4210 */ | ||
2866 | } else if (soc_is_exynos5250()) { | 3001 | } else if (soc_is_exynos5250()) { |
2867 | #ifdef CONFIG_SOC_EXYNOS5250 | 3002 | exynos5_gpiolib_init(); |
2868 | void __iomem *gpx_base; | ||
2869 | |||
2870 | /* gpio part1 */ | ||
2871 | gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K); | ||
2872 | if (gpio_base1 == NULL) { | ||
2873 | pr_err("unable to ioremap for gpio_base1\n"); | ||
2874 | goto err_ioremap1; | ||
2875 | } | ||
2876 | |||
2877 | /* need to set base address for gpx */ | ||
2878 | chip = &exynos5_gpios_1[20]; | ||
2879 | gpx_base = gpio_base1 + 0xC00; | ||
2880 | for (i = 0; i < 4; i++, chip++, gpx_base += 0x20) | ||
2881 | chip->base = gpx_base; | ||
2882 | |||
2883 | chip = exynos5_gpios_1; | ||
2884 | nr_chips = ARRAY_SIZE(exynos5_gpios_1); | ||
2885 | |||
2886 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2887 | if (!chip->config) { | ||
2888 | chip->config = &exynos_gpio_cfg; | ||
2889 | chip->group = group++; | ||
2890 | } | ||
2891 | exynos_gpiolib_attach_ofnode(chip, | ||
2892 | EXYNOS5_PA_GPIO1, i * 0x20); | ||
2893 | } | ||
2894 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_1, | ||
2895 | nr_chips, gpio_base1); | ||
2896 | |||
2897 | /* gpio part2 */ | ||
2898 | gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K); | ||
2899 | if (gpio_base2 == NULL) { | ||
2900 | pr_err("unable to ioremap for gpio_base2\n"); | ||
2901 | goto err_ioremap2; | ||
2902 | } | ||
2903 | |||
2904 | chip = exynos5_gpios_2; | ||
2905 | nr_chips = ARRAY_SIZE(exynos5_gpios_2); | ||
2906 | |||
2907 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2908 | if (!chip->config) { | ||
2909 | chip->config = &exynos_gpio_cfg; | ||
2910 | chip->group = group++; | ||
2911 | } | ||
2912 | exynos_gpiolib_attach_ofnode(chip, | ||
2913 | EXYNOS5_PA_GPIO2, i * 0x20); | ||
2914 | } | ||
2915 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_2, | ||
2916 | nr_chips, gpio_base2); | ||
2917 | |||
2918 | /* gpio part3 */ | ||
2919 | gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K); | ||
2920 | if (gpio_base3 == NULL) { | ||
2921 | pr_err("unable to ioremap for gpio_base3\n"); | ||
2922 | goto err_ioremap3; | ||
2923 | } | ||
2924 | |||
2925 | /* need to set base address for gpv */ | ||
2926 | exynos5_gpios_3[0].base = gpio_base3; | ||
2927 | exynos5_gpios_3[1].base = gpio_base3 + 0x20; | ||
2928 | exynos5_gpios_3[2].base = gpio_base3 + 0x60; | ||
2929 | exynos5_gpios_3[3].base = gpio_base3 + 0x80; | ||
2930 | exynos5_gpios_3[4].base = gpio_base3 + 0xC0; | ||
2931 | |||
2932 | chip = exynos5_gpios_3; | ||
2933 | nr_chips = ARRAY_SIZE(exynos5_gpios_3); | ||
2934 | |||
2935 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2936 | if (!chip->config) { | ||
2937 | chip->config = &exynos_gpio_cfg; | ||
2938 | chip->group = group++; | ||
2939 | } | ||
2940 | exynos_gpiolib_attach_ofnode(chip, | ||
2941 | EXYNOS5_PA_GPIO3, i * 0x20); | ||
2942 | } | ||
2943 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_3, | ||
2944 | nr_chips, gpio_base3); | ||
2945 | |||
2946 | /* gpio part4 */ | ||
2947 | gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K); | ||
2948 | if (gpio_base4 == NULL) { | ||
2949 | pr_err("unable to ioremap for gpio_base4\n"); | ||
2950 | goto err_ioremap4; | ||
2951 | } | ||
2952 | |||
2953 | chip = exynos5_gpios_4; | ||
2954 | nr_chips = ARRAY_SIZE(exynos5_gpios_4); | ||
2955 | |||
2956 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2957 | if (!chip->config) { | ||
2958 | chip->config = &exynos_gpio_cfg; | ||
2959 | chip->group = group++; | ||
2960 | } | ||
2961 | exynos_gpiolib_attach_ofnode(chip, | ||
2962 | EXYNOS5_PA_GPIO4, i * 0x20); | ||
2963 | } | ||
2964 | samsung_gpiolib_add_4bit_chips(exynos5_gpios_4, | ||
2965 | nr_chips, gpio_base4); | ||
2966 | #endif /* CONFIG_SOC_EXYNOS5250 */ | ||
2967 | } else { | 3003 | } else { |
2968 | WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n"); | 3004 | WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n"); |
2969 | return -ENODEV; | 3005 | return -ENODEV; |
2970 | } | 3006 | } |
2971 | 3007 | ||
2972 | return 0; | 3008 | return 0; |
2973 | |||
2974 | err_ioremap4: | ||
2975 | iounmap(gpio_base3); | ||
2976 | err_ioremap3: | ||
2977 | iounmap(gpio_base2); | ||
2978 | err_ioremap2: | ||
2979 | iounmap(gpio_base1); | ||
2980 | err_ioremap1: | ||
2981 | return -ENOMEM; | ||
2982 | } | 3009 | } |
2983 | core_initcall(samsung_gpiolib_init); | 3010 | core_initcall(samsung_gpiolib_init); |
2984 | 3011 | ||