Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 958585f5 authored by Michael Hennerich's avatar Michael Hennerich Committed by Ben Dooks
Browse files

i2c: Blackfin I2C Driver: Functional power management support



PM_SUSPEND_MEM: Blackfin does not maintain register state through
Hibernate. Save and restore peripheral base initialization during
PM transitions.

Signed-off-by: default avatarMichael Hennerich <michael.hennerich@analog.com>
Signed-off-by: default avatarBryan Wu <cooloney@kernel.org>
Signed-off-by: default avatarBen Dooks <ben-linux@fluff.org>
parent 31321b76
Loading
Loading
Loading
Loading
+24 −11
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ struct bfin_twi_iface {
	struct i2c_msg 		*pmsg;
	int			msg_num;
	int			cur_msg;
	u16			saved_clkdiv;
	u16			saved_control;
	void __iomem		*regs_base;
};

@@ -565,32 +567,43 @@ static u32 bfin_twi_functionality(struct i2c_adapter *adap)
	       I2C_FUNC_I2C;
}


static struct i2c_algorithm bfin_twi_algorithm = {
	.master_xfer   = bfin_twi_master_xfer,
	.smbus_xfer    = bfin_twi_smbus_xfer,
	.functionality = bfin_twi_functionality,
};


static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state)
static int i2c_bfin_twi_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct bfin_twi_iface *iface = platform_get_drvdata(dev);
	struct bfin_twi_iface *iface = platform_get_drvdata(pdev);

	iface->saved_clkdiv = read_CLKDIV(iface);
	iface->saved_control = read_CONTROL(iface);

	free_irq(iface->irq, iface);

	/* Disable TWI */
	write_CONTROL(iface, read_CONTROL(iface) & ~TWI_ENA);
	SSYNC();
	write_CONTROL(iface, iface->saved_control & ~TWI_ENA);

	return 0;
}

static int i2c_bfin_twi_resume(struct platform_device *dev)
static int i2c_bfin_twi_resume(struct platform_device *pdev)
{
	struct bfin_twi_iface *iface = platform_get_drvdata(dev);
	struct bfin_twi_iface *iface = platform_get_drvdata(pdev);

	/* Enable TWI */
	write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA);
	SSYNC();
	int rc = request_irq(iface->irq, bfin_twi_interrupt_entry,
		IRQF_DISABLED, pdev->name, iface);
	if (rc) {
		dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);
		return -ENODEV;
	}

	/* Resume TWI interface clock as specified */
	write_CLKDIV(iface, iface->saved_clkdiv);

	/* Resume TWI */
	write_CONTROL(iface, iface->saved_control);

	return 0;
}