drivers/gnss/sirf.c

Source file repositories/reference/linux-study-clean/drivers/gnss/sirf.c

File Facts

System
Linux kernel
Corpus path
drivers/gnss/sirf.c
Extension
.c
Size
12277 bytes
Lines
582
Domain
Driver Families
Bucket
drivers/gnss
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 sirf_data {
	struct gnss_device *gdev;
	struct serdev_device *serdev;
	speed_t	speed;
	struct regulator *vcc;
	struct regulator *lna;
	struct gpio_desc *on_off;
	struct gpio_desc *wakeup;
	int irq;
	bool active;

	struct mutex gdev_mutex;
	bool open;

	struct mutex serdev_mutex;
	int serdev_count;

	wait_queue_head_t power_wait;
};

static int sirf_serdev_open(struct sirf_data *data)
{
	int ret = 0;

	mutex_lock(&data->serdev_mutex);
	if (++data->serdev_count == 1) {
		ret = serdev_device_open(data->serdev);
		if (ret) {
			data->serdev_count--;
			goto out_unlock;
		}

		serdev_device_set_baudrate(data->serdev, data->speed);
		serdev_device_set_flow_control(data->serdev, false);
	}

out_unlock:
	mutex_unlock(&data->serdev_mutex);

	return ret;
}

static void sirf_serdev_close(struct sirf_data *data)
{
	mutex_lock(&data->serdev_mutex);
	if (--data->serdev_count == 0)
		serdev_device_close(data->serdev);
	mutex_unlock(&data->serdev_mutex);
}

static int sirf_open(struct gnss_device *gdev)
{
	struct sirf_data *data = gnss_get_drvdata(gdev);
	struct serdev_device *serdev = data->serdev;
	int ret;

	mutex_lock(&data->gdev_mutex);
	data->open = true;
	mutex_unlock(&data->gdev_mutex);

	ret = sirf_serdev_open(data);
	if (ret) {
		mutex_lock(&data->gdev_mutex);
		data->open = false;
		mutex_unlock(&data->gdev_mutex);
		return ret;
	}

	ret = pm_runtime_get_sync(&serdev->dev);
	if (ret < 0) {
		dev_err(&gdev->dev, "failed to runtime resume: %d\n", ret);
		pm_runtime_put_noidle(&serdev->dev);
		goto err_close;
	}

	return 0;

err_close:
	sirf_serdev_close(data);

	mutex_lock(&data->gdev_mutex);
	data->open = false;
	mutex_unlock(&data->gdev_mutex);

	return ret;
}

static void sirf_close(struct gnss_device *gdev)
{
	struct sirf_data *data = gnss_get_drvdata(gdev);

Annotation

Implementation Notes