|
@@ -2714,12 +2714,224 @@ static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
|
|
|
}
|
|
|
#endif /* defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) */
|
|
|
|
|
|
+static __init void exynos4_gpiolib_init(void)
|
|
|
+{
|
|
|
+#ifdef CONFIG_CPU_EXYNOS4210
|
|
|
+ struct samsung_gpio_chip *chip;
|
|
|
+ int i, nr_chips;
|
|
|
+ void __iomem *gpio_base1, *gpio_base2, *gpio_base3;
|
|
|
+ int group = 0;
|
|
|
+ void __iomem *gpx_base;
|
|
|
+
|
|
|
+ /* gpio part1 */
|
|
|
+ gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K);
|
|
|
+ if (gpio_base1 == NULL) {
|
|
|
+ pr_err("unable to ioremap for gpio_base1\n");
|
|
|
+ goto err_ioremap1;
|
|
|
+ }
|
|
|
+
|
|
|
+ chip = exynos4_gpios_1;
|
|
|
+ nr_chips = ARRAY_SIZE(exynos4_gpios_1);
|
|
|
+
|
|
|
+ for (i = 0; i < nr_chips; i++, chip++) {
|
|
|
+ if (!chip->config) {
|
|
|
+ chip->config = &exynos_gpio_cfg;
|
|
|
+ chip->group = group++;
|
|
|
+ }
|
|
|
+ exynos_gpiolib_attach_ofnode(chip,
|
|
|
+ EXYNOS4_PA_GPIO1, i * 0x20);
|
|
|
+ }
|
|
|
+ samsung_gpiolib_add_4bit_chips(exynos4_gpios_1,
|
|
|
+ nr_chips, gpio_base1);
|
|
|
+
|
|
|
+ /* gpio part2 */
|
|
|
+ gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K);
|
|
|
+ if (gpio_base2 == NULL) {
|
|
|
+ pr_err("unable to ioremap for gpio_base2\n");
|
|
|
+ goto err_ioremap2;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* need to set base address for gpx */
|
|
|
+ chip = &exynos4_gpios_2[16];
|
|
|
+ gpx_base = gpio_base2 + 0xC00;
|
|
|
+ for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
|
|
|
+ chip->base = gpx_base;
|
|
|
+
|
|
|
+ chip = exynos4_gpios_2;
|
|
|
+ nr_chips = ARRAY_SIZE(exynos4_gpios_2);
|
|
|
+
|
|
|
+ for (i = 0; i < nr_chips; i++, chip++) {
|
|
|
+ if (!chip->config) {
|
|
|
+ chip->config = &exynos_gpio_cfg;
|
|
|
+ chip->group = group++;
|
|
|
+ }
|
|
|
+ exynos_gpiolib_attach_ofnode(chip,
|
|
|
+ EXYNOS4_PA_GPIO2, i * 0x20);
|
|
|
+ }
|
|
|
+ samsung_gpiolib_add_4bit_chips(exynos4_gpios_2,
|
|
|
+ nr_chips, gpio_base2);
|
|
|
+
|
|
|
+ /* gpio part3 */
|
|
|
+ gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256);
|
|
|
+ if (gpio_base3 == NULL) {
|
|
|
+ pr_err("unable to ioremap for gpio_base3\n");
|
|
|
+ goto err_ioremap3;
|
|
|
+ }
|
|
|
+
|
|
|
+ chip = exynos4_gpios_3;
|
|
|
+ nr_chips = ARRAY_SIZE(exynos4_gpios_3);
|
|
|
+
|
|
|
+ for (i = 0; i < nr_chips; i++, chip++) {
|
|
|
+ if (!chip->config) {
|
|
|
+ chip->config = &exynos_gpio_cfg;
|
|
|
+ chip->group = group++;
|
|
|
+ }
|
|
|
+ exynos_gpiolib_attach_ofnode(chip,
|
|
|
+ EXYNOS4_PA_GPIO3, i * 0x20);
|
|
|
+ }
|
|
|
+ samsung_gpiolib_add_4bit_chips(exynos4_gpios_3,
|
|
|
+ nr_chips, gpio_base3);
|
|
|
+
|
|
|
+#if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT)
|
|
|
+ s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
|
|
|
+ s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
|
|
|
+#endif
|
|
|
+
|
|
|
+ return;
|
|
|
+
|
|
|
+err_ioremap3:
|
|
|
+ iounmap(gpio_base2);
|
|
|
+err_ioremap2:
|
|
|
+ iounmap(gpio_base1);
|
|
|
+err_ioremap1:
|
|
|
+ return;
|
|
|
+#endif /* CONFIG_CPU_EXYNOS4210 */
|
|
|
+}
|
|
|
+
|
|
|
+static __init void exynos5_gpiolib_init(void)
|
|
|
+{
|
|
|
+#ifdef CONFIG_SOC_EXYNOS5250
|
|
|
+ struct samsung_gpio_chip *chip;
|
|
|
+ int i, nr_chips;
|
|
|
+ void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4;
|
|
|
+ int group = 0;
|
|
|
+ void __iomem *gpx_base;
|
|
|
+
|
|
|
+ /* gpio part1 */
|
|
|
+ gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
|
|
|
+ if (gpio_base1 == NULL) {
|
|
|
+ pr_err("unable to ioremap for gpio_base1\n");
|
|
|
+ goto err_ioremap1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* need to set base address for gpx */
|
|
|
+ chip = &exynos5_gpios_1[20];
|
|
|
+ gpx_base = gpio_base1 + 0xC00;
|
|
|
+ for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
|
|
|
+ chip->base = gpx_base;
|
|
|
+
|
|
|
+ chip = exynos5_gpios_1;
|
|
|
+ nr_chips = ARRAY_SIZE(exynos5_gpios_1);
|
|
|
+
|
|
|
+ for (i = 0; i < nr_chips; i++, chip++) {
|
|
|
+ if (!chip->config) {
|
|
|
+ chip->config = &exynos_gpio_cfg;
|
|
|
+ chip->group = group++;
|
|
|
+ }
|
|
|
+ exynos_gpiolib_attach_ofnode(chip,
|
|
|
+ EXYNOS5_PA_GPIO1, i * 0x20);
|
|
|
+ }
|
|
|
+ samsung_gpiolib_add_4bit_chips(exynos5_gpios_1,
|
|
|
+ nr_chips, gpio_base1);
|
|
|
+
|
|
|
+ /* gpio part2 */
|
|
|
+ gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K);
|
|
|
+ if (gpio_base2 == NULL) {
|
|
|
+ pr_err("unable to ioremap for gpio_base2\n");
|
|
|
+ goto err_ioremap2;
|
|
|
+ }
|
|
|
+
|
|
|
+ chip = exynos5_gpios_2;
|
|
|
+ nr_chips = ARRAY_SIZE(exynos5_gpios_2);
|
|
|
+
|
|
|
+ for (i = 0; i < nr_chips; i++, chip++) {
|
|
|
+ if (!chip->config) {
|
|
|
+ chip->config = &exynos_gpio_cfg;
|
|
|
+ chip->group = group++;
|
|
|
+ }
|
|
|
+ exynos_gpiolib_attach_ofnode(chip,
|
|
|
+ EXYNOS5_PA_GPIO2, i * 0x20);
|
|
|
+ }
|
|
|
+ samsung_gpiolib_add_4bit_chips(exynos5_gpios_2,
|
|
|
+ nr_chips, gpio_base2);
|
|
|
+
|
|
|
+ /* gpio part3 */
|
|
|
+ gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K);
|
|
|
+ if (gpio_base3 == NULL) {
|
|
|
+ pr_err("unable to ioremap for gpio_base3\n");
|
|
|
+ goto err_ioremap3;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* need to set base address for gpv */
|
|
|
+ exynos5_gpios_3[0].base = gpio_base3;
|
|
|
+ exynos5_gpios_3[1].base = gpio_base3 + 0x20;
|
|
|
+ exynos5_gpios_3[2].base = gpio_base3 + 0x60;
|
|
|
+ exynos5_gpios_3[3].base = gpio_base3 + 0x80;
|
|
|
+ exynos5_gpios_3[4].base = gpio_base3 + 0xC0;
|
|
|
+
|
|
|
+ chip = exynos5_gpios_3;
|
|
|
+ nr_chips = ARRAY_SIZE(exynos5_gpios_3);
|
|
|
+
|
|
|
+ for (i = 0; i < nr_chips; i++, chip++) {
|
|
|
+ if (!chip->config) {
|
|
|
+ chip->config = &exynos_gpio_cfg;
|
|
|
+ chip->group = group++;
|
|
|
+ }
|
|
|
+ exynos_gpiolib_attach_ofnode(chip,
|
|
|
+ EXYNOS5_PA_GPIO3, i * 0x20);
|
|
|
+ }
|
|
|
+ samsung_gpiolib_add_4bit_chips(exynos5_gpios_3,
|
|
|
+ nr_chips, gpio_base3);
|
|
|
+
|
|
|
+ /* gpio part4 */
|
|
|
+ gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K);
|
|
|
+ if (gpio_base4 == NULL) {
|
|
|
+ pr_err("unable to ioremap for gpio_base4\n");
|
|
|
+ goto err_ioremap4;
|
|
|
+ }
|
|
|
+
|
|
|
+ chip = exynos5_gpios_4;
|
|
|
+ nr_chips = ARRAY_SIZE(exynos5_gpios_4);
|
|
|
+
|
|
|
+ for (i = 0; i < nr_chips; i++, chip++) {
|
|
|
+ if (!chip->config) {
|
|
|
+ chip->config = &exynos_gpio_cfg;
|
|
|
+ chip->group = group++;
|
|
|
+ }
|
|
|
+ exynos_gpiolib_attach_ofnode(chip,
|
|
|
+ EXYNOS5_PA_GPIO4, i * 0x20);
|
|
|
+ }
|
|
|
+ samsung_gpiolib_add_4bit_chips(exynos5_gpios_4,
|
|
|
+ nr_chips, gpio_base4);
|
|
|
+ return;
|
|
|
+
|
|
|
+err_ioremap4:
|
|
|
+ iounmap(gpio_base3);
|
|
|
+err_ioremap3:
|
|
|
+ iounmap(gpio_base2);
|
|
|
+err_ioremap2:
|
|
|
+ iounmap(gpio_base1);
|
|
|
+err_ioremap1:
|
|
|
+ return;
|
|
|
+
|
|
|
+#endif /* CONFIG_SOC_EXYNOS5250 */
|
|
|
+}
|
|
|
+
|
|
|
/* TODO: cleanup soc_is_* */
|
|
|
static __init int samsung_gpiolib_init(void)
|
|
|
{
|
|
|
struct samsung_gpio_chip *chip;
|
|
|
int i, nr_chips;
|
|
|
- void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4;
|
|
|
int group = 0;
|
|
|
|
|
|
samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
|
|
@@ -2785,200 +2997,15 @@ static __init int samsung_gpiolib_init(void)
|
|
|
s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
|
|
|
#endif
|
|
|
} else if (soc_is_exynos4210()) {
|
|
|
-#ifdef CONFIG_CPU_EXYNOS4210
|
|
|
- void __iomem *gpx_base;
|
|
|
-
|
|
|
- /* gpio part1 */
|
|
|
- gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K);
|
|
|
- if (gpio_base1 == NULL) {
|
|
|
- pr_err("unable to ioremap for gpio_base1\n");
|
|
|
- goto err_ioremap1;
|
|
|
- }
|
|
|
-
|
|
|
- chip = exynos4_gpios_1;
|
|
|
- nr_chips = ARRAY_SIZE(exynos4_gpios_1);
|
|
|
-
|
|
|
- for (i = 0; i < nr_chips; i++, chip++) {
|
|
|
- if (!chip->config) {
|
|
|
- chip->config = &exynos_gpio_cfg;
|
|
|
- chip->group = group++;
|
|
|
- }
|
|
|
- exynos_gpiolib_attach_ofnode(chip,
|
|
|
- EXYNOS4_PA_GPIO1, i * 0x20);
|
|
|
- }
|
|
|
- samsung_gpiolib_add_4bit_chips(exynos4_gpios_1,
|
|
|
- nr_chips, gpio_base1);
|
|
|
-
|
|
|
- /* gpio part2 */
|
|
|
- gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K);
|
|
|
- if (gpio_base2 == NULL) {
|
|
|
- pr_err("unable to ioremap for gpio_base2\n");
|
|
|
- goto err_ioremap2;
|
|
|
- }
|
|
|
-
|
|
|
- /* need to set base address for gpx */
|
|
|
- chip = &exynos4_gpios_2[16];
|
|
|
- gpx_base = gpio_base2 + 0xC00;
|
|
|
- for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
|
|
|
- chip->base = gpx_base;
|
|
|
-
|
|
|
- chip = exynos4_gpios_2;
|
|
|
- nr_chips = ARRAY_SIZE(exynos4_gpios_2);
|
|
|
-
|
|
|
- for (i = 0; i < nr_chips; i++, chip++) {
|
|
|
- if (!chip->config) {
|
|
|
- chip->config = &exynos_gpio_cfg;
|
|
|
- chip->group = group++;
|
|
|
- }
|
|
|
- exynos_gpiolib_attach_ofnode(chip,
|
|
|
- EXYNOS4_PA_GPIO2, i * 0x20);
|
|
|
- }
|
|
|
- samsung_gpiolib_add_4bit_chips(exynos4_gpios_2,
|
|
|
- nr_chips, gpio_base2);
|
|
|
-
|
|
|
- /* gpio part3 */
|
|
|
- gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256);
|
|
|
- if (gpio_base3 == NULL) {
|
|
|
- pr_err("unable to ioremap for gpio_base3\n");
|
|
|
- goto err_ioremap3;
|
|
|
- }
|
|
|
-
|
|
|
- chip = exynos4_gpios_3;
|
|
|
- nr_chips = ARRAY_SIZE(exynos4_gpios_3);
|
|
|
-
|
|
|
- for (i = 0; i < nr_chips; i++, chip++) {
|
|
|
- if (!chip->config) {
|
|
|
- chip->config = &exynos_gpio_cfg;
|
|
|
- chip->group = group++;
|
|
|
- }
|
|
|
- exynos_gpiolib_attach_ofnode(chip,
|
|
|
- EXYNOS4_PA_GPIO3, i * 0x20);
|
|
|
- }
|
|
|
- samsung_gpiolib_add_4bit_chips(exynos4_gpios_3,
|
|
|
- nr_chips, gpio_base3);
|
|
|
-
|
|
|
-#if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT)
|
|
|
- s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
|
|
|
- s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
|
|
|
-#endif
|
|
|
-
|
|
|
-#endif /* CONFIG_CPU_EXYNOS4210 */
|
|
|
+ exynos4_gpiolib_init();
|
|
|
} else if (soc_is_exynos5250()) {
|
|
|
-#ifdef CONFIG_SOC_EXYNOS5250
|
|
|
- void __iomem *gpx_base;
|
|
|
-
|
|
|
- /* gpio part1 */
|
|
|
- gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
|
|
|
- if (gpio_base1 == NULL) {
|
|
|
- pr_err("unable to ioremap for gpio_base1\n");
|
|
|
- goto err_ioremap1;
|
|
|
- }
|
|
|
-
|
|
|
- /* need to set base address for gpx */
|
|
|
- chip = &exynos5_gpios_1[20];
|
|
|
- gpx_base = gpio_base1 + 0xC00;
|
|
|
- for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
|
|
|
- chip->base = gpx_base;
|
|
|
-
|
|
|
- chip = exynos5_gpios_1;
|
|
|
- nr_chips = ARRAY_SIZE(exynos5_gpios_1);
|
|
|
-
|
|
|
- for (i = 0; i < nr_chips; i++, chip++) {
|
|
|
- if (!chip->config) {
|
|
|
- chip->config = &exynos_gpio_cfg;
|
|
|
- chip->group = group++;
|
|
|
- }
|
|
|
- exynos_gpiolib_attach_ofnode(chip,
|
|
|
- EXYNOS5_PA_GPIO1, i * 0x20);
|
|
|
- }
|
|
|
- samsung_gpiolib_add_4bit_chips(exynos5_gpios_1,
|
|
|
- nr_chips, gpio_base1);
|
|
|
-
|
|
|
- /* gpio part2 */
|
|
|
- gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K);
|
|
|
- if (gpio_base2 == NULL) {
|
|
|
- pr_err("unable to ioremap for gpio_base2\n");
|
|
|
- goto err_ioremap2;
|
|
|
- }
|
|
|
-
|
|
|
- chip = exynos5_gpios_2;
|
|
|
- nr_chips = ARRAY_SIZE(exynos5_gpios_2);
|
|
|
-
|
|
|
- for (i = 0; i < nr_chips; i++, chip++) {
|
|
|
- if (!chip->config) {
|
|
|
- chip->config = &exynos_gpio_cfg;
|
|
|
- chip->group = group++;
|
|
|
- }
|
|
|
- exynos_gpiolib_attach_ofnode(chip,
|
|
|
- EXYNOS5_PA_GPIO2, i * 0x20);
|
|
|
- }
|
|
|
- samsung_gpiolib_add_4bit_chips(exynos5_gpios_2,
|
|
|
- nr_chips, gpio_base2);
|
|
|
-
|
|
|
- /* gpio part3 */
|
|
|
- gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K);
|
|
|
- if (gpio_base3 == NULL) {
|
|
|
- pr_err("unable to ioremap for gpio_base3\n");
|
|
|
- goto err_ioremap3;
|
|
|
- }
|
|
|
-
|
|
|
- /* need to set base address for gpv */
|
|
|
- exynos5_gpios_3[0].base = gpio_base3;
|
|
|
- exynos5_gpios_3[1].base = gpio_base3 + 0x20;
|
|
|
- exynos5_gpios_3[2].base = gpio_base3 + 0x60;
|
|
|
- exynos5_gpios_3[3].base = gpio_base3 + 0x80;
|
|
|
- exynos5_gpios_3[4].base = gpio_base3 + 0xC0;
|
|
|
-
|
|
|
- chip = exynos5_gpios_3;
|
|
|
- nr_chips = ARRAY_SIZE(exynos5_gpios_3);
|
|
|
-
|
|
|
- for (i = 0; i < nr_chips; i++, chip++) {
|
|
|
- if (!chip->config) {
|
|
|
- chip->config = &exynos_gpio_cfg;
|
|
|
- chip->group = group++;
|
|
|
- }
|
|
|
- exynos_gpiolib_attach_ofnode(chip,
|
|
|
- EXYNOS5_PA_GPIO3, i * 0x20);
|
|
|
- }
|
|
|
- samsung_gpiolib_add_4bit_chips(exynos5_gpios_3,
|
|
|
- nr_chips, gpio_base3);
|
|
|
-
|
|
|
- /* gpio part4 */
|
|
|
- gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K);
|
|
|
- if (gpio_base4 == NULL) {
|
|
|
- pr_err("unable to ioremap for gpio_base4\n");
|
|
|
- goto err_ioremap4;
|
|
|
- }
|
|
|
-
|
|
|
- chip = exynos5_gpios_4;
|
|
|
- nr_chips = ARRAY_SIZE(exynos5_gpios_4);
|
|
|
-
|
|
|
- for (i = 0; i < nr_chips; i++, chip++) {
|
|
|
- if (!chip->config) {
|
|
|
- chip->config = &exynos_gpio_cfg;
|
|
|
- chip->group = group++;
|
|
|
- }
|
|
|
- exynos_gpiolib_attach_ofnode(chip,
|
|
|
- EXYNOS5_PA_GPIO4, i * 0x20);
|
|
|
- }
|
|
|
- samsung_gpiolib_add_4bit_chips(exynos5_gpios_4,
|
|
|
- nr_chips, gpio_base4);
|
|
|
-#endif /* CONFIG_SOC_EXYNOS5250 */
|
|
|
+ exynos5_gpiolib_init();
|
|
|
} else {
|
|
|
WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
-
|
|
|
-err_ioremap4:
|
|
|
- iounmap(gpio_base3);
|
|
|
-err_ioremap3:
|
|
|
- iounmap(gpio_base2);
|
|
|
-err_ioremap2:
|
|
|
- iounmap(gpio_base1);
|
|
|
-err_ioremap1:
|
|
|
- return -ENOMEM;
|
|
|
}
|
|
|
core_initcall(samsung_gpiolib_init);
|
|
|
|