Merge branches 'backport/ltsi-3.4.25/lager-3' and 'backport/ltsi-3.4.25/pfc-7' into backport/ltsi-3.4.25/h2-base-8
diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c
index c8a64b1..9fd0574 100644
--- a/arch/arm/mach-shmobile/board-lager.c
+++ b/arch/arm/mach-shmobile/board-lager.c
@@ -18,16 +18,59 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/irqchip.h>
 #include <linux/kernel.h>
+#include <linux/leds.h>
 #include <linux/pinctrl/machine.h>
+#include <linux/platform_data/gpio-rcar.h>
 #include <linux/platform_device.h>
 #include <mach/common.h>
 #include <mach/r8a7790.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+/* LEDS */
+static struct gpio_led lager_leds[] = {
+	{
+		.name		= "led8",
+		.gpio		= RCAR_GP_PIN(5, 17),
+		.default_state	= LEDS_GPIO_DEFSTATE_ON,
+	}, {
+		.name		= "led7",
+		.gpio		= RCAR_GP_PIN(4, 23),
+		.default_state	= LEDS_GPIO_DEFSTATE_ON,
+	}, {
+		.name		= "led6",
+		.gpio		= RCAR_GP_PIN(4, 22),
+		.default_state	= LEDS_GPIO_DEFSTATE_ON,
+	},
+};
+
+static __initdata struct gpio_led_platform_data lager_leds_pdata = {
+	.leds		= lager_leds,
+	.num_leds	= ARRAY_SIZE(lager_leds),
+};
+
+/* GPIO KEY */
+#define GPIO_KEY(c, g, d, ...) \
+	{ .code = c, .gpio = g, .desc = d, .active_low = 1 }
+
+static __initdata struct gpio_keys_button gpio_buttons[] = {
+	GPIO_KEY(KEY_4,		RCAR_GP_PIN(1, 28),	"SW2-pin4"),
+	GPIO_KEY(KEY_3,		RCAR_GP_PIN(1, 26),	"SW2-pin3"),
+	GPIO_KEY(KEY_2,		RCAR_GP_PIN(1, 24),	"SW2-pin2"),
+	GPIO_KEY(KEY_1,		RCAR_GP_PIN(1, 14),	"SW2-pin1"),
+};
+
+static __initdata struct gpio_keys_platform_data lager_keys_pdata = {
+	.buttons	= gpio_buttons,
+	.nbuttons	= ARRAY_SIZE(gpio_buttons),
+};
+
 static const struct pinctrl_map lager_pinctrl_map[] = {
 	/* SCIF0 (CN19: DEBUG SERIAL0) */
 	PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.6", "pfc-r8a7790",
@@ -46,6 +89,12 @@
 	r8a7790_pinmux_init();
 
 	r8a7790_add_standard_devices();
+	platform_device_register_data(&platform_bus, "leds-gpio", -1,
+				      &lager_leds_pdata,
+				      sizeof(lager_leds_pdata));
+	platform_device_register_data(&platform_bus, "gpio-keys", -1,
+				      &lager_keys_pdata,
+				      sizeof(lager_keys_pdata));
 }
 
 static const char *lager_boards_compat_dt[] __initdata = {
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index b4ca450..ac6604a3 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -49,6 +49,7 @@
 #define POSNEG 0x20
 #define EDGLEVEL 0x24
 #define FILONOFF 0x28
+#define BOTHEDGE 0x4c
 
 static inline u32 gpio_rcar_read(struct gpio_rcar_priv *p, int offs)
 {
@@ -91,7 +92,8 @@
 static void gpio_rcar_config_interrupt_input_mode(struct gpio_rcar_priv *p,
 						  unsigned int hwirq,
 						  bool active_high_rising_edge,
-						  bool level_trigger)
+						  bool level_trigger,
+						  bool both)
 {
 	unsigned long flags;
 
@@ -108,6 +110,10 @@
 	/* Configure edge or level trigger in EDGLEVEL */
 	gpio_rcar_modify_bit(p, EDGLEVEL, hwirq, !level_trigger);
 
+	/* Select one edge or both edges in BOTHEDGE */
+	if (p->config.has_both_edge_trigger)
+		gpio_rcar_modify_bit(p, BOTHEDGE, hwirq, both);
+
 	/* Select "Interrupt Input Mode" in IOINTSEL */
 	gpio_rcar_modify_bit(p, IOINTSEL, hwirq, true);
 
@@ -127,16 +133,26 @@
 
 	switch (type & IRQ_TYPE_SENSE_MASK) {
 	case IRQ_TYPE_LEVEL_HIGH:
-		gpio_rcar_config_interrupt_input_mode(p, hwirq, true, true);
+		gpio_rcar_config_interrupt_input_mode(p, hwirq, true, true,
+						      false);
 		break;
 	case IRQ_TYPE_LEVEL_LOW:
-		gpio_rcar_config_interrupt_input_mode(p, hwirq, false, true);
+		gpio_rcar_config_interrupt_input_mode(p, hwirq, false, true,
+						      false);
 		break;
 	case IRQ_TYPE_EDGE_RISING:
-		gpio_rcar_config_interrupt_input_mode(p, hwirq, true, false);
+		gpio_rcar_config_interrupt_input_mode(p, hwirq, true, false,
+						      false);
 		break;
 	case IRQ_TYPE_EDGE_FALLING:
-		gpio_rcar_config_interrupt_input_mode(p, hwirq, false, false);
+		gpio_rcar_config_interrupt_input_mode(p, hwirq, false, false,
+						      false);
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		if (!p->config.has_both_edge_trigger)
+			return -EINVAL;
+		gpio_rcar_config_interrupt_input_mode(p, hwirq, true, false,
+						      true);
 		break;
 	default:
 		return -EINVAL;
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
index 1656915..aed9630 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
@@ -294,7 +294,7 @@
 	FN_GLO_SS_C, FN_PWM1, FN_SCIFA2_TXD_C,
 	FN_STP_ISSYNC_1_B, FN_TS_SCK1_C, FN_GLO_RFON_C,
 	FN_PCMOE_N, FN_PWM2, FN_PWMFSW0, FN_SCIFA2_RXD_C,
-	FN_PCMWE_N, FN_IECLK_C, FN_DU1_DOTCLKIN,
+	FN_PCMWE_N, FN_IECLK_C, FN_DU_DOTCLKIN1,
 	FN_AUDIO_CLKC, FN_AUDIO_CLKOUT_C, FN_VI0_CLK,
 	FN_ATACS00_N, FN_AVB_RXD1, FN_MII_RXD1,
 	FN_VI0_DATA0_VI0_B0, FN_ATACS10_N, FN_AVB_RXD2,
@@ -668,7 +668,7 @@
 	GLO_SS_C_MARK, PWM1_MARK, SCIFA2_TXD_C_MARK,
 	STP_ISSYNC_1_B_MARK, TS_SCK1_C_MARK, GLO_RFON_C_MARK,
 	PCMOE_N_MARK, PWM2_MARK, PWMFSW0_MARK, SCIFA2_RXD_C_MARK,
-	PCMWE_N_MARK, IECLK_C_MARK, DU1_DOTCLKIN_MARK,
+	PCMWE_N_MARK, IECLK_C_MARK, DU_DOTCLKIN1_MARK,
 	AUDIO_CLKC_MARK, AUDIO_CLKOUT_C_MARK, VI0_CLK_MARK,
 	ATACS00_N_MARK, AVB_RXD1_MARK, MII_RXD1_MARK,
 	VI0_DATA0_VI0_B0_MARK, ATACS10_N_MARK, AVB_RXD2_MARK,
@@ -1288,7 +1288,7 @@
 	PINMUX_IPSR_MODSEL_DATA(IP7_24_22, SCIFA2_RXD_C, SEL_SCIFA2_2),
 	PINMUX_IPSR_DATA(IP7_24_22, PCMWE_N),
 	PINMUX_IPSR_MODSEL_DATA(IP7_24_22, IECLK_C, SEL_IEB_2),
-	PINMUX_IPSR_DATA(IP7_26_25, DU1_DOTCLKIN),
+	PINMUX_IPSR_DATA(IP7_26_25, DU_DOTCLKIN1),
 	PINMUX_IPSR_DATA(IP7_26_25, AUDIO_CLKC),
 	PINMUX_IPSR_DATA(IP7_26_25, AUDIO_CLKOUT_C),
 	PINMUX_IPSR_MODSEL_DATA(IP7_28_27, VI0_CLK, SEL_VI0_0),
@@ -1825,6 +1825,104 @@
 	PINMUX_GPIO_GP_ALL(),
 };
 
+/* - DU RGB ----------------------------------------------------------------- */
+static const unsigned int du_rgb666_pins[] = {
+	/* R[7:2], G[7:2], B[7:2] */
+	RCAR_GP_PIN(4, 21), RCAR_GP_PIN(4, 20), RCAR_GP_PIN(4, 19),
+	RCAR_GP_PIN(4, 18), RCAR_GP_PIN(4, 17), RCAR_GP_PIN(4, 16),
+	RCAR_GP_PIN(5, 4),  RCAR_GP_PIN(5, 15), RCAR_GP_PIN(5, 14),
+	RCAR_GP_PIN(5, 7),  RCAR_GP_PIN(4, 30), RCAR_GP_PIN(4, 27),
+	RCAR_GP_PIN(5, 13), RCAR_GP_PIN(5, 12), RCAR_GP_PIN(5, 11),
+	RCAR_GP_PIN(5, 10), RCAR_GP_PIN(5, 9),  RCAR_GP_PIN(5, 8),
+};
+static const unsigned int du_rgb666_mux[] = {
+	DU2_DR7_MARK, DU2_DR6_MARK, DU2_DR5_MARK, DU2_DR4_MARK,
+	DU2_DR3_MARK, DU2_DR2_MARK,
+	DU2_DG7_MARK, DU2_DG6_MARK, DU2_DG5_MARK, DU2_DG4_MARK,
+	DU2_DG3_MARK, DU2_DG2_MARK,
+	DU2_DB7_MARK, DU2_DB6_MARK, DU2_DB5_MARK, DU2_DB4_MARK,
+	DU2_DB3_MARK, DU2_DB2_MARK,
+};
+static const unsigned int du_rgb888_pins[] = {
+	/* R[7:0], G[7:0], B[7:0] */
+	RCAR_GP_PIN(4, 21), RCAR_GP_PIN(4, 20), RCAR_GP_PIN(4, 19),
+	RCAR_GP_PIN(4, 18), RCAR_GP_PIN(4, 17), RCAR_GP_PIN(4, 16),
+	RCAR_GP_PIN(4, 29), RCAR_GP_PIN(4, 28), RCAR_GP_PIN(5, 4),
+	RCAR_GP_PIN(5, 15), RCAR_GP_PIN(5, 14), RCAR_GP_PIN(5, 7),
+	RCAR_GP_PIN(4, 30), RCAR_GP_PIN(4, 27), RCAR_GP_PIN(5, 1),
+	RCAR_GP_PIN(4, 31), RCAR_GP_PIN(5, 13), RCAR_GP_PIN(5, 12),
+	RCAR_GP_PIN(5, 11), RCAR_GP_PIN(5, 10), RCAR_GP_PIN(5, 9),
+	RCAR_GP_PIN(5, 8),  RCAR_GP_PIN(5, 6),  RCAR_GP_PIN(5, 5),
+};
+static const unsigned int du_rgb888_mux[] = {
+	DU2_DR7_MARK, DU2_DR6_MARK, DU2_DR5_MARK, DU2_DR4_MARK,
+	DU2_DR3_MARK, DU2_DR2_MARK, DU2_DR1_MARK, DU2_DR0_MARK,
+	DU2_DG7_MARK, DU2_DG6_MARK, DU2_DG5_MARK, DU2_DG4_MARK,
+	DU2_DG3_MARK, DU2_DG2_MARK, DU2_DG1_MARK, DU2_DG0_MARK,
+	DU2_DB7_MARK, DU2_DB6_MARK, DU2_DB5_MARK, DU2_DB4_MARK,
+	DU2_DB3_MARK, DU2_DB2_MARK, DU2_DB1_MARK, DU2_DB0_MARK,
+};
+static const unsigned int du_clk_out_0_pins[] = {
+	/* CLKOUT */
+	RCAR_GP_PIN(5, 2),
+};
+static const unsigned int du_clk_out_0_mux[] = {
+	DU0_DOTCLKOUT_MARK
+};
+static const unsigned int du_clk_out_1_pins[] = {
+	/* CLKOUT */
+	RCAR_GP_PIN(5, 3),
+};
+static const unsigned int du_clk_out_1_mux[] = {
+	DU1_DOTCLKOUT_MARK
+};
+static const unsigned int du_sync_0_pins[] = {
+	/* VSYNC, HSYNC, DISP */
+	RCAR_GP_PIN(4, 15), RCAR_GP_PIN(4, 14), RCAR_GP_PIN(5, 0),
+};
+static const unsigned int du_sync_0_mux[] = {
+	DU2_EXVSYNC_DU2_VSYNC_MARK, DU2_EXHSYNC_DU2_HSYNC_MARK,
+	DU2_EXODDF_DU2_ODDF_DISP_CDE_MARK
+};
+static const unsigned int du_sync_1_pins[] = {
+	/* VSYNC, HSYNC, DISP */
+	RCAR_GP_PIN(4, 15), RCAR_GP_PIN(4, 14), RCAR_GP_PIN(5, 16),
+};
+static const unsigned int du_sync_1_mux[] = {
+	DU2_EXVSYNC_DU2_VSYNC_MARK, DU2_EXHSYNC_DU2_HSYNC_MARK,
+	DU2_DISP_MARK
+};
+static const unsigned int du_cde_pins[] = {
+	/* CDE */
+	RCAR_GP_PIN(5, 17),
+};
+static const unsigned int du_cde_mux[] = {
+	DU2_CDE_MARK,
+};
+/* - DU0 -------------------------------------------------------------------- */
+static const unsigned int du0_clk_in_pins[] = {
+	/* CLKIN */
+	RCAR_GP_PIN(5, 26),
+};
+static const unsigned int du0_clk_in_mux[] = {
+	DU_DOTCLKIN0_MARK
+};
+/* - DU1 -------------------------------------------------------------------- */
+static const unsigned int du1_clk_in_pins[] = {
+	/* CLKIN */
+	RCAR_GP_PIN(5, 27),
+};
+static const unsigned int du1_clk_in_mux[] = {
+	DU_DOTCLKIN1_MARK,
+};
+/* - DU2 -------------------------------------------------------------------- */
+static const unsigned int du2_clk_in_pins[] = {
+	/* CLKIN */
+	RCAR_GP_PIN(5, 28),
+};
+static const unsigned int du2_clk_in_mux[] = {
+	DU_DOTCLKIN2_MARK,
+};
 /* - ETH -------------------------------------------------------------------- */
 static const unsigned int eth_link_pins[] = {
 	/* LINK */
@@ -2344,6 +2442,16 @@
 };
 
 static const struct sh_pfc_pin_group pinmux_groups[] = {
+	SH_PFC_PIN_GROUP(du_rgb666),
+	SH_PFC_PIN_GROUP(du_rgb888),
+	SH_PFC_PIN_GROUP(du_clk_out_0),
+	SH_PFC_PIN_GROUP(du_clk_out_1),
+	SH_PFC_PIN_GROUP(du_sync_0),
+	SH_PFC_PIN_GROUP(du_sync_1),
+	SH_PFC_PIN_GROUP(du_cde),
+	SH_PFC_PIN_GROUP(du0_clk_in),
+	SH_PFC_PIN_GROUP(du1_clk_in),
+	SH_PFC_PIN_GROUP(du2_clk_in),
 	SH_PFC_PIN_GROUP(eth_link),
 	SH_PFC_PIN_GROUP(eth_magic),
 	SH_PFC_PIN_GROUP(eth_mdio),
@@ -2418,6 +2526,28 @@
 	SH_PFC_PIN_GROUP(scifb2_data_c),
 };
 
+static const char * const du_groups[] = {
+	"du_rgb666",
+	"du_rgb888",
+	"du_clk_out_0",
+	"du_clk_out_1",
+	"du_sync_0",
+	"du_sync_1",
+	"du_cde",
+};
+
+static const char * const du0_groups[] = {
+	"du0_clk_in",
+};
+
+static const char * const du1_groups[] = {
+	"du1_clk_in",
+};
+
+static const char * const du2_groups[] = {
+	"du2_clk_in",
+};
+
 static const char * const eth_groups[] = {
 	"eth_link",
 	"eth_magic",
@@ -2521,6 +2651,10 @@
 };
 
 static const struct sh_pfc_function pinmux_functions[] = {
+	SH_PFC_FUNCTION(du),
+	SH_PFC_FUNCTION(du0),
+	SH_PFC_FUNCTION(du1),
+	SH_PFC_FUNCTION(du2),
 	SH_PFC_FUNCTION(eth),
 	SH_PFC_FUNCTION(intc),
 	SH_PFC_FUNCTION(scif0),
@@ -2990,7 +3124,7 @@
 		/* IP7_28_27 [2] */
 		FN_VI0_CLK, FN_ATACS00_N, FN_AVB_RXD1, FN_MII_RXD1,
 		/* IP7_26_25 [2] */
-		FN_DU1_DOTCLKIN, FN_AUDIO_CLKC, FN_AUDIO_CLKOUT_C, 0,
+		FN_DU_DOTCLKIN1, FN_AUDIO_CLKC, FN_AUDIO_CLKOUT_C, 0,
 		/* IP7_24_22 [3] */
 		FN_PWM2, FN_PWMFSW0, FN_SCIFA2_RXD_C, FN_PCMWE_N, FN_IECLK_C,
 		0, 0, 0,
diff --git a/include/linux/platform_data/gpio-rcar.h b/include/linux/platform_data/gpio-rcar.h
index cc472f6..2d8d694 100644
--- a/include/linux/platform_data/gpio-rcar.h
+++ b/include/linux/platform_data/gpio-rcar.h
@@ -17,10 +17,11 @@
 #define __GPIO_RCAR_H__
 
 struct gpio_rcar_config {
-	unsigned int gpio_base;
+	int gpio_base;
 	unsigned int irq_base;
 	unsigned int number_of_pins;
 	const char *pctl_name;
+	unsigned has_both_edge_trigger:1;
 };
 
 #define RCAR_GP_PIN(bank, pin)		(((bank) * 32) + (pin))