cancel
Showing results for 
Search instead for 
Did you mean: 

Linux "gpio-poweroff" won't load

allard
Senior

I'm trying to add the linux "gpio-poweroff" function to the distribution package. I've added the following to my device tree:

gpio-poweroff {
	compatible = "gpio-poweroff";
	gpios = <&gpioe 1 GPIO_ACTIVE_HIGH>;
	timeout-ms = <3000>;
};

The kernel/device tree compiles OK, but the poweroff function does not work. The logs give the following lines about the poweroff:

[    1.482136] poweroff-gpio gpio-poweroff: gpio_poweroff_probe: pm_power_off function already registered
[    1.482174] poweroff-gpio: probe of gpio-poweroff failed with error -16

So I guess openSTLinux already has some handler attached? How do I disable this?

1 ACCEPTED SOLUTION

Accepted Solutions
Emma
Associate II

Hi @allard​ ,

gpio-poweroff is registered to psci_sys_poweroff in firmware/psci.c which invokes a PSCI (Power State Coordination Interface

) function which is implemented in TF-A.

I added code to set my poweroff gpio in TF-A. Not sure if this is the correct way to do it. If you do this, also note that the system_off_mode is defined to STM32_PM_CSTOP_ALLOW_STANDBY_DDR_OFF in the CubeMX-generated device tree for TF-A; I changed it to STM32_PM_SHUTDOWN.

View solution in original post

7 REPLIES 7
Christophe Guibout
ST Employee

Hi @allard​ ,

gpio-poweroff is not loadable because STM32MP supports power domains.

pm_power_off is already registered in stm32_pm_domain_add function (drivers/soc/st/stm32_pm_domain.c) :

domain->genpd.power_off = stm32_pd_power_off;

This feature is under CONFIG_STM32_PM_DOMAINS switch, but I don't recommand to disable it as it's part of SoC.

BR,

Christophe

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Emma
Associate II

Hi @allard​ ,

gpio-poweroff is registered to psci_sys_poweroff in firmware/psci.c which invokes a PSCI (Power State Coordination Interface

) function which is implemented in TF-A.

I added code to set my poweroff gpio in TF-A. Not sure if this is the correct way to do it. If you do this, also note that the system_off_mode is defined to STM32_PM_CSTOP_ALLOW_STANDBY_DDR_OFF in the CubeMX-generated device tree for TF-A; I changed it to STM32_PM_SHUTDOWN.

allard
Senior

@Emma​ @Christophe Guibout​ 

This should be enough info to get me going, thanks both.

hi, can you sow me some example of how to add gpio in tf-a to power off my board?

In file plat/st/stm32mp1/stm32mp1_low_power.c, function enter_shutdown(void) I put the following code after the DDR has been set in self-refresh:

/* Activate the poweroff GPIO (active low) */

uint32_t poweroff_gpio_clk = GPIOB;

uintptr_t poweroff_gpio_port = GPIOB_BASE;

uint32_t poweroff_gpio_pin = 10;

stm32mp_clk_enable(poweroff_gpio_clk);

/* Bit Reset Register (BRR): Set bit to set low output value */

mmio_setbits_32(poweroff_gpio_port + 0x28, 1 << poweroff_gpio_pin);

/* Output Type Register (OTYPER): Clear bit to configure push-pull */

mmio_clrbits_32(poweroff_gpio_port + 0x04, 1 << poweroff_gpio_pin);

/* Mode Register (MODER): 01 for GPIO output */

mmio_clrsetbits_32(poweroff_gpio_port, 1 << (poweroff_gpio_pin*2 +1),

                  1 << (poweroff_gpio_pin*2));

udelay(100);

/* If that didn't work, switch off the PMIC */

If your GPIO is active high, use BSRR (offset 0x18) instead of BRR.

Also set system_off_soc_mode to <STM32_PM_SHUTDOWN> in your device tree.

Tnx Emma, it power off the pmic immediately ? there is a way to make some delay of couple of seconds you think?

Hi there, 

I know that this reply was posted 3 years ago, but I'm facing the same problem right now. 

Your solution seems the best around the internet, but I have a question: I can't see the enter_shutdown() function in my distribution! In stm32mp1_low_power.c file, I Have enter_cstop() and enter_csleep() functions...    

I also can see these pretty interesting lines: 

void stm32_enter_low_power(uint32_t mode, uint32_t nsec_addr)
{
	switch (mode) {
	case STM32_PM_SHUTDOWN:
		break;

	case STM32_PM_CSLEEP_RUN:
		enter_csleep();
		break;

	default:
		enter_cstop(mode, nsec_addr);
		break;
	}
}

Did you create the function yourself?  If yes, how did you write that? 
I think that is a pretty big feature setting a gpio-poweroff for a Linux-embedded board, I don't know why ST doesn't give any documentation about that... 
Thanks a lot!