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