static void poweroff_seq(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev); if (apb->init_disabled || apb->state == ARCHE_PLATFORM_STATE_OFF) return; if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && gpio_is_valid(apb->spi_en_gpio)) devm_gpio_free(dev, apb->spi_en_gpio); /* disable the clock */ if (gpio_is_valid(apb->clk_en_gpio)) gpio_set_value(apb->clk_en_gpio, 0); if (!IS_ERR(apb->vcore) && regulator_is_enabled(apb->vcore) > 0) regulator_disable(apb->vcore); if (!IS_ERR(apb->vio) && regulator_is_enabled(apb->vio) > 0) regulator_disable(apb->vio); /* As part of exit, put APB back in reset state */ assert_reset(apb->resetn_gpio); apb->state = ARCHE_PLATFORM_STATE_OFF; /* TODO: May have to send an event to SVC about this exit */ }
/* * Note: Please do not modify the below sequence, as it is as per the spec */ static int coldboot_seq(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev); int ret; if (apb->init_disabled || apb->state == ARCHE_PLATFORM_STATE_ACTIVE) return 0; /* Hold APB in reset state */ assert_reset(apb->resetn_gpio); if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && gpio_is_valid(apb->spi_en_gpio)) devm_gpio_free(dev, apb->spi_en_gpio); /* Enable power to APB */ if (!IS_ERR(apb->vcore)) { ret = regulator_enable(apb->vcore); if (ret) { dev_err(dev, "failed to enable core regulator\n"); return ret; } } if (!IS_ERR(apb->vio)) { ret = regulator_enable(apb->vio); if (ret) { dev_err(dev, "failed to enable IO regulator\n"); return ret; } } apb_bootret_deassert(dev); /* On DB3 clock was not mandatory */ if (gpio_is_valid(apb->clk_en_gpio)) gpio_set_value(apb->clk_en_gpio, 1); usleep_range(100, 200); /* deassert reset to APB : Active-low signal */ deassert_reset(apb->resetn_gpio); apb->state = ARCHE_PLATFORM_STATE_ACTIVE; return 0; }
static int fw_flashing_seq(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev); int ret; if (apb->init_disabled || apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING) return 0; ret = regulator_enable(apb->vcore); if (ret) { dev_err(dev, "failed to enable core regulator\n"); return ret; } ret = regulator_enable(apb->vio); if (ret) { dev_err(dev, "failed to enable IO regulator\n"); return ret; } if (gpio_is_valid(apb->spi_en_gpio)) { unsigned long flags; if (apb->spi_en_polarity_high) flags = GPIOF_OUT_INIT_HIGH; else flags = GPIOF_OUT_INIT_LOW; ret = devm_gpio_request_one(dev, apb->spi_en_gpio, flags, "apb_spi_en"); if (ret) { dev_err(dev, "Failed requesting SPI bus en gpio %d\n", apb->spi_en_gpio); return ret; } } /* for flashing device should be in reset state */ assert_reset(apb->resetn_gpio); apb->state = ARCHE_PLATFORM_STATE_FW_FLASHING; return 0; }
static void apb_ctrl_cleanup(struct arche_apb_ctrl_drvdata *apb) { /* disable the clock */ if (gpio_is_valid(apb->clk_en_gpio)) gpio_set_value(apb->clk_en_gpio, 0); if (!IS_ERR(apb->vcore) && regulator_is_enabled(apb->vcore) > 0) regulator_disable(apb->vcore); if (!IS_ERR(apb->vio) && regulator_is_enabled(apb->vio) > 0) regulator_disable(apb->vio); /* As part of exit, put APB back in reset state */ assert_reset(apb->resetn_gpio); apb->state = APB_STATE_OFF; /* TODO: May have to send an event to SVC about this exit */ }