cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sun4i-gpadc-iio.c (19475B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* ADC driver for sunxi platforms' (A10, A13 and A31) GPADC
      3 *
      4 * Copyright (c) 2016 Quentin Schulz <quentin.schulz@free-electrons.com>
      5 *
      6 * The Allwinner SoCs all have an ADC that can also act as a touchscreen
      7 * controller and a thermal sensor.
      8 * The thermal sensor works only when the ADC acts as a touchscreen controller
      9 * and is configured to throw an interrupt every fixed periods of time (let say
     10 * every X seconds).
     11 * One would be tempted to disable the IP on the hardware side rather than
     12 * disabling interrupts to save some power but that resets the internal clock of
     13 * the IP, resulting in having to wait X seconds every time we want to read the
     14 * value of the thermal sensor.
     15 * This is also the reason of using autosuspend in pm_runtime. If there was no
     16 * autosuspend, the thermal sensor would need X seconds after every
     17 * pm_runtime_get_sync to get a value from the ADC. The autosuspend allows the
     18 * thermal sensor to be requested again in a certain time span before it gets
     19 * shutdown for not being used.
     20 */
     21
     22#include <linux/completion.h>
     23#include <linux/interrupt.h>
     24#include <linux/io.h>
     25#include <linux/module.h>
     26#include <linux/of.h>
     27#include <linux/of_device.h>
     28#include <linux/platform_device.h>
     29#include <linux/pm_runtime.h>
     30#include <linux/regmap.h>
     31#include <linux/thermal.h>
     32#include <linux/delay.h>
     33
     34#include <linux/iio/iio.h>
     35#include <linux/iio/driver.h>
     36#include <linux/iio/machine.h>
     37#include <linux/mfd/sun4i-gpadc.h>
     38
     39static unsigned int sun4i_gpadc_chan_select(unsigned int chan)
     40{
     41	return SUN4I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
     42}
     43
     44static unsigned int sun6i_gpadc_chan_select(unsigned int chan)
     45{
     46	return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
     47}
     48
     49struct gpadc_data {
     50	int		temp_offset;
     51	int		temp_scale;
     52	unsigned int	tp_mode_en;
     53	unsigned int	tp_adc_select;
     54	unsigned int	(*adc_chan_select)(unsigned int chan);
     55	unsigned int	adc_chan_mask;
     56};
     57
     58static const struct gpadc_data sun4i_gpadc_data = {
     59	.temp_offset = -1932,
     60	.temp_scale = 133,
     61	.tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN,
     62	.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
     63	.adc_chan_select = &sun4i_gpadc_chan_select,
     64	.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
     65};
     66
     67static const struct gpadc_data sun5i_gpadc_data = {
     68	.temp_offset = -1447,
     69	.temp_scale = 100,
     70	.tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN,
     71	.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
     72	.adc_chan_select = &sun4i_gpadc_chan_select,
     73	.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
     74};
     75
     76static const struct gpadc_data sun6i_gpadc_data = {
     77	.temp_offset = -1623,
     78	.temp_scale = 167,
     79	.tp_mode_en = SUN6I_GPADC_CTRL1_TP_MODE_EN,
     80	.tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
     81	.adc_chan_select = &sun6i_gpadc_chan_select,
     82	.adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
     83};
     84
     85static const struct gpadc_data sun8i_a33_gpadc_data = {
     86	.temp_offset = -1662,
     87	.temp_scale = 162,
     88	.tp_mode_en = SUN8I_GPADC_CTRL1_CHOP_TEMP_EN,
     89};
     90
     91struct sun4i_gpadc_iio {
     92	struct iio_dev			*indio_dev;
     93	struct completion		completion;
     94	int				temp_data;
     95	u32				adc_data;
     96	struct regmap			*regmap;
     97	unsigned int			fifo_data_irq;
     98	atomic_t			ignore_fifo_data_irq;
     99	unsigned int			temp_data_irq;
    100	atomic_t			ignore_temp_data_irq;
    101	const struct gpadc_data		*data;
    102	bool				no_irq;
    103	/* prevents concurrent reads of temperature and ADC */
    104	struct mutex			mutex;
    105	struct thermal_zone_device	*tzd;
    106	struct device			*sensor_device;
    107};
    108
    109#define SUN4I_GPADC_ADC_CHANNEL(_channel, _name) {		\
    110	.type = IIO_VOLTAGE,					\
    111	.indexed = 1,						\
    112	.channel = _channel,					\
    113	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
    114	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
    115	.datasheet_name = _name,				\
    116}
    117
    118static struct iio_map sun4i_gpadc_hwmon_maps[] = {
    119	{
    120		.adc_channel_label = "temp_adc",
    121		.consumer_dev_name = "iio_hwmon.0",
    122	},
    123	{ /* sentinel */ },
    124};
    125
    126static const struct iio_chan_spec sun4i_gpadc_channels[] = {
    127	SUN4I_GPADC_ADC_CHANNEL(0, "adc_chan0"),
    128	SUN4I_GPADC_ADC_CHANNEL(1, "adc_chan1"),
    129	SUN4I_GPADC_ADC_CHANNEL(2, "adc_chan2"),
    130	SUN4I_GPADC_ADC_CHANNEL(3, "adc_chan3"),
    131	{
    132		.type = IIO_TEMP,
    133		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    134				      BIT(IIO_CHAN_INFO_SCALE) |
    135				      BIT(IIO_CHAN_INFO_OFFSET),
    136		.datasheet_name = "temp_adc",
    137	},
    138};
    139
    140static const struct iio_chan_spec sun4i_gpadc_channels_no_temp[] = {
    141	SUN4I_GPADC_ADC_CHANNEL(0, "adc_chan0"),
    142	SUN4I_GPADC_ADC_CHANNEL(1, "adc_chan1"),
    143	SUN4I_GPADC_ADC_CHANNEL(2, "adc_chan2"),
    144	SUN4I_GPADC_ADC_CHANNEL(3, "adc_chan3"),
    145};
    146
    147static const struct iio_chan_spec sun8i_a33_gpadc_channels[] = {
    148	{
    149		.type = IIO_TEMP,
    150		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    151				      BIT(IIO_CHAN_INFO_SCALE) |
    152				      BIT(IIO_CHAN_INFO_OFFSET),
    153		.datasheet_name = "temp_adc",
    154	},
    155};
    156
    157static const struct regmap_config sun4i_gpadc_regmap_config = {
    158	.reg_bits = 32,
    159	.val_bits = 32,
    160	.reg_stride = 4,
    161	.fast_io = true,
    162};
    163
    164static int sun4i_prepare_for_irq(struct iio_dev *indio_dev, int channel,
    165				 unsigned int irq)
    166{
    167	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
    168	int ret;
    169	u32 reg;
    170
    171	pm_runtime_get_sync(indio_dev->dev.parent);
    172
    173	reinit_completion(&info->completion);
    174
    175	ret = regmap_write(info->regmap, SUN4I_GPADC_INT_FIFOC,
    176			   SUN4I_GPADC_INT_FIFOC_TP_FIFO_TRIG_LEVEL(1) |
    177			   SUN4I_GPADC_INT_FIFOC_TP_FIFO_FLUSH);
    178	if (ret)
    179		return ret;
    180
    181	ret = regmap_read(info->regmap, SUN4I_GPADC_CTRL1, &reg);
    182	if (ret)
    183		return ret;
    184
    185	if (irq == info->fifo_data_irq) {
    186		ret = regmap_write(info->regmap, SUN4I_GPADC_CTRL1,
    187				   info->data->tp_mode_en |
    188				   info->data->tp_adc_select |
    189				   info->data->adc_chan_select(channel));
    190		/*
    191		 * When the IP changes channel, it needs a bit of time to get
    192		 * correct values.
    193		 */
    194		if ((reg & info->data->adc_chan_mask) !=
    195			 info->data->adc_chan_select(channel))
    196			mdelay(10);
    197
    198	} else {
    199		/*
    200		 * The temperature sensor returns valid data only when the ADC
    201		 * operates in touchscreen mode.
    202		 */
    203		ret = regmap_write(info->regmap, SUN4I_GPADC_CTRL1,
    204				   info->data->tp_mode_en);
    205	}
    206
    207	if (ret)
    208		return ret;
    209
    210	/*
    211	 * When the IP changes mode between ADC or touchscreen, it
    212	 * needs a bit of time to get correct values.
    213	 */
    214	if ((reg & info->data->tp_adc_select) != info->data->tp_adc_select)
    215		mdelay(100);
    216
    217	return 0;
    218}
    219
    220static int sun4i_gpadc_read(struct iio_dev *indio_dev, int channel, int *val,
    221			    unsigned int irq)
    222{
    223	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
    224	int ret;
    225
    226	mutex_lock(&info->mutex);
    227
    228	ret = sun4i_prepare_for_irq(indio_dev, channel, irq);
    229	if (ret)
    230		goto err;
    231
    232	enable_irq(irq);
    233
    234	/*
    235	 * The temperature sensor throws an interruption periodically (currently
    236	 * set at periods of ~0.6s in sun4i_gpadc_runtime_resume). A 1s delay
    237	 * makes sure an interruption occurs in normal conditions. If it doesn't
    238	 * occur, then there is a timeout.
    239	 */
    240	if (!wait_for_completion_timeout(&info->completion,
    241					 msecs_to_jiffies(1000))) {
    242		ret = -ETIMEDOUT;
    243		goto err;
    244	}
    245
    246	if (irq == info->fifo_data_irq)
    247		*val = info->adc_data;
    248	else
    249		*val = info->temp_data;
    250
    251	ret = 0;
    252	pm_runtime_mark_last_busy(indio_dev->dev.parent);
    253
    254err:
    255	pm_runtime_put_autosuspend(indio_dev->dev.parent);
    256	disable_irq(irq);
    257	mutex_unlock(&info->mutex);
    258
    259	return ret;
    260}
    261
    262static int sun4i_gpadc_adc_read(struct iio_dev *indio_dev, int channel,
    263				int *val)
    264{
    265	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
    266
    267	return sun4i_gpadc_read(indio_dev, channel, val, info->fifo_data_irq);
    268}
    269
    270static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val)
    271{
    272	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
    273
    274	if (info->no_irq) {
    275		pm_runtime_get_sync(indio_dev->dev.parent);
    276
    277		regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val);
    278
    279		pm_runtime_mark_last_busy(indio_dev->dev.parent);
    280		pm_runtime_put_autosuspend(indio_dev->dev.parent);
    281
    282		return 0;
    283	}
    284
    285	return sun4i_gpadc_read(indio_dev, 0, val, info->temp_data_irq);
    286}
    287
    288static int sun4i_gpadc_temp_offset(struct iio_dev *indio_dev, int *val)
    289{
    290	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
    291
    292	*val = info->data->temp_offset;
    293
    294	return 0;
    295}
    296
    297static int sun4i_gpadc_temp_scale(struct iio_dev *indio_dev, int *val)
    298{
    299	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
    300
    301	*val = info->data->temp_scale;
    302
    303	return 0;
    304}
    305
    306static int sun4i_gpadc_read_raw(struct iio_dev *indio_dev,
    307				struct iio_chan_spec const *chan, int *val,
    308				int *val2, long mask)
    309{
    310	int ret;
    311
    312	switch (mask) {
    313	case IIO_CHAN_INFO_OFFSET:
    314		ret = sun4i_gpadc_temp_offset(indio_dev, val);
    315		if (ret)
    316			return ret;
    317
    318		return IIO_VAL_INT;
    319	case IIO_CHAN_INFO_RAW:
    320		if (chan->type == IIO_VOLTAGE)
    321			ret = sun4i_gpadc_adc_read(indio_dev, chan->channel,
    322						   val);
    323		else
    324			ret = sun4i_gpadc_temp_read(indio_dev, val);
    325
    326		if (ret)
    327			return ret;
    328
    329		return IIO_VAL_INT;
    330	case IIO_CHAN_INFO_SCALE:
    331		if (chan->type == IIO_VOLTAGE) {
    332			/* 3000mV / 4096 * raw */
    333			*val = 0;
    334			*val2 = 732421875;
    335			return IIO_VAL_INT_PLUS_NANO;
    336		}
    337
    338		ret = sun4i_gpadc_temp_scale(indio_dev, val);
    339		if (ret)
    340			return ret;
    341
    342		return IIO_VAL_INT;
    343	default:
    344		return -EINVAL;
    345	}
    346
    347	return -EINVAL;
    348}
    349
    350static const struct iio_info sun4i_gpadc_iio_info = {
    351	.read_raw = sun4i_gpadc_read_raw,
    352};
    353
    354static irqreturn_t sun4i_gpadc_temp_data_irq_handler(int irq, void *dev_id)
    355{
    356	struct sun4i_gpadc_iio *info = dev_id;
    357
    358	if (atomic_read(&info->ignore_temp_data_irq))
    359		goto out;
    360
    361	if (!regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, &info->temp_data))
    362		complete(&info->completion);
    363
    364out:
    365	return IRQ_HANDLED;
    366}
    367
    368static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int irq, void *dev_id)
    369{
    370	struct sun4i_gpadc_iio *info = dev_id;
    371
    372	if (atomic_read(&info->ignore_fifo_data_irq))
    373		goto out;
    374
    375	if (!regmap_read(info->regmap, SUN4I_GPADC_DATA, &info->adc_data))
    376		complete(&info->completion);
    377
    378out:
    379	return IRQ_HANDLED;
    380}
    381
    382static int sun4i_gpadc_runtime_suspend(struct device *dev)
    383{
    384	struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
    385
    386	/* Disable the ADC on IP */
    387	regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0);
    388	/* Disable temperature sensor on IP */
    389	regmap_write(info->regmap, SUN4I_GPADC_TPR, 0);
    390
    391	return 0;
    392}
    393
    394static int sun4i_gpadc_runtime_resume(struct device *dev)
    395{
    396	struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
    397
    398	/* clkin = 6MHz */
    399	regmap_write(info->regmap, SUN4I_GPADC_CTRL0,
    400		     SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(2) |
    401		     SUN4I_GPADC_CTRL0_FS_DIV(7) |
    402		     SUN4I_GPADC_CTRL0_T_ACQ(63));
    403	regmap_write(info->regmap, SUN4I_GPADC_CTRL1, info->data->tp_mode_en);
    404	regmap_write(info->regmap, SUN4I_GPADC_CTRL3,
    405		     SUN4I_GPADC_CTRL3_FILTER_EN |
    406		     SUN4I_GPADC_CTRL3_FILTER_TYPE(1));
    407	/* period = SUN4I_GPADC_TPR_TEMP_PERIOD * 256 * 16 / clkin; ~0.6s */
    408	regmap_write(info->regmap, SUN4I_GPADC_TPR,
    409		     SUN4I_GPADC_TPR_TEMP_ENABLE |
    410		     SUN4I_GPADC_TPR_TEMP_PERIOD(800));
    411
    412	return 0;
    413}
    414
    415static int sun4i_gpadc_get_temp(void *data, int *temp)
    416{
    417	struct sun4i_gpadc_iio *info = data;
    418	int val, scale, offset;
    419
    420	if (sun4i_gpadc_temp_read(info->indio_dev, &val))
    421		return -ETIMEDOUT;
    422
    423	sun4i_gpadc_temp_scale(info->indio_dev, &scale);
    424	sun4i_gpadc_temp_offset(info->indio_dev, &offset);
    425
    426	*temp = (val + offset) * scale;
    427
    428	return 0;
    429}
    430
    431static const struct thermal_zone_of_device_ops sun4i_ts_tz_ops = {
    432	.get_temp = &sun4i_gpadc_get_temp,
    433};
    434
    435static const struct dev_pm_ops sun4i_gpadc_pm_ops = {
    436	.runtime_suspend = &sun4i_gpadc_runtime_suspend,
    437	.runtime_resume = &sun4i_gpadc_runtime_resume,
    438};
    439
    440static int sun4i_irq_init(struct platform_device *pdev, const char *name,
    441			  irq_handler_t handler, const char *devname,
    442			  unsigned int *irq, atomic_t *atomic)
    443{
    444	int ret;
    445	struct sun4i_gpadc_dev *mfd_dev = dev_get_drvdata(pdev->dev.parent);
    446	struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(&pdev->dev));
    447
    448	/*
    449	 * Once the interrupt is activated, the IP continuously performs
    450	 * conversions thus throws interrupts. The interrupt is activated right
    451	 * after being requested but we want to control when these interrupts
    452	 * occur thus we disable it right after being requested. However, an
    453	 * interrupt might occur between these two instructions and we have to
    454	 * make sure that does not happen, by using atomic flags. We set the
    455	 * flag before requesting the interrupt and unset it right after
    456	 * disabling the interrupt. When an interrupt occurs between these two
    457	 * instructions, reading the atomic flag will tell us to ignore the
    458	 * interrupt.
    459	 */
    460	atomic_set(atomic, 1);
    461
    462	ret = platform_get_irq_byname(pdev, name);
    463	if (ret < 0)
    464		return ret;
    465
    466	ret = regmap_irq_get_virq(mfd_dev->regmap_irqc, ret);
    467	if (ret < 0) {
    468		dev_err(&pdev->dev, "failed to get virq for irq %s\n", name);
    469		return ret;
    470	}
    471
    472	*irq = ret;
    473	ret = devm_request_any_context_irq(&pdev->dev, *irq, handler,
    474					   IRQF_NO_AUTOEN,
    475					   devname, info);
    476	if (ret < 0) {
    477		dev_err(&pdev->dev, "could not request %s interrupt: %d\n",
    478			name, ret);
    479		return ret;
    480	}
    481
    482	atomic_set(atomic, 0);
    483
    484	return 0;
    485}
    486
    487static const struct of_device_id sun4i_gpadc_of_id[] = {
    488	{
    489		.compatible = "allwinner,sun8i-a33-ths",
    490		.data = &sun8i_a33_gpadc_data,
    491	},
    492	{ /* sentinel */ }
    493};
    494
    495static int sun4i_gpadc_probe_dt(struct platform_device *pdev,
    496				struct iio_dev *indio_dev)
    497{
    498	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
    499	void __iomem *base;
    500	int ret;
    501
    502	info->data = of_device_get_match_data(&pdev->dev);
    503	if (!info->data)
    504		return -ENODEV;
    505
    506	info->no_irq = true;
    507	indio_dev->num_channels = ARRAY_SIZE(sun8i_a33_gpadc_channels);
    508	indio_dev->channels = sun8i_a33_gpadc_channels;
    509
    510	base = devm_platform_ioremap_resource(pdev, 0);
    511	if (IS_ERR(base))
    512		return PTR_ERR(base);
    513
    514	info->regmap = devm_regmap_init_mmio(&pdev->dev, base,
    515					     &sun4i_gpadc_regmap_config);
    516	if (IS_ERR(info->regmap)) {
    517		ret = PTR_ERR(info->regmap);
    518		dev_err(&pdev->dev, "failed to init regmap: %d\n", ret);
    519		return ret;
    520	}
    521
    522	if (IS_ENABLED(CONFIG_THERMAL_OF))
    523		info->sensor_device = &pdev->dev;
    524
    525	return 0;
    526}
    527
    528static int sun4i_gpadc_probe_mfd(struct platform_device *pdev,
    529				 struct iio_dev *indio_dev)
    530{
    531	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
    532	struct sun4i_gpadc_dev *sun4i_gpadc_dev =
    533		dev_get_drvdata(pdev->dev.parent);
    534	int ret;
    535
    536	info->no_irq = false;
    537	info->regmap = sun4i_gpadc_dev->regmap;
    538
    539	indio_dev->num_channels = ARRAY_SIZE(sun4i_gpadc_channels);
    540	indio_dev->channels = sun4i_gpadc_channels;
    541
    542	info->data = (struct gpadc_data *)platform_get_device_id(pdev)->driver_data;
    543
    544	/*
    545	 * Since the controller needs to be in touchscreen mode for its thermal
    546	 * sensor to operate properly, and that switching between the two modes
    547	 * needs a delay, always registering in the thermal framework will
    548	 * significantly slow down the conversion rate of the ADCs.
    549	 *
    550	 * Therefore, instead of depending on THERMAL_OF in Kconfig, we only
    551	 * register the sensor if that option is enabled, eventually leaving
    552	 * that choice to the user.
    553	 */
    554
    555	if (IS_ENABLED(CONFIG_THERMAL_OF)) {
    556		/*
    557		 * This driver is a child of an MFD which has a node in the DT
    558		 * but not its children, because of DT backward compatibility
    559		 * for A10, A13 and A31 SoCs. Therefore, the resulting devices
    560		 * of this driver do not have an of_node variable.
    561		 * However, its parent (the MFD driver) has an of_node variable
    562		 * and since devm_thermal_zone_of_sensor_register uses its first
    563		 * argument to match the phandle defined in the node of the
    564		 * thermal driver with the of_node of the device passed as first
    565		 * argument and the third argument to call ops from
    566		 * thermal_zone_of_device_ops, the solution is to use the parent
    567		 * device as first argument to match the phandle with its
    568		 * of_node, and the device from this driver as third argument to
    569		 * return the temperature.
    570		 */
    571		info->sensor_device = pdev->dev.parent;
    572	} else {
    573		indio_dev->num_channels =
    574			ARRAY_SIZE(sun4i_gpadc_channels_no_temp);
    575		indio_dev->channels = sun4i_gpadc_channels_no_temp;
    576	}
    577
    578	if (IS_ENABLED(CONFIG_THERMAL_OF)) {
    579		ret = sun4i_irq_init(pdev, "TEMP_DATA_PENDING",
    580				     sun4i_gpadc_temp_data_irq_handler,
    581				     "temp_data", &info->temp_data_irq,
    582				     &info->ignore_temp_data_irq);
    583		if (ret < 0)
    584			return ret;
    585	}
    586
    587	ret = sun4i_irq_init(pdev, "FIFO_DATA_PENDING",
    588			     sun4i_gpadc_fifo_data_irq_handler, "fifo_data",
    589			     &info->fifo_data_irq, &info->ignore_fifo_data_irq);
    590	if (ret < 0)
    591		return ret;
    592
    593	if (IS_ENABLED(CONFIG_THERMAL_OF)) {
    594		ret = iio_map_array_register(indio_dev, sun4i_gpadc_hwmon_maps);
    595		if (ret < 0) {
    596			dev_err(&pdev->dev,
    597				"failed to register iio map array\n");
    598			return ret;
    599		}
    600	}
    601
    602	return 0;
    603}
    604
    605static int sun4i_gpadc_probe(struct platform_device *pdev)
    606{
    607	struct sun4i_gpadc_iio *info;
    608	struct iio_dev *indio_dev;
    609	int ret;
    610
    611	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
    612	if (!indio_dev)
    613		return -ENOMEM;
    614
    615	info = iio_priv(indio_dev);
    616	platform_set_drvdata(pdev, indio_dev);
    617
    618	mutex_init(&info->mutex);
    619	info->indio_dev = indio_dev;
    620	init_completion(&info->completion);
    621	indio_dev->name = dev_name(&pdev->dev);
    622	indio_dev->info = &sun4i_gpadc_iio_info;
    623	indio_dev->modes = INDIO_DIRECT_MODE;
    624
    625	if (pdev->dev.of_node)
    626		ret = sun4i_gpadc_probe_dt(pdev, indio_dev);
    627	else
    628		ret = sun4i_gpadc_probe_mfd(pdev, indio_dev);
    629
    630	if (ret)
    631		return ret;
    632
    633	pm_runtime_set_autosuspend_delay(&pdev->dev,
    634					 SUN4I_GPADC_AUTOSUSPEND_DELAY);
    635	pm_runtime_use_autosuspend(&pdev->dev);
    636	pm_runtime_set_suspended(&pdev->dev);
    637	pm_runtime_enable(&pdev->dev);
    638
    639	if (IS_ENABLED(CONFIG_THERMAL_OF)) {
    640		info->tzd = thermal_zone_of_sensor_register(info->sensor_device,
    641							    0, info,
    642							    &sun4i_ts_tz_ops);
    643		/*
    644		 * Do not fail driver probing when failing to register in
    645		 * thermal because no thermal DT node is found.
    646		 */
    647		if (IS_ERR(info->tzd) && PTR_ERR(info->tzd) != -ENODEV) {
    648			dev_err(&pdev->dev,
    649				"could not register thermal sensor: %ld\n",
    650				PTR_ERR(info->tzd));
    651			return PTR_ERR(info->tzd);
    652		}
    653	}
    654
    655	ret = devm_iio_device_register(&pdev->dev, indio_dev);
    656	if (ret < 0) {
    657		dev_err(&pdev->dev, "could not register the device\n");
    658		goto err_map;
    659	}
    660
    661	return 0;
    662
    663err_map:
    664	if (!info->no_irq && IS_ENABLED(CONFIG_THERMAL_OF))
    665		iio_map_array_unregister(indio_dev);
    666
    667	pm_runtime_put(&pdev->dev);
    668	pm_runtime_disable(&pdev->dev);
    669
    670	return ret;
    671}
    672
    673static int sun4i_gpadc_remove(struct platform_device *pdev)
    674{
    675	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
    676	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
    677
    678	pm_runtime_put(&pdev->dev);
    679	pm_runtime_disable(&pdev->dev);
    680
    681	if (!IS_ENABLED(CONFIG_THERMAL_OF))
    682		return 0;
    683
    684	thermal_zone_of_sensor_unregister(info->sensor_device, info->tzd);
    685
    686	if (!info->no_irq)
    687		iio_map_array_unregister(indio_dev);
    688
    689	return 0;
    690}
    691
    692static const struct platform_device_id sun4i_gpadc_id[] = {
    693	{ "sun4i-a10-gpadc-iio", (kernel_ulong_t)&sun4i_gpadc_data },
    694	{ "sun5i-a13-gpadc-iio", (kernel_ulong_t)&sun5i_gpadc_data },
    695	{ "sun6i-a31-gpadc-iio", (kernel_ulong_t)&sun6i_gpadc_data },
    696	{ /* sentinel */ },
    697};
    698MODULE_DEVICE_TABLE(platform, sun4i_gpadc_id);
    699
    700static struct platform_driver sun4i_gpadc_driver = {
    701	.driver = {
    702		.name = "sun4i-gpadc-iio",
    703		.of_match_table = sun4i_gpadc_of_id,
    704		.pm = &sun4i_gpadc_pm_ops,
    705	},
    706	.id_table = sun4i_gpadc_id,
    707	.probe = sun4i_gpadc_probe,
    708	.remove = sun4i_gpadc_remove,
    709};
    710MODULE_DEVICE_TABLE(of, sun4i_gpadc_of_id);
    711
    712module_platform_driver(sun4i_gpadc_driver);
    713
    714MODULE_DESCRIPTION("ADC driver for sunxi platforms");
    715MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
    716MODULE_LICENSE("GPL v2");