Inter-revision diff: patch 2

Comparing v4 (message) to v5 (message)

--- v4
+++ v5
@@ -15,25 +15,30 @@
 Changes in v4:
 	No changes
 
- drivers/mfd/Kconfig                  |    9 ++
+Changes in v5:
+	Make use of devm_xxx and regmap MMIO API's.
+
+ drivers/mfd/Kconfig                  |   11 ++
  drivers/mfd/Makefile                 |    1 +
- drivers/mfd/ti_am335x_tscadc.c       |  193 ++++++++++++++++++++++++++++++++++
- include/linux/mfd/ti_am335x_tscadc.h |  133 +++++++++++++++++++++++
- 4 files changed, 336 insertions(+), 0 deletions(-)
+ drivers/mfd/ti_am335x_tscadc.c       |  250 ++++++++++++++++++++++++++++++++++
+ include/linux/mfd/ti_am335x_tscadc.h |  137 +++++++++++++++++++
+ 4 files changed, 399 insertions(+), 0 deletions(-)
  create mode 100644 drivers/mfd/ti_am335x_tscadc.c
  create mode 100644 include/linux/mfd/ti_am335x_tscadc.h
 
 diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
-index b1a1462..e472184 100644
+index b1a1462..8a1d655 100644
 --- a/drivers/mfd/Kconfig
 +++ b/drivers/mfd/Kconfig
-@@ -94,6 +94,15 @@ config MFD_TI_SSP
+@@ -94,6 +94,17 @@ config MFD_TI_SSP
  	  To compile this driver as a module, choose M here: the
  	  module will be called ti-ssp.
  
 +config MFD_TI_AM335X_TSCADC
 +	tristate "TI ADC / Touch Screen chip support"
-+	depends on ARCH_OMAP2PLUS
++	select MFD_CORE
++	select REGMAP
++	select REGMAP_MMIO
 +	help
 +	  If you say yes here you get support for Texas Instruments series
 +	  of Touch Screen /ADC chips.
@@ -57,10 +62,10 @@
  obj-$(CONFIG_MFD_STMPE)		+= stmpe.o
 diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
 new file mode 100644
-index 0000000..ae93b48
+index 0000000..14df67b
 --- /dev/null
 +++ b/drivers/mfd/ti_am335x_tscadc.c
-@@ -0,0 +1,193 @@
+@@ -0,0 +1,250 @@
 +/*
 + * TI Touch Screen / ADC MFD driver
 + *
@@ -82,20 +87,32 @@
 +#include <linux/err.h>
 +#include <linux/io.h>
 +#include <linux/clk.h>
++#include <linux/regmap.h>
 +#include <linux/mfd/core.h>
 +#include <linux/pm_runtime.h>
++
 +#include <linux/mfd/ti_am335x_tscadc.h>
 +
 +static unsigned int tscadc_readl(struct ti_tscadc_dev *tsadc, unsigned int reg)
 +{
-+	return readl(tsadc->tscadc_base + reg);
++	unsigned int val;
++
++	regmap_read(tsadc->regmap_tscadc, reg, &val);
++	return val;
 +}
 +
 +static void tscadc_writel(struct ti_tscadc_dev *tsadc, unsigned int reg,
 +					unsigned int val)
 +{
-+	writel(val, tsadc->tscadc_base + reg);
-+}
++	regmap_write(tsadc->regmap_tscadc, reg, val);
++}
++
++static const struct regmap_config tscadc_regmap_config = {
++	.name = "ti_tscadc",
++	.reg_bits = 32,
++	.reg_stride = 4,
++	.val_bits = 32,
++};
 +
 +static void tscadc_idle_config(struct ti_tscadc_dev *config)
 +{
@@ -135,7 +152,8 @@
 +	}
 +
 +	/* Allocate memory for device */
-+	tscadc = kzalloc(sizeof(struct ti_tscadc_dev), GFP_KERNEL);
++	tscadc = devm_kzalloc(&pdev->dev,
++			sizeof(struct ti_tscadc_dev), GFP_KERNEL);
 +	if (!tscadc) {
 +		dev_err(&pdev->dev, "failed to allocate memory.\n");
 +		return -ENOMEM;
@@ -143,18 +161,28 @@
 +	tscadc->dev = &pdev->dev;
 +	tscadc->irq = irq;
 +
-+	res = request_mem_region(res->start, resource_size(res), pdev->name);
++	res = devm_request_mem_region(&pdev->dev,
++			res->start, resource_size(res), pdev->name);
 +	if (!res) {
 +		dev_err(&pdev->dev, "failed to reserve registers.\n");
 +		err = -EBUSY;
-+		goto err_free_mem;
-+	}
-+
-+	tscadc->tscadc_base = ioremap(res->start, resource_size(res));
++		goto err;
++	}
++
++	tscadc->tscadc_base = devm_ioremap(&pdev->dev,
++			res->start, resource_size(res));
 +	if (!tscadc->tscadc_base) {
 +		dev_err(&pdev->dev, "failed to map registers.\n");
 +		err = -ENOMEM;
-+		goto err_release_mem_region;
++		goto err;
++	}
++
++	tscadc->regmap_tscadc = devm_regmap_init_mmio(&pdev->dev,
++			tscadc->tscadc_base, &tscadc_regmap_config);
++	if (IS_ERR(tscadc->regmap_tscadc)) {
++		dev_err(&pdev->dev, "regmap init failed\n");
++		err = PTR_ERR(tscadc->regmap_tscadc);
++		goto err;
 +	}
 +
 +	pm_runtime_enable(&pdev->dev);
@@ -206,43 +234,77 @@
 +	if (err < 0)
 +		goto err_disable_clk;
 +
++	device_init_wakeup(&pdev->dev, true);
 +	platform_set_drvdata(pdev, tscadc);
++
 +	return 0;
 +
 +err_disable_clk:
 +	pm_runtime_put_sync(&pdev->dev);
 +	pm_runtime_disable(&pdev->dev);
-+	iounmap(tscadc->tscadc_base);
-+err_release_mem_region:
-+	release_mem_region(res->start, resource_size(res));
-+	mfd_remove_devices(tscadc->dev);
-+err_free_mem:
-+	kfree(tscadc);
++err:
 +	return err;
 +}
 +
 +static int __devexit ti_tscadc_remove(struct platform_device *pdev)
 +{
 +	struct ti_tscadc_dev	*tscadc = platform_get_drvdata(pdev);
-+	struct resource		*res;
 +
 +	tscadc_writel(tscadc, REG_SE, 0x00);
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	iounmap(tscadc->tscadc_base);
-+	release_mem_region(res->start, resource_size(res));
 +
 +	pm_runtime_put_sync(&pdev->dev);
 +	pm_runtime_disable(&pdev->dev);
 +
 +	mfd_remove_devices(tscadc->dev);
-+	kfree(tscadc);
++
 +	return 0;
 +}
++
++#ifdef CONFIG_PM
++static int tscadc_suspend(struct device *dev)
++{
++	struct ti_tscadc_dev	*tscadc_dev = dev_get_drvdata(dev);
++
++	tscadc_writel(tscadc_dev, REG_SE, 0x00);
++	pm_runtime_put_sync(dev);
++
++	return 0;
++}
++
++static int tscadc_resume(struct device *dev)
++{
++	struct ti_tscadc_dev	*tscadc_dev = dev_get_drvdata(dev);
++	unsigned int restore, ctrl;
++
++	pm_runtime_get_sync(dev);
++
++	/* context restore */
++	ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_TSCENB |
++			CNTRLREG_STEPID | CNTRLREG_4WIRE;
++	tscadc_writel(tscadc_dev, REG_CTRL, ctrl);
++	tscadc_idle_config(tscadc_dev);
++	tscadc_writel(tscadc_dev, REG_SE, STPENB_STEPENB);
++	restore = tscadc_readl(tscadc_dev, REG_CTRL);
++	tscadc_writel(tscadc_dev, REG_CTRL,
++			(restore | CNTRLREG_TSCSSENB));
++
++	return 0;
++}
++
++static const struct dev_pm_ops tscadc_pm_ops = {
++	.suspend = tscadc_suspend,
++	.resume = tscadc_resume,
++};
++#define TSCADC_PM_OPS (&tscadc_pm_ops)
++#else
++#define TSCADC_PM_OPS NULL
++#endif
 +
 +static struct platform_driver ti_tscadc_driver = {
 +	.driver = {
 +		.name   = "ti_tscadc",
 +		.owner	= THIS_MODULE,
++		.pm	= TSCADC_PM_OPS,
 +	},
 +	.probe	= ti_tscadc_probe,
 +	.remove	= __devexit_p(ti_tscadc_remove),
@@ -256,10 +318,10 @@
 +MODULE_LICENSE("GPL");
 diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
 new file mode 100644
-index 0000000..b1eec17
+index 0000000..b7232b1
 --- /dev/null
 +++ b/include/linux/mfd/ti_am335x_tscadc.h
-@@ -0,0 +1,133 @@
+@@ -0,0 +1,137 @@
 +#ifndef __LINUX_TI_AM335X_TSCADC_MFD_H
 +#define __LINUX_TI_AM335X_TSCADC_MFD_H
 +
@@ -302,6 +364,9 @@
 +#define REG_FIFO1		0x200
 +
 +/*	Register Bitfields	*/
++/* IRQ wakeup enable */
++#define IRQWKUP_ENB		BIT(0)
++
 +/* Step Enable */
 +#define STEPENB_MASK		(0x1FFFF << 0)
 +#define STEPENB(val)		((val) << 0)
@@ -387,6 +452,7 @@
 +
 +struct ti_tscadc_dev {
 +	struct device *dev;
++	struct regmap *regmap_tscadc;
 +	void __iomem *tscadc_base;
 +	int irq;
 +	struct mfd_cell cells[TSCADC_CELLS];
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help