drivers/staging/greybus/arche-apb-ctrl.c

Source file repositories/reference/linux-study-clean/drivers/staging/greybus/arche-apb-ctrl.c

File Facts

System
Linux kernel
Corpus path
drivers/staging/greybus/arche-apb-ctrl.c
Extension
.c
Size
12213 bytes
Lines
492
Domain
Driver Families
Bucket
drivers/staging
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct arche_apb_ctrl_drvdata {
	/* Control GPIO signals to and from AP <=> AP Bridges */
	struct gpio_desc *resetn;
	struct gpio_desc *boot_ret;
	struct gpio_desc *pwroff;
	struct gpio_desc *wake_in;
	struct gpio_desc *wake_out;
	struct gpio_desc *pwrdn;

	enum arche_platform_state state;
	bool init_disabled;

	struct regulator *vcore;
	struct regulator *vio;

	struct gpio_desc *clk_en;
	struct clk *clk;

	struct pinctrl *pinctrl;
	struct pinctrl_state *pin_default;

	/* V2: SPI Bus control  */
	struct gpio_desc *spi_en;
	bool spi_en_polarity_high;
};

/*
 * Note that these low level api's are active high
 */
static inline void deassert_reset(struct gpio_desc *gpio)
{
	gpiod_set_raw_value(gpio, 1);
}

static inline void assert_reset(struct gpio_desc *gpio)
{
	gpiod_set_raw_value(gpio, 0);
}

/*
 * 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);

	if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en)
		devm_gpiod_put(dev, apb->spi_en);

	/* 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 (apb->clk_en)
		gpiod_set_value(apb->clk_en, 1);

	usleep_range(100, 200);

	/* deassert reset to APB : Active-low signal */
	deassert_reset(apb->resetn);

	apb->state = ARCHE_PLATFORM_STATE_ACTIVE;

	return 0;
}

Annotation

Implementation Notes