diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index eec0c0bda7668f13c2ead9b05fd104463dc1e21b..4e3a1dca8959f35aa1045ae484ea53b455725961 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -60,6 +60,7 @@ struct machine_desc {
 	void			(*handle_irq)(struct pt_regs *);
 #endif
 	void			(*restart)(enum reboot_mode, const char *);
+	void            (*pwroff)(void);
 };
 
 /*
diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h
index 66f6a3ae68d273ba0f08e827b15f27c093cf8867..d1e450e00fd296bf4ac37cdb016b85b5ae1641f1 100644
--- a/arch/arm/include/asm/system_misc.h
+++ b/arch/arm/include/asm/system_misc.h
@@ -15,6 +15,8 @@ extern void cpu_init(void);
 void soft_restart(unsigned long);
 extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
 extern void (*arm_pm_idle)(void);
+extern void (*arm_pm_poweroff)(void);
+
 
 #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
 typedef void (*harden_branch_predictor_fn_t)(void);
diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
index 0ce388f15422646023f64f7e888db942f1ddb5b0..241b9c4d6cabd444c43ef6be3941f51d089b2930 100644
--- a/arch/arm/kernel/reboot.c
+++ b/arch/arm/kernel/reboot.c
@@ -19,6 +19,7 @@ typedef void (*phys_reset_t)(unsigned long, bool);
  * Function pointers to optional machine specific functions
  */
 void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
+void (*arm_pm_poweroff)(void);
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
@@ -104,6 +105,10 @@ void machine_halt(void)
 {
 	local_irq_disable();
 	smp_send_stop();
+
+	if ( arm_pm_poweroff )
+		arm_pm_poweroff ();
+
 	while (1);
 }
 
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index b06602cea99c786bc478bdd6b23e835efa9885b2..c031ce3f9ff89d5e88fc2c72bc5e4ee3369697e8 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1152,6 +1152,9 @@ void __init setup_arch(char **cmdline_p)
 	if (mdesc->restart)
 		arm_pm_restart = mdesc->restart;
 
+	if (mdesc->pwroff)
+		arm_pm_poweroff = mdesc->pwroff;
+
 	unflatten_device_tree();
 
 	arm_dt_init_cpu_maps();
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 5bdb65dcd67fb221a4a39584994fb444b195c73a..0506ce51f550a7c35c94ce13bd8c16da26c9a6a7 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -7,12 +7,14 @@
 #include <linux/clk.h>
 #include <linux/irqchip.h>
 #include <linux/of_platform.h>
+#include <linux/gpio.h>
 #include <linux/pci.h>
 #include <linux/phy.h>
 #include <linux/regmap.h>
 #include <linux/micrel_phy.h>
 #include <linux/mfd/syscon.h>
 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/of_gpio.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
@@ -20,6 +22,10 @@
 #include "cpuidle.h"
 #include "hardware.h"
 
+static int power_gpio = -1;
+static int power_gpio_pol = 0;
+static int only_for_poweroff = 0;
+
 /* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */
 static int ksz9021rn_phy_fixup(struct phy_device *phydev)
 {
@@ -324,8 +330,45 @@ static void __init imx6q_init_machine(void)
 	imx6q_axi_init();
 }
 
+static void imx6q_poweroff (void) {
+	int ret;
+
+	if ( power_gpio_pol	)
+		ret = gpio_request_one (power_gpio, GPIOF_OUT_INIT_HIGH, "power_gpio");
+	else
+		ret = gpio_request_one (power_gpio, GPIOF_OUT_INIT_LOW, "power_gpio");
+
+	if ( ret < 0)
+	printk (KERN_ERR "(%d) Unable to get kill power GPIO (%d)\n", ret, power_gpio);
+};
+
+
+void imx6q_restart (enum reboot_mode reboot_mode, const char *cmd) {
+	int ret = 0;
+	int ectrl_signed = 0;
+
+	if ( !only_for_poweroff ) {
+		if ( power_gpio_pol	)
+			ret = gpio_request_one (power_gpio, GPIOF_OUT_INIT_HIGH, "power_gpio");
+		else
+			ret = gpio_request_one (power_gpio, GPIOF_OUT_INIT_LOW, "power_gpio");
+
+		if ( ret < 0)
+			printk (KERN_ERR "Unable to get kill power GPIO\n");
+		else {
+			ectrl_signed = 1;
+		}
+	}
+
+	if ( !ectrl_signed )
+		mxc_restart (reboot_mode, cmd);
+}
+
+
+
 static void __init imx6q_init_late(void)
 {
+	struct device_node *np;
 	/*
 	 * WAIT mode is broken on imx6 Dual/Quad revision 1.0 and 1.1 so
 	 * there is no point to run cpuidle on them.
@@ -338,6 +381,19 @@ static void __init imx6q_init_late(void)
 
 	if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
 		platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
+	np = of_find_node_by_path ("/power_signal");
+	if ( np ) {
+		power_gpio = of_get_named_gpio (np, "power-gpio", 0);
+		if ( gpio_is_valid (power_gpio) ) {
+			pm_power_off = imx6q_poweroff;
+			printk (KERN_WARNING "kill power GPIO %d ok\n", power_gpio);
+		}
+		else
+			printk (KERN_WARNING "Unable to get kill power GPIO\n");
+		power_gpio_pol = of_property_read_bool(np, "set_high");
+		only_for_poweroff = of_property_read_bool(np, "only_for_poweroff");
+		np = NULL;
+	}
 }
 
 static void __init imx6q_map_io(void)
@@ -374,4 +430,6 @@ DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
 	.init_machine	= imx6q_init_machine,
 	.init_late      = imx6q_init_late,
 	.dt_compat	= imx6q_dt_compat,
+	.restart	= imx6q_restart,
+	.pwroff = imx6q_poweroff,
 MACHINE_END