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

sirf.c (12285B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * SiRFstar GNSS receiver driver
      4 *
      5 * Copyright (C) 2018 Johan Hovold <johan@kernel.org>
      6 */
      7
      8#include <linux/errno.h>
      9#include <linux/gnss.h>
     10#include <linux/gpio/consumer.h>
     11#include <linux/init.h>
     12#include <linux/interrupt.h>
     13#include <linux/kernel.h>
     14#include <linux/module.h>
     15#include <linux/of.h>
     16#include <linux/pm.h>
     17#include <linux/pm_runtime.h>
     18#include <linux/regulator/consumer.h>
     19#include <linux/sched.h>
     20#include <linux/serdev.h>
     21#include <linux/slab.h>
     22#include <linux/wait.h>
     23
     24#define SIRF_BOOT_DELAY			500
     25#define SIRF_ON_OFF_PULSE_TIME		100
     26#define SIRF_ACTIVATE_TIMEOUT		200
     27#define SIRF_HIBERNATE_TIMEOUT		200
     28/*
     29 * If no data arrives for this time, we assume that the chip is off.
     30 * REVISIT: The report cycle is configurable and can be several minutes long,
     31 * so this will only work reliably if the report cycle is set to a reasonable
     32 * low value. Also power saving settings (like send data only on movement)
     33 * might things work even worse.
     34 * Workaround might be to parse shutdown or bootup messages.
     35 */
     36#define SIRF_REPORT_CYCLE	2000
     37
     38struct sirf_data {
     39	struct gnss_device *gdev;
     40	struct serdev_device *serdev;
     41	speed_t	speed;
     42	struct regulator *vcc;
     43	struct regulator *lna;
     44	struct gpio_desc *on_off;
     45	struct gpio_desc *wakeup;
     46	int irq;
     47	bool active;
     48
     49	struct mutex gdev_mutex;
     50	bool open;
     51
     52	struct mutex serdev_mutex;
     53	int serdev_count;
     54
     55	wait_queue_head_t power_wait;
     56};
     57
     58static int sirf_serdev_open(struct sirf_data *data)
     59{
     60	int ret = 0;
     61
     62	mutex_lock(&data->serdev_mutex);
     63	if (++data->serdev_count == 1) {
     64		ret = serdev_device_open(data->serdev);
     65		if (ret) {
     66			data->serdev_count--;
     67			goto out_unlock;
     68		}
     69
     70		serdev_device_set_baudrate(data->serdev, data->speed);
     71		serdev_device_set_flow_control(data->serdev, false);
     72	}
     73
     74out_unlock:
     75	mutex_unlock(&data->serdev_mutex);
     76
     77	return ret;
     78}
     79
     80static void sirf_serdev_close(struct sirf_data *data)
     81{
     82	mutex_lock(&data->serdev_mutex);
     83	if (--data->serdev_count == 0)
     84		serdev_device_close(data->serdev);
     85	mutex_unlock(&data->serdev_mutex);
     86}
     87
     88static int sirf_open(struct gnss_device *gdev)
     89{
     90	struct sirf_data *data = gnss_get_drvdata(gdev);
     91	struct serdev_device *serdev = data->serdev;
     92	int ret;
     93
     94	mutex_lock(&data->gdev_mutex);
     95	data->open = true;
     96	mutex_unlock(&data->gdev_mutex);
     97
     98	ret = sirf_serdev_open(data);
     99	if (ret) {
    100		mutex_lock(&data->gdev_mutex);
    101		data->open = false;
    102		mutex_unlock(&data->gdev_mutex);
    103		return ret;
    104	}
    105
    106	ret = pm_runtime_get_sync(&serdev->dev);
    107	if (ret < 0) {
    108		dev_err(&gdev->dev, "failed to runtime resume: %d\n", ret);
    109		pm_runtime_put_noidle(&serdev->dev);
    110		goto err_close;
    111	}
    112
    113	return 0;
    114
    115err_close:
    116	sirf_serdev_close(data);
    117
    118	mutex_lock(&data->gdev_mutex);
    119	data->open = false;
    120	mutex_unlock(&data->gdev_mutex);
    121
    122	return ret;
    123}
    124
    125static void sirf_close(struct gnss_device *gdev)
    126{
    127	struct sirf_data *data = gnss_get_drvdata(gdev);
    128	struct serdev_device *serdev = data->serdev;
    129
    130	sirf_serdev_close(data);
    131
    132	pm_runtime_put(&serdev->dev);
    133
    134	mutex_lock(&data->gdev_mutex);
    135	data->open = false;
    136	mutex_unlock(&data->gdev_mutex);
    137}
    138
    139static int sirf_write_raw(struct gnss_device *gdev, const unsigned char *buf,
    140				size_t count)
    141{
    142	struct sirf_data *data = gnss_get_drvdata(gdev);
    143	struct serdev_device *serdev = data->serdev;
    144	int ret;
    145
    146	/* write is only buffered synchronously */
    147	ret = serdev_device_write(serdev, buf, count, MAX_SCHEDULE_TIMEOUT);
    148	if (ret < 0 || ret < count)
    149		return ret;
    150
    151	/* FIXME: determine if interrupted? */
    152	serdev_device_wait_until_sent(serdev, 0);
    153
    154	return count;
    155}
    156
    157static const struct gnss_operations sirf_gnss_ops = {
    158	.open		= sirf_open,
    159	.close		= sirf_close,
    160	.write_raw	= sirf_write_raw,
    161};
    162
    163static int sirf_receive_buf(struct serdev_device *serdev,
    164				const unsigned char *buf, size_t count)
    165{
    166	struct sirf_data *data = serdev_device_get_drvdata(serdev);
    167	struct gnss_device *gdev = data->gdev;
    168	int ret = 0;
    169
    170	if (!data->wakeup && !data->active) {
    171		data->active = true;
    172		wake_up_interruptible(&data->power_wait);
    173	}
    174
    175	mutex_lock(&data->gdev_mutex);
    176	if (data->open)
    177		ret = gnss_insert_raw(gdev, buf, count);
    178	mutex_unlock(&data->gdev_mutex);
    179
    180	return ret;
    181}
    182
    183static const struct serdev_device_ops sirf_serdev_ops = {
    184	.receive_buf	= sirf_receive_buf,
    185	.write_wakeup	= serdev_device_write_wakeup,
    186};
    187
    188static irqreturn_t sirf_wakeup_handler(int irq, void *dev_id)
    189{
    190	struct sirf_data *data = dev_id;
    191	struct device *dev = &data->serdev->dev;
    192	int ret;
    193
    194	ret = gpiod_get_value_cansleep(data->wakeup);
    195	dev_dbg(dev, "%s - wakeup = %d\n", __func__, ret);
    196	if (ret < 0)
    197		goto out;
    198
    199	data->active = ret;
    200	wake_up_interruptible(&data->power_wait);
    201out:
    202	return IRQ_HANDLED;
    203}
    204
    205static int sirf_wait_for_power_state_nowakeup(struct sirf_data *data,
    206						bool active,
    207						unsigned long timeout)
    208{
    209	int ret;
    210
    211	/* Wait for state change (including any shutdown messages). */
    212	msleep(timeout);
    213
    214	/* Wait for data reception or timeout. */
    215	data->active = false;
    216	ret = wait_event_interruptible_timeout(data->power_wait,
    217			data->active, msecs_to_jiffies(SIRF_REPORT_CYCLE));
    218	if (ret < 0)
    219		return ret;
    220
    221	if (ret > 0 && !active)
    222		return -ETIMEDOUT;
    223
    224	if (ret == 0 && active)
    225		return -ETIMEDOUT;
    226
    227	return 0;
    228}
    229
    230static int sirf_wait_for_power_state(struct sirf_data *data, bool active,
    231					unsigned long timeout)
    232{
    233	int ret;
    234
    235	if (!data->wakeup)
    236		return sirf_wait_for_power_state_nowakeup(data, active, timeout);
    237
    238	ret = wait_event_interruptible_timeout(data->power_wait,
    239			data->active == active, msecs_to_jiffies(timeout));
    240	if (ret < 0)
    241		return ret;
    242
    243	if (ret == 0) {
    244		dev_warn(&data->serdev->dev, "timeout waiting for active state = %d\n",
    245				active);
    246		return -ETIMEDOUT;
    247	}
    248
    249	return 0;
    250}
    251
    252static void sirf_pulse_on_off(struct sirf_data *data)
    253{
    254	gpiod_set_value_cansleep(data->on_off, 1);
    255	msleep(SIRF_ON_OFF_PULSE_TIME);
    256	gpiod_set_value_cansleep(data->on_off, 0);
    257}
    258
    259static int sirf_set_active(struct sirf_data *data, bool active)
    260{
    261	unsigned long timeout;
    262	int retries = 3;
    263	int ret;
    264
    265	if (active)
    266		timeout = SIRF_ACTIVATE_TIMEOUT;
    267	else
    268		timeout = SIRF_HIBERNATE_TIMEOUT;
    269
    270	if (!data->wakeup) {
    271		ret = sirf_serdev_open(data);
    272		if (ret)
    273			return ret;
    274	}
    275
    276	do {
    277		sirf_pulse_on_off(data);
    278		ret = sirf_wait_for_power_state(data, active, timeout);
    279	} while (ret == -ETIMEDOUT && retries--);
    280
    281	if (!data->wakeup)
    282		sirf_serdev_close(data);
    283
    284	if (ret)
    285		return ret;
    286
    287	return 0;
    288}
    289
    290static int sirf_runtime_suspend(struct device *dev)
    291{
    292	struct sirf_data *data = dev_get_drvdata(dev);
    293	int ret2;
    294	int ret;
    295
    296	if (data->on_off)
    297		ret = sirf_set_active(data, false);
    298	else
    299		ret = regulator_disable(data->vcc);
    300
    301	if (ret)
    302		return ret;
    303
    304	ret = regulator_disable(data->lna);
    305	if (ret)
    306		goto err_reenable;
    307
    308	return 0;
    309
    310err_reenable:
    311	if (data->on_off)
    312		ret2 = sirf_set_active(data, true);
    313	else
    314		ret2 = regulator_enable(data->vcc);
    315
    316	if (ret2)
    317		dev_err(dev,
    318			"failed to reenable power on failed suspend: %d\n",
    319			ret2);
    320
    321	return ret;
    322}
    323
    324static int sirf_runtime_resume(struct device *dev)
    325{
    326	struct sirf_data *data = dev_get_drvdata(dev);
    327	int ret;
    328
    329	ret = regulator_enable(data->lna);
    330	if (ret)
    331		return ret;
    332
    333	if (data->on_off)
    334		ret = sirf_set_active(data, true);
    335	else
    336		ret = regulator_enable(data->vcc);
    337
    338	if (ret)
    339		goto err_disable_lna;
    340
    341	return 0;
    342
    343err_disable_lna:
    344	regulator_disable(data->lna);
    345
    346	return ret;
    347}
    348
    349static int __maybe_unused sirf_suspend(struct device *dev)
    350{
    351	struct sirf_data *data = dev_get_drvdata(dev);
    352	int ret = 0;
    353
    354	if (!pm_runtime_suspended(dev))
    355		ret = sirf_runtime_suspend(dev);
    356
    357	if (data->wakeup)
    358		disable_irq(data->irq);
    359
    360	return ret;
    361}
    362
    363static int __maybe_unused sirf_resume(struct device *dev)
    364{
    365	struct sirf_data *data = dev_get_drvdata(dev);
    366	int ret = 0;
    367
    368	if (data->wakeup)
    369		enable_irq(data->irq);
    370
    371	if (!pm_runtime_suspended(dev))
    372		ret = sirf_runtime_resume(dev);
    373
    374	return ret;
    375}
    376
    377static const struct dev_pm_ops sirf_pm_ops = {
    378	SET_SYSTEM_SLEEP_PM_OPS(sirf_suspend, sirf_resume)
    379	SET_RUNTIME_PM_OPS(sirf_runtime_suspend, sirf_runtime_resume, NULL)
    380};
    381
    382static int sirf_parse_dt(struct serdev_device *serdev)
    383{
    384	struct sirf_data *data = serdev_device_get_drvdata(serdev);
    385	struct device_node *node = serdev->dev.of_node;
    386	u32 speed = 9600;
    387
    388	of_property_read_u32(node, "current-speed", &speed);
    389
    390	data->speed = speed;
    391
    392	return 0;
    393}
    394
    395static int sirf_probe(struct serdev_device *serdev)
    396{
    397	struct device *dev = &serdev->dev;
    398	struct gnss_device *gdev;
    399	struct sirf_data *data;
    400	int ret;
    401
    402	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
    403	if (!data)
    404		return -ENOMEM;
    405
    406	gdev = gnss_allocate_device(dev);
    407	if (!gdev)
    408		return -ENOMEM;
    409
    410	gdev->type = GNSS_TYPE_SIRF;
    411	gdev->ops = &sirf_gnss_ops;
    412	gnss_set_drvdata(gdev, data);
    413
    414	data->serdev = serdev;
    415	data->gdev = gdev;
    416
    417	mutex_init(&data->gdev_mutex);
    418	mutex_init(&data->serdev_mutex);
    419	init_waitqueue_head(&data->power_wait);
    420
    421	serdev_device_set_drvdata(serdev, data);
    422	serdev_device_set_client_ops(serdev, &sirf_serdev_ops);
    423
    424	ret = sirf_parse_dt(serdev);
    425	if (ret)
    426		goto err_put_device;
    427
    428	data->vcc = devm_regulator_get(dev, "vcc");
    429	if (IS_ERR(data->vcc)) {
    430		ret = PTR_ERR(data->vcc);
    431		goto err_put_device;
    432	}
    433
    434	data->lna = devm_regulator_get(dev, "lna");
    435	if (IS_ERR(data->lna)) {
    436		ret = PTR_ERR(data->lna);
    437		goto err_put_device;
    438	}
    439
    440	data->on_off = devm_gpiod_get_optional(dev, "sirf,onoff",
    441			GPIOD_OUT_LOW);
    442	if (IS_ERR(data->on_off)) {
    443		ret = PTR_ERR(data->on_off);
    444		goto err_put_device;
    445	}
    446
    447	if (data->on_off) {
    448		data->wakeup = devm_gpiod_get_optional(dev, "sirf,wakeup",
    449				GPIOD_IN);
    450		if (IS_ERR(data->wakeup)) {
    451			ret = PTR_ERR(data->wakeup);
    452			goto err_put_device;
    453		}
    454
    455		ret = regulator_enable(data->vcc);
    456		if (ret)
    457			goto err_put_device;
    458
    459		/* Wait for chip to boot into hibernate mode. */
    460		msleep(SIRF_BOOT_DELAY);
    461	}
    462
    463	if (data->wakeup) {
    464		ret = gpiod_get_value_cansleep(data->wakeup);
    465		if (ret < 0)
    466			goto err_disable_vcc;
    467		data->active = ret;
    468
    469		ret = gpiod_to_irq(data->wakeup);
    470		if (ret < 0)
    471			goto err_disable_vcc;
    472		data->irq = ret;
    473
    474		ret = request_threaded_irq(data->irq, NULL, sirf_wakeup_handler,
    475				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
    476				"wakeup", data);
    477		if (ret)
    478			goto err_disable_vcc;
    479	}
    480
    481	if (data->on_off) {
    482		if (!data->wakeup) {
    483			data->active = false;
    484
    485			ret = sirf_serdev_open(data);
    486			if (ret)
    487				goto err_disable_vcc;
    488
    489			msleep(SIRF_REPORT_CYCLE);
    490			sirf_serdev_close(data);
    491		}
    492
    493		/* Force hibernate mode if already active. */
    494		if (data->active) {
    495			ret = sirf_set_active(data, false);
    496			if (ret) {
    497				dev_err(dev, "failed to set hibernate mode: %d\n",
    498						ret);
    499				goto err_free_irq;
    500			}
    501		}
    502	}
    503
    504	if (IS_ENABLED(CONFIG_PM)) {
    505		pm_runtime_set_suspended(dev);	/* clear runtime_error flag */
    506		pm_runtime_enable(dev);
    507	} else {
    508		ret = sirf_runtime_resume(dev);
    509		if (ret < 0)
    510			goto err_free_irq;
    511	}
    512
    513	ret = gnss_register_device(gdev);
    514	if (ret)
    515		goto err_disable_rpm;
    516
    517	return 0;
    518
    519err_disable_rpm:
    520	if (IS_ENABLED(CONFIG_PM))
    521		pm_runtime_disable(dev);
    522	else
    523		sirf_runtime_suspend(dev);
    524err_free_irq:
    525	if (data->wakeup)
    526		free_irq(data->irq, data);
    527err_disable_vcc:
    528	if (data->on_off)
    529		regulator_disable(data->vcc);
    530err_put_device:
    531	gnss_put_device(data->gdev);
    532
    533	return ret;
    534}
    535
    536static void sirf_remove(struct serdev_device *serdev)
    537{
    538	struct sirf_data *data = serdev_device_get_drvdata(serdev);
    539
    540	gnss_deregister_device(data->gdev);
    541
    542	if (IS_ENABLED(CONFIG_PM))
    543		pm_runtime_disable(&serdev->dev);
    544	else
    545		sirf_runtime_suspend(&serdev->dev);
    546
    547	if (data->wakeup)
    548		free_irq(data->irq, data);
    549
    550	if (data->on_off)
    551		regulator_disable(data->vcc);
    552
    553	gnss_put_device(data->gdev);
    554}
    555
    556#ifdef CONFIG_OF
    557static const struct of_device_id sirf_of_match[] = {
    558	{ .compatible = "fastrax,uc430" },
    559	{ .compatible = "linx,r4" },
    560	{ .compatible = "wi2wi,w2sg0004" },
    561	{ .compatible = "wi2wi,w2sg0008i" },
    562	{ .compatible = "wi2wi,w2sg0084i" },
    563	{},
    564};
    565MODULE_DEVICE_TABLE(of, sirf_of_match);
    566#endif
    567
    568static struct serdev_device_driver sirf_driver = {
    569	.driver	= {
    570		.name		= "gnss-sirf",
    571		.of_match_table	= of_match_ptr(sirf_of_match),
    572		.pm		= &sirf_pm_ops,
    573	},
    574	.probe	= sirf_probe,
    575	.remove	= sirf_remove,
    576};
    577module_serdev_device_driver(sirf_driver);
    578
    579MODULE_AUTHOR("Johan Hovold <johan@kernel.org>");
    580MODULE_DESCRIPTION("SiRFstar GNSS receiver driver");
    581MODULE_LICENSE("GPL v2");