Commit 915fdc94 authored by Linus Walleij's avatar Linus Walleij
Browse files

Merge tag 'samsung-pinctrl-6.8' of...

Merge tag 'samsung-pinctrl-6.8' of https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung

 into devel

Samsung pinctrl drivers changes for v6.8

1. New hardware: Add pin controllers for Samsung ExynosAutov920 and
   Google Tensor GS101.

2. Few DT bindings cleanups: add specific compatibles for each device
   using generic compatible as fallback.  This affects only DTS, no
   driver changes are needed.

3. Allow setting affinity on non wake-up external GPIO interrupts.

Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parents 84e769e6 6cf96df7
Loading
Loading
Loading
Loading
+30 −15
Original line number Diff line number Diff line
@@ -28,15 +28,27 @@ description: |

properties:
  compatible:
    enum:
    oneOf:
      - enum:
          - samsung,s3c2410-wakeup-eint
          - samsung,s3c2412-wakeup-eint
          - samsung,s3c64xx-wakeup-eint
          - samsung,s5pv210-wakeup-eint
          - samsung,exynos4210-wakeup-eint
          - samsung,exynos7-wakeup-eint
          - samsung,exynosautov920-wakeup-eint
      - items:
          - enum:
              - samsung,exynos5433-wakeup-eint
              - samsung,exynos7885-wakeup-eint
              - samsung,exynos850-wakeup-eint
          - const: samsung,exynos7-wakeup-eint
      - items:
          - enum:
              - google,gs101-wakeup-eint
              - samsung,exynosautov9-wakeup-eint
          - const: samsung,exynos850-wakeup-eint
          - const: samsung,exynos7-wakeup-eint

  interrupts:
    description:
@@ -79,11 +91,14 @@ allOf:
  - if:
      properties:
        compatible:
          contains:
          # Match without "contains", to skip newer variants which are still
          # compatible with samsung,exynos7-wakeup-eint
          enum:
            - samsung,s5pv210-wakeup-eint
            - samsung,exynos4210-wakeup-eint
            - samsung,exynos5433-wakeup-eint
            - samsung,exynos7-wakeup-eint
            - samsung,exynos7885-wakeup-eint
    then:
      properties:
        interrupts:
@@ -98,7 +113,7 @@ allOf:
          contains:
            enum:
              - samsung,exynos850-wakeup-eint
              - samsung,exynosautov9-wakeup-eint
              - samsung,exynosautov920-wakeup-eint
    then:
      properties:
        interrupts: false
+4 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ properties:

  compatible:
    enum:
      - google,gs101-pinctrl
      - samsung,s3c2412-pinctrl
      - samsung,s3c2416-pinctrl
      - samsung,s3c2440-pinctrl
@@ -53,6 +54,7 @@ properties:
      - samsung,exynos7885-pinctrl
      - samsung,exynos850-pinctrl
      - samsung,exynosautov9-pinctrl
      - samsung,exynosautov920-pinctrl
      - tesla,fsd-pinctrl

  interrupts:
@@ -313,7 +315,8 @@ examples:
        pinctrl-0 = <&initial_alive>;

        wakeup-interrupt-controller {
            compatible = "samsung,exynos7-wakeup-eint";
            compatible = "samsung,exynos5433-wakeup-eint",
                         "samsung,exynos7-wakeup-eint";
            interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
        };

+0 −1
Original line number Diff line number Diff line
@@ -19227,7 +19227,6 @@ R: Alim Akhtar <alim.akhtar@samsung.com>
L:	linux-samsung-soc@vger.kernel.org
S:	Maintained
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
F:	Documentation/devicetree/bindings/clock/samsung,*.yaml
F:	Documentation/devicetree/bindings/clock/samsung,s3c*
F:	drivers/clk/samsung/
+280 −0
Original line number Diff line number Diff line
@@ -726,6 +726,146 @@ const struct samsung_pinctrl_of_match_data exynosautov9_of_data __initconst = {
	.num_ctrl	= ARRAY_SIZE(exynosautov9_pin_ctrl),
};

/* pin banks of exynosautov920 pin-controller 0 (ALIVE) */
static const struct samsung_pin_bank_data exynosautov920_pin_banks0[] = {
	EXYNOSV920_PIN_BANK_EINTW(8, 0x0000, "gpa0", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTW(2, 0x1000, "gpa1", 0x18, 0x20, 0x24),
	EXYNOS850_PIN_BANK_EINTN(2, 0x2000, "gpq0"),
};

/* pin banks of exynosautov920 pin-controller 1 (AUD) */
static const struct samsung_pin_bank_data exynosautov920_pin_banks1[] = {
	EXYNOSV920_PIN_BANK_EINTG(7, 0x0000, "gpb0", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(6, 0x1000, "gpb1", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(8, 0x2000, "gpb2", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(8, 0x3000, "gpb3", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(8, 0x4000, "gpb4", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(5, 0x5000, "gpb5", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(5, 0x6000, "gpb6", 0x18, 0x24, 0x28),
};

/* pin banks of exynosautov920 pin-controller 2 (HSI0) */
static const struct samsung_pin_bank_data exynosautov920_pin_banks2[] = {
	EXYNOSV920_PIN_BANK_EINTG(6, 0x0000, "gph0", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(2, 0x1000, "gph1", 0x18, 0x20, 0x24),
};

/* pin banks of exynosautov920 pin-controller 3 (HSI1) */
static const struct samsung_pin_bank_data exynosautov920_pin_banks3[] = {
	EXYNOSV920_PIN_BANK_EINTG(7, 0x000, "gph8", 0x18, 0x24, 0x28),
};

/* pin banks of exynosautov920 pin-controller 4 (HSI2) */
static const struct samsung_pin_bank_data exynosautov920_pin_banks4[] = {
	EXYNOSV920_PIN_BANK_EINTG(8, 0x0000, "gph3", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(7, 0x1000, "gph4", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(8, 0x2000, "gph5", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(7, 0x3000, "gph6", 0x18, 0x24, 0x28),
};

/* pin banks of exynosautov920 pin-controller 5 (HSI2UFS) */
static const struct samsung_pin_bank_data exynosautov920_pin_banks5[] = {
	EXYNOSV920_PIN_BANK_EINTG(4, 0x000, "gph2", 0x18, 0x20, 0x24),
};

/* pin banks of exynosautov920 pin-controller 6 (PERIC0) */
static const struct samsung_pin_bank_data exynosautov920_pin_banks6[] = {
	EXYNOSV920_PIN_BANK_EINTG(8, 0x0000, "gpp0", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(8, 0x1000, "gpp1", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(8, 0x2000, "gpp2", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(5, 0x3000, "gpg0", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(8, 0x4000, "gpp3", 0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(4, 0x5000, "gpp4", 0x18, 0x20, 0x24),
	EXYNOSV920_PIN_BANK_EINTG(4, 0x6000, "gpg2", 0x18, 0x20, 0x24),
	EXYNOSV920_PIN_BANK_EINTG(4, 0x7000, "gpg5", 0x18, 0x20, 0x24),
	EXYNOSV920_PIN_BANK_EINTG(3, 0x8000, "gpg3", 0x18, 0x20, 0x24),
	EXYNOSV920_PIN_BANK_EINTG(5, 0x9000, "gpg4", 0x18, 0x24, 0x28),
};

/* pin banks of exynosautov920 pin-controller 7 (PERIC1) */
static const struct samsung_pin_bank_data exynosautov920_pin_banks7[] = {
	EXYNOSV920_PIN_BANK_EINTG(8, 0x0000, "gpp5",  0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(5, 0x1000, "gpp6",  0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(4, 0x2000, "gpp10", 0x18, 0x20, 0x24),
	EXYNOSV920_PIN_BANK_EINTG(8, 0x3000, "gpp7",  0x18, 0x24, 0x28),
	EXYNOSV920_PIN_BANK_EINTG(4, 0x4000, "gpp8",  0x18, 0x20, 0x24),
	EXYNOSV920_PIN_BANK_EINTG(4, 0x5000, "gpp11", 0x18, 0x20, 0x24),
	EXYNOSV920_PIN_BANK_EINTG(4, 0x6000, "gpp9",  0x18, 0x20, 0x24),
	EXYNOSV920_PIN_BANK_EINTG(4, 0x7000, "gpp12", 0x18, 0x20, 0x24),
	EXYNOSV920_PIN_BANK_EINTG(8, 0x8000, "gpg1",  0x18, 0x24, 0x28),
};

static const struct samsung_retention_data exynosautov920_retention_data __initconst = {
	.regs	 = NULL,
	.nr_regs = 0,
	.value	 = 0,
	.refcnt	 = &exynos_shared_retention_refcnt,
	.init	 = exynos_retention_init,
};

static const struct samsung_pin_ctrl exynosautov920_pin_ctrl[] = {
	{
		/* pin-controller instance 0 ALIVE data */
		.pin_banks	= exynosautov920_pin_banks0,
		.nr_banks	= ARRAY_SIZE(exynosautov920_pin_banks0),
		.eint_wkup_init	= exynos_eint_wkup_init,
		.suspend	= exynos_pinctrl_suspend,
		.resume		= exynos_pinctrl_resume,
		.retention_data	= &exynosautov920_retention_data,
	}, {
		/* pin-controller instance 1 AUD data */
		.pin_banks	= exynosautov920_pin_banks1,
		.nr_banks	= ARRAY_SIZE(exynosautov920_pin_banks1),
	}, {
		/* pin-controller instance 2 HSI0 data */
		.pin_banks	= exynosautov920_pin_banks2,
		.nr_banks	= ARRAY_SIZE(exynosautov920_pin_banks2),
		.eint_gpio_init	= exynos_eint_gpio_init,
		.suspend	= exynos_pinctrl_suspend,
		.resume		= exynos_pinctrl_resume,
	}, {
		/* pin-controller instance 3 HSI1 data */
		.pin_banks	= exynosautov920_pin_banks3,
		.nr_banks	= ARRAY_SIZE(exynosautov920_pin_banks3),
		.eint_gpio_init	= exynos_eint_gpio_init,
		.suspend	= exynos_pinctrl_suspend,
		.resume		= exynos_pinctrl_resume,
	}, {
		/* pin-controller instance 4 HSI2 data */
		.pin_banks	= exynosautov920_pin_banks4,
		.nr_banks	= ARRAY_SIZE(exynosautov920_pin_banks4),
		.eint_gpio_init	= exynos_eint_gpio_init,
		.suspend	= exynos_pinctrl_suspend,
		.resume		= exynos_pinctrl_resume,
	}, {
		/* pin-controller instance 5 HSI2UFS data */
		.pin_banks	= exynosautov920_pin_banks5,
		.nr_banks	= ARRAY_SIZE(exynosautov920_pin_banks5),
		.eint_gpio_init	= exynos_eint_gpio_init,
		.suspend	= exynos_pinctrl_suspend,
		.resume		= exynos_pinctrl_resume,
	}, {
		/* pin-controller instance 6 PERIC0 data */
		.pin_banks	= exynosautov920_pin_banks6,
		.nr_banks	= ARRAY_SIZE(exynosautov920_pin_banks6),
		.eint_gpio_init	= exynos_eint_gpio_init,
		.suspend	= exynos_pinctrl_suspend,
		.resume		= exynos_pinctrl_resume,
	}, {
		/* pin-controller instance 7 PERIC1 data */
		.pin_banks	= exynosautov920_pin_banks7,
		.nr_banks	= ARRAY_SIZE(exynosautov920_pin_banks7),
		.eint_gpio_init	= exynos_eint_gpio_init,
		.suspend	= exynos_pinctrl_suspend,
		.resume		= exynos_pinctrl_resume,
	},
};

const struct samsung_pinctrl_of_match_data exynosautov920_of_data __initconst = {
	.ctrl		= exynosautov920_pin_ctrl,
	.num_ctrl	= ARRAY_SIZE(exynosautov920_pin_ctrl),
};

/*
 * Pinctrl driver data for Tesla FSD SoC. FSD SoC includes three
 * gpio/pin-mux/pinconfig controllers.
@@ -796,3 +936,143 @@ const struct samsung_pinctrl_of_match_data fsd_of_data __initconst = {
	.ctrl		= fsd_pin_ctrl,
	.num_ctrl	= ARRAY_SIZE(fsd_pin_ctrl),
};

/* pin banks of gs101 pin-controller (ALIVE) */
static const struct samsung_pin_bank_data gs101_pin_alive[] = {
	EXYNOS850_PIN_BANK_EINTW(8, 0x0, "gpa0", 0x00),
	EXYNOS850_PIN_BANK_EINTW(7, 0x20, "gpa1", 0x04),
	EXYNOS850_PIN_BANK_EINTW(5, 0x40, "gpa2", 0x08),
	EXYNOS850_PIN_BANK_EINTW(4, 0x60, "gpa3", 0x0c),
	EXYNOS850_PIN_BANK_EINTW(4, 0x80, "gpa4", 0x10),
	EXYNOS850_PIN_BANK_EINTW(7, 0xa0, "gpa5", 0x14),
	EXYNOS850_PIN_BANK_EINTW(8, 0xc0, "gpa9", 0x18),
	EXYNOS850_PIN_BANK_EINTW(2, 0xe0, "gpa10", 0x1c),
};

/* pin banks of gs101 pin-controller (FAR_ALIVE) */
static const struct samsung_pin_bank_data gs101_pin_far_alive[] = {
	EXYNOS850_PIN_BANK_EINTW(8, 0x0, "gpa6", 0x00),
	EXYNOS850_PIN_BANK_EINTW(4, 0x20, "gpa7", 0x04),
	EXYNOS850_PIN_BANK_EINTW(8, 0x40, "gpa8", 0x08),
	EXYNOS850_PIN_BANK_EINTW(2, 0x60, "gpa11", 0x0c),
};

/* pin banks of gs101 pin-controller (GSACORE) */
static const struct samsung_pin_bank_data gs101_pin_gsacore[] = {
	EXYNOS850_PIN_BANK_EINTG(2, 0x0, "gps0", 0x00),
	EXYNOS850_PIN_BANK_EINTG(8, 0x20, "gps1", 0x04),
	EXYNOS850_PIN_BANK_EINTG(3, 0x40, "gps2", 0x08),
};

/* pin banks of gs101 pin-controller (GSACTRL) */
static const struct samsung_pin_bank_data gs101_pin_gsactrl[] = {
	EXYNOS850_PIN_BANK_EINTW(6, 0x0, "gps3", 0x00),
};

/* pin banks of gs101 pin-controller (PERIC0) */
static const struct samsung_pin_bank_data gs101_pin_peric0[] = {
	EXYNOS850_PIN_BANK_EINTG(5, 0x0, "gpp0", 0x00),
	EXYNOS850_PIN_BANK_EINTG(4, 0x20, "gpp1", 0x04),
	EXYNOS850_PIN_BANK_EINTG(4, 0x40, "gpp2", 0x08),
	EXYNOS850_PIN_BANK_EINTG(2, 0x60, "gpp3", 0x0c),
	EXYNOS850_PIN_BANK_EINTG(4, 0x80, "gpp4", 0x10),
	EXYNOS850_PIN_BANK_EINTG(2, 0xa0, "gpp5", 0x14),
	EXYNOS850_PIN_BANK_EINTG(4, 0xc0, "gpp6", 0x18),
	EXYNOS850_PIN_BANK_EINTG(2, 0xe0, "gpp7", 0x1c),
	EXYNOS850_PIN_BANK_EINTG(4, 0x100, "gpp8", 0x20),
	EXYNOS850_PIN_BANK_EINTG(2, 0x120, "gpp9", 0x24),
	EXYNOS850_PIN_BANK_EINTG(4, 0x140, "gpp10", 0x28),
	EXYNOS850_PIN_BANK_EINTG(2, 0x160, "gpp11", 0x2c),
	EXYNOS850_PIN_BANK_EINTG(4, 0x180, "gpp12", 0x30),
	EXYNOS850_PIN_BANK_EINTG(2, 0x1a0, "gpp13", 0x34),
	EXYNOS850_PIN_BANK_EINTG(4, 0x1c0, "gpp14", 0x38),
	EXYNOS850_PIN_BANK_EINTG(2, 0x1e0, "gpp15", 0x3c),
	EXYNOS850_PIN_BANK_EINTG(4, 0x200, "gpp16", 0x40),
	EXYNOS850_PIN_BANK_EINTG(2, 0x220, "gpp17", 0x44),
	EXYNOS850_PIN_BANK_EINTG(4, 0x240, "gpp18", 0x48),
	EXYNOS850_PIN_BANK_EINTG(4, 0x260, "gpp19", 0x4c),
};

/* pin banks of gs101 pin-controller (PERIC1) */
static const struct samsung_pin_bank_data gs101_pin_peric1[] = {
	EXYNOS850_PIN_BANK_EINTG(8, 0x0, "gpp20", 0x00),
	EXYNOS850_PIN_BANK_EINTG(4, 0x20, "gpp21", 0x04),
	EXYNOS850_PIN_BANK_EINTG(2, 0x40, "gpp22", 0x08),
	EXYNOS850_PIN_BANK_EINTG(8, 0x60, "gpp23", 0x0c),
	EXYNOS850_PIN_BANK_EINTG(4, 0x80, "gpp24", 0x10),
	EXYNOS850_PIN_BANK_EINTG(4, 0xa0, "gpp25", 0x14),
	EXYNOS850_PIN_BANK_EINTG(5, 0xc0, "gpp26", 0x18),
	EXYNOS850_PIN_BANK_EINTG(4, 0xe0, "gpp27", 0x1c),
};

/* pin banks of gs101 pin-controller (HSI1) */
static const struct samsung_pin_bank_data gs101_pin_hsi1[] = {
	EXYNOS850_PIN_BANK_EINTG(6, 0x0, "gph0", 0x00),
	EXYNOS850_PIN_BANK_EINTG(7, 0x20, "gph1", 0x04),
};

/* pin banks of gs101 pin-controller (HSI2) */
static const struct samsung_pin_bank_data gs101_pin_hsi2[] = {
	EXYNOS850_PIN_BANK_EINTG(6, 0x0, "gph2", 0x00),
	EXYNOS850_PIN_BANK_EINTG(2, 0x20, "gph3", 0x04),
	EXYNOS850_PIN_BANK_EINTG(6, 0x40, "gph4", 0x08),
};

static const struct samsung_pin_ctrl gs101_pin_ctrl[] __initconst = {
	{
		/* pin banks of gs101 pin-controller (ALIVE) */
		.pin_banks	= gs101_pin_alive,
		.nr_banks	= ARRAY_SIZE(gs101_pin_alive),
		.eint_wkup_init = exynos_eint_wkup_init,
		.suspend	= exynos_pinctrl_suspend,
		.resume		= exynos_pinctrl_resume,
	}, {
		/* pin banks of gs101 pin-controller (FAR_ALIVE) */
		.pin_banks	= gs101_pin_far_alive,
		.nr_banks	= ARRAY_SIZE(gs101_pin_far_alive),
		.eint_wkup_init = exynos_eint_wkup_init,
		.suspend	= exynos_pinctrl_suspend,
		.resume		= exynos_pinctrl_resume,
	}, {
		/* pin banks of gs101 pin-controller (GSACORE) */
		.pin_banks	= gs101_pin_gsacore,
		.nr_banks	= ARRAY_SIZE(gs101_pin_gsacore),
	}, {
		/* pin banks of gs101 pin-controller (GSACTRL) */
		.pin_banks	= gs101_pin_gsactrl,
		.nr_banks	= ARRAY_SIZE(gs101_pin_gsactrl),
	}, {
		/* pin banks of gs101 pin-controller (PERIC0) */
		.pin_banks	= gs101_pin_peric0,
		.nr_banks	= ARRAY_SIZE(gs101_pin_peric0),
		.eint_gpio_init = exynos_eint_gpio_init,
		.suspend	= exynos_pinctrl_suspend,
		.resume		= exynos_pinctrl_resume,
	}, {
		/* pin banks of gs101 pin-controller (PERIC1) */
		.pin_banks	= gs101_pin_peric1,
		.nr_banks	= ARRAY_SIZE(gs101_pin_peric1),
		.eint_gpio_init = exynos_eint_gpio_init,
		.suspend	= exynos_pinctrl_suspend,
		.resume	= exynos_pinctrl_resume,
	}, {
		/* pin banks of gs101 pin-controller (HSI1) */
		.pin_banks	= gs101_pin_hsi1,
		.nr_banks	= ARRAY_SIZE(gs101_pin_hsi1),
		.eint_gpio_init = exynos_eint_gpio_init,
		.suspend	= exynos_pinctrl_suspend,
		.resume		= exynos_pinctrl_resume,
	}, {
		/* pin banks of gs101 pin-controller (HSI2) */
		.pin_banks	= gs101_pin_hsi2,
		.nr_banks	= ARRAY_SIZE(gs101_pin_hsi2),
		.eint_gpio_init = exynos_eint_gpio_init,
		.suspend	= exynos_pinctrl_suspend,
		.resume		= exynos_pinctrl_resume,
	},
};

const struct samsung_pinctrl_of_match_data gs101_of_data __initconst = {
	.ctrl		= gs101_pin_ctrl,
	.num_ctrl	= ARRAY_SIZE(gs101_pin_ctrl),
};
+100 −9
Original line number Diff line number Diff line
@@ -52,10 +52,15 @@ static void exynos_irq_mask(struct irq_data *irqd)
	struct irq_chip *chip = irq_data_get_irq_chip(irqd);
	struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
	unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
	unsigned long reg_mask;
	unsigned int mask;
	unsigned long flags;

	if (bank->eint_mask_offset)
		reg_mask = bank->pctl_offset + bank->eint_mask_offset;
	else
		reg_mask = our_chip->eint_mask + bank->eint_offset;

	raw_spin_lock_irqsave(&bank->slock, flags);

	mask = readl(bank->eint_base + reg_mask);
@@ -70,7 +75,12 @@ static void exynos_irq_ack(struct irq_data *irqd)
	struct irq_chip *chip = irq_data_get_irq_chip(irqd);
	struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
	unsigned long reg_pend = our_chip->eint_pend + bank->eint_offset;
	unsigned long reg_pend;

	if (bank->eint_pend_offset)
		reg_pend = bank->pctl_offset + bank->eint_pend_offset;
	else
		reg_pend = our_chip->eint_pend + bank->eint_offset;

	writel(1 << irqd->hwirq, bank->eint_base + reg_pend);
}
@@ -80,7 +90,7 @@ static void exynos_irq_unmask(struct irq_data *irqd)
	struct irq_chip *chip = irq_data_get_irq_chip(irqd);
	struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
	unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
	unsigned long reg_mask;
	unsigned int mask;
	unsigned long flags;

@@ -95,6 +105,11 @@ static void exynos_irq_unmask(struct irq_data *irqd)
	if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
		exynos_irq_ack(irqd);

	if (bank->eint_mask_offset)
		reg_mask = bank->pctl_offset + bank->eint_mask_offset;
	else
		reg_mask = our_chip->eint_mask + bank->eint_offset;

	raw_spin_lock_irqsave(&bank->slock, flags);

	mask = readl(bank->eint_base + reg_mask);
@@ -111,7 +126,7 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
	unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq;
	unsigned int con, trig_type;
	unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
	unsigned long reg_con;

	switch (type) {
	case IRQ_TYPE_EDGE_RISING:
@@ -139,6 +154,11 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
	else
		irq_set_handler_locked(irqd, handle_level_irq);

	if (bank->eint_con_offset)
		reg_con = bank->pctl_offset + bank->eint_con_offset;
	else
		reg_con = our_chip->eint_con + bank->eint_offset;

	con = readl(bank->eint_base + reg_con);
	con &= ~(EXYNOS_EINT_CON_MASK << shift);
	con |= trig_type << shift;
@@ -147,6 +167,19 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
	return 0;
}

static int exynos_irq_set_affinity(struct irq_data *irqd,
				   const struct cpumask *dest, bool force)
{
	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
	struct samsung_pinctrl_drv_data *d = bank->drvdata;
	struct irq_data *parent = irq_get_irq_data(d->irq);

	if (parent)
		return parent->chip->irq_set_affinity(parent, dest, force);

	return -EINVAL;
}

static int exynos_irq_request_resources(struct irq_data *irqd)
{
	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
@@ -212,6 +245,7 @@ static const struct exynos_irq_chip exynos_gpio_irq_chip __initconst = {
		.irq_mask = exynos_irq_mask,
		.irq_ack = exynos_irq_ack,
		.irq_set_type = exynos_irq_set_type,
		.irq_set_affinity = exynos_irq_set_affinity,
		.irq_request_resources = exynos_irq_request_resources,
		.irq_release_resources = exynos_irq_release_resources,
	},
@@ -247,6 +281,9 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
	unsigned int svc, group, pin;
	int ret;

	if (bank->eint_con_offset)
		svc = readl(bank->eint_base + EXYNOSAUTO_SVC_OFFSET);
	else
		svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET);
	group = EXYNOS_SVC_GROUP(svc);
	pin = svc & EXYNOS_SVC_NUM_MASK;
@@ -456,6 +493,22 @@ static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = {
	.set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask,
};

static const struct exynos_irq_chip exynosautov920_wkup_irq_chip __initconst = {
	.chip = {
		.name = "exynosautov920_wkup_irq_chip",
		.irq_unmask = exynos_irq_unmask,
		.irq_mask = exynos_irq_mask,
		.irq_ack = exynos_irq_ack,
		.irq_set_type = exynos_irq_set_type,
		.irq_set_wake = exynos_wkup_irq_set_wake,
		.irq_request_resources = exynos_irq_request_resources,
		.irq_release_resources = exynos_irq_release_resources,
	},
	.eint_wake_mask_value = &eint_wake_mask_value,
	.eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK,
	.set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask,
};

/* list of external wakeup controllers supported */
static const struct of_device_id exynos_wkup_irq_ids[] = {
	{ .compatible = "samsung,s5pv210-wakeup-eint",
@@ -468,6 +521,8 @@ static const struct of_device_id exynos_wkup_irq_ids[] = {
			.data = &exynos7_wkup_irq_chip },
	{ .compatible = "samsung,exynosautov9-wakeup-eint",
			.data = &exynos7_wkup_irq_chip },
	{ .compatible = "samsung,exynosautov920-wakeup-eint",
			.data = &exynosautov920_wkup_irq_chip },
	{ }
};

@@ -655,6 +710,19 @@ static void exynos_pinctrl_suspend_bank(
	pr_debug("%s: save    mask %#010x\n", bank->name, save->eint_mask);
}

static void exynosauto_pinctrl_suspend_bank(struct samsung_pinctrl_drv_data *drvdata,
					    struct samsung_pin_bank *bank)
{
	struct exynos_eint_gpio_save *save = bank->soc_priv;
	void __iomem *regs = bank->eint_base;

	save->eint_con = readl(regs + bank->pctl_offset + bank->eint_con_offset);
	save->eint_mask = readl(regs + bank->pctl_offset + bank->eint_mask_offset);

	pr_debug("%s: save     con %#010x\n", bank->name, save->eint_con);
	pr_debug("%s: save    mask %#010x\n", bank->name, save->eint_mask);
}

void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
{
	struct samsung_pin_bank *bank = drvdata->pin_banks;
@@ -662,8 +730,12 @@ void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
	int i;

	for (i = 0; i < drvdata->nr_banks; ++i, ++bank) {
		if (bank->eint_type == EINT_TYPE_GPIO)
		if (bank->eint_type == EINT_TYPE_GPIO) {
			if (bank->eint_con_offset)
				exynosauto_pinctrl_suspend_bank(drvdata, bank);
			else
				exynos_pinctrl_suspend_bank(drvdata, bank);
		}
		else if (bank->eint_type == EINT_TYPE_WKUP) {
			if (!irq_chip) {
				irq_chip = bank->irq_chip;
@@ -704,15 +776,34 @@ static void exynos_pinctrl_resume_bank(
						+ bank->eint_offset);
}

static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvdata,
					   struct samsung_pin_bank *bank)
{
	struct exynos_eint_gpio_save *save = bank->soc_priv;
	void __iomem *regs = bank->eint_base;

	pr_debug("%s:     con %#010x => %#010x\n", bank->name,
		 readl(regs + bank->pctl_offset + bank->eint_con_offset), save->eint_con);
	pr_debug("%s:    mask %#010x => %#010x\n", bank->name,
		 readl(regs + bank->pctl_offset + bank->eint_mask_offset), save->eint_mask);

	writel(save->eint_con, regs + bank->pctl_offset + bank->eint_con_offset);
	writel(save->eint_mask, regs + bank->pctl_offset + bank->eint_mask_offset);
}

void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
{
	struct samsung_pin_bank *bank = drvdata->pin_banks;
	int i;

	for (i = 0; i < drvdata->nr_banks; ++i, ++bank)
		if (bank->eint_type == EINT_TYPE_GPIO)
		if (bank->eint_type == EINT_TYPE_GPIO) {
			if (bank->eint_con_offset)
				exynosauto_pinctrl_resume_bank(drvdata, bank);
			else
				exynos_pinctrl_resume_bank(drvdata, bank);
		}
}

static void exynos_retention_enable(struct samsung_pinctrl_drv_data *drvdata)
{
Loading