// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2015-2017 Pengutronix, Uwe Kleine-König <kernel@pengutronix.de>
 */
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/sysfs.h>

#include "siox.h"

/*
 * The lowest bit in the SIOX status word signals if the in-device watchdog is
 * ok. If the bit is set, the device is functional.
 *
 * On writing the watchdog timer is reset when this bit toggles.
 */
#define SIOX_STATUS_WDG			0x01

/*
 * Bits 1 to 3 of the status word read as the bitwise negation of what was
 * clocked in before. The value clocked in is changed in each cycle and so
 * allows to detect transmit/receive problems.
 */
#define SIOX_STATUS_COUNTER		0x0e

/*
 * Each Siox-Device has a 4 bit type number that is neither 0 nor 15. This is
 * available in the upper nibble of the read status.
 *
 * On write these bits are DC.
 */
#define SIOX_STATUS_TYPE		0xf0

#define CREATE_TRACE_POINTS
#include <trace/events/siox.h>

static bool siox_is_registered;

static void siox_master_lock(struct siox_master *smaster)
{
	mutex_lock(&smaster->lock);
}

static void siox_master_unlock(struct siox_master *smaster)
{
	mutex_unlock(&smaster->lock);
}

static inline u8 siox_status_clean(u8 status_read, u8 status_written)
{
	/*
	 * bits 3:1 of status sample the respective bit in the status
	 * byte written in the previous cycle but inverted. So if you wrote the
	 * status word as 0xa before (counter = 0b101), it is expected to get
	 * back the counter bits as 0b010.
	 *
	 * So given the last status written this function toggles the there
	 * unset counter bits in the read value such that the counter bits in
	 * the return value are all zero iff the bits were read as expected to
	 * simplify error detection.
	 */

	return status_read ^ (~status_written & 0xe);
}

static bool siox_device_counter_error(struct siox_device *sdevice,
				      u8 status_clean)
{
	return (status_clean & SIOX_STATUS_COUNTER) != 0;
}

static bool siox_device_type_error(struct siox_device *sdevice, u8 status_clean)
{
	u8 statustype = (status_clean & SIOX_STATUS_TYPE) >> 4;

	/*
	 * If the device knows which value the type bits should have, check
	 * against this value otherwise just rule out the invalid values 0b0000
	 * and 0b1111.
	 */
	if (sdevice->statustype) {
		if (statustype != sdevice->statustype)
			return true;
	} else {
		switch (statustype) {
		case 0:
		case 0xf:
			return true;
		}
	}

	return false;
}

static bool siox_device_wdg_error(struct siox_device *sdevice, u8 status_clean)
{
	return (status_clean & SIOX_STATUS_WDG) == 0;
}

/*
 * If there is a type or counter error the device is called "unsynced".
 */
bool siox_device_synced(struct siox_device *sdevice)
{
	if (siox_device_type_error(sdevice, sdevice->status_read_clean))
		return false;

	return !siox_device_counter_error(sdevice, sdevice->status_read_clean);

}
EXPORT_SYMBOL_GPL(siox_device_synced);

/*
 * A device is called "connected" if it is synced and the watchdog is not
 * asserted.
 */
bool siox_device_connected(struct siox_device *sdevice)
{
	if (!siox_device_synced(sdevice))
		return false;

	return !siox_device_wdg_error(sdevice, sdevice->status_read_clean);
}
EXPORT_SYMBOL_GPL(siox_device_connected);

static void siox_poll(struct siox_master *smaster)
{
	struct siox_device *sdevice;
	size_t i = smaster->setbuf_len;
	unsigned int devno = 0;
	int unsync_error = 0;

	smaster->last_poll = jiffies;

	/*
	 * The counter bits change in each second cycle, the watchdog bit
	 * toggles each time.
	 * The counter bits hold values from [0, 6]. 7 would be possible
	 * theoretically but the protocol designer considered that a bad idea
	 * for reasons unknown today. (Maybe that's because then the status read
	 * back has only zeros in the counter bits then which might be confused
	 * with a stuck-at-0 error. But for the same reason (with s/0/1/) 0
	 * could be skipped.)
	 */
	if (++smaster->status > 0x0d)
		smaster->status = 0;

	memset(smaster->buf, 0, smaster->setbuf_len);

	/* prepare data pushed out to devices in buf[0..setbuf_len) */
	list_for_each_entry(sdevice, &smaster->devices, node) {
		struct siox_driver *sdriver =
			to_siox_driver(sdevice->dev.driver);
		sdevice->status_written = smaster->status;

		i -= sdevice->inbytes;

		/*
		 * If the device or a previous one is unsynced, don't pet the
		 * watchdog. This is done to ensure that the device is kept in
		 * reset when something is wrong.
		 */
		if (!siox_device_synced(sdevice))
			unsync_error = 1;

		if (sdriver && !unsync_error)
			sdriver->set_data(sdevice, sdevice->status_written,
					  &smaster->buf[i + 1]);
		else
			/*
			 * Don't trigger watchdog if there is no driver or a
			 * sync problem
			 */
			sdevice->status_written &= ~SIOX_STATUS_WDG;

		smaster->buf[i] = sdevice->status_written;

		trace_siox_set_data(smaster, sdevice, devno, i);

		devno++;
	}

	smaster->pushpull(smaster, smaster->setbuf_len, smaster->buf,
			  smaster->getbuf_len,
			  smaster->buf + smaster->setbuf_len);

	unsync_error = 0;

	/* interpret data pulled in from devices in buf[setbuf_len..] */
	devno = 0;
	i = smaster->setbuf_len;
	list_for_each_entry(sdevice, &smaster->devices, node) {
		struct siox_driver *sdriver =
			to_siox_driver(sdevice->dev.driver);
		u8 status = smaster->buf[i + sdevice->outbytes - 1];
		u8 status_clean;
		u8 prev_status_clean = sdevice->status_read_clean;
		bool synced = true;
		bool connected = true;

		if (!siox_device_synced(sdevice))
			unsync_error = 1;

		/*
		 * If the watchdog bit wasn't toggled in this cycle, report the
		 * watchdog as active to give a consistent view for drivers and
		 * sysfs consumers.
		 */
		if (!sdriver || unsync_error)
			status &= ~SIOX_STATUS_WDG;

		status_clean =
			siox_status_clean(status,
					  sdevice->status_written_lastcycle);

		/* Check counter and type bits */
		if (siox_device_counter_error(sdevice, status_clean) ||
		    siox_device_type_error(sdevice, status_clean)) {
			bool prev_error;

			synced = false;

			/* only report a new error if the last cycle was ok */
			prev_error =
				siox_device_counter_error(sdevice,
							  prev_status_clean) ||
				siox_device_type_error(sdevice,
						       prev_status_clean);

			if (!prev_error) {
				sdevice->status_errors++;
				sysfs_notify_dirent(sdevice->status_errors_kn);
			}
		}

		/* If the device is unsynced report the watchdog as active */
		if (!synced) {
			status &= ~SIOX_STATUS_WDG;
			status_clean &= ~SIOX_STATUS_WDG;
		}

		if (siox_device_wdg_error(sdevice, status_clean))
			connected = false;

		/* The watchdog state changed just now */
		if ((status_clean ^ prev_status_clean) & SIOX_STATUS_WDG) {
			sysfs_notify_dirent(sdevice->watchdog_kn);

			if (siox_device_wdg_error(sdevice, status_clean)) {
				struct kernfs_node *wd_errs =
					sdevice->watchdog_errors_kn;

				sdevice->watchdog_errors++;
				sysfs_notify_dirent(wd_errs);
			}
		}

		if (connected != sdevice->connected)
			sysfs_notify_dirent(sdevice->connected_kn);

		sdevice->status_read_clean = status_clean;
		sdevice->status_written_lastcycle = sdevice->status_written;
		sdevice->connected = connected;

		trace_siox_get_data(smaster, sdevice, devno, status_clean, i);

		/* only give data read to driver if the device is connected */
		if (sdriver && connected)
			sdriver->get_data(sdevice, &smaster->buf[i]);

		devno++;
		i += sdevice->outbytes;
	}
}

static int siox_poll_thread(void *data)
{
	struct siox_master *smaster = data;
	signed long timeout = 0;

	get_device(&smaster->dev);

	for (;;) {
		if (kthread_should_stop()) {
			put_device(&smaster->dev);
			return 0;
		}

		siox_master_lock(smaster);

		if (smaster->active) {
			unsigned long next_poll =
				smaster->last_poll + smaster->poll_interval;
			if (time_is_before_eq_jiffies(next_poll))
				siox_poll(smaster);

			timeout = smaster->poll_interval -
				(jiffies - smaster->last_poll);
		} else {
			timeout = MAX_SCHEDULE_TIMEOUT;
		}

		/*
		 * Set the task to idle while holding the lock. This makes sure
		 * that we don't sleep too long when the bus is reenabled before
		 * schedule_timeout is reached.
		 */
		if (timeout > 0)
			set_current_state(TASK_IDLE);

		siox_master_unlock(smaster);

		if (timeout > 0)
			schedule_timeout(timeout);

		/*
		 * I'm not clear if/why it is important to set the state to
		 * RUNNING again, but it fixes a "do not call blocking ops when
		 * !TASK_RUNNING;"-warning.
		 */
		set_current_state(TASK_RUNNING);
	}
}

static int __siox_start(struct siox_master *smaster)
{
	if (!(smaster->setbuf_len + smaster->getbuf_len))
		return -ENODEV;

	if (!smaster->buf)
		return -ENOMEM;

	if (smaster->active)
		return 0;

	smaster->active = 1;
	wake_up_process(smaster->poll_thread);

	return 1;
}

static int siox_start(struct siox_master *smaster)
{
	int ret;

	siox_master_lock(smaster);
	ret = __siox_start(smaster);
	siox_master_unlock(smaster);

	return ret;
}

static int __siox_stop(struct siox_master *smaster)
{
	if (smaster->active) {
		struct siox_device *sdevice;

		smaster->active = 0;

		list_for_each_entry(sdevice, &smaster->devices, node) {
			if (sdevice->connected)
				sysfs_notify_dirent(sdevice->connected_kn);
			sdevice->connected = false;
		}

		return 1;
	}
	return 0;
}

static int siox_stop(struct siox_master *smaster)
{
	int ret;

	siox_master_lock(smaster);
	ret = __siox_stop(smaster);
	siox_master_unlock(smaster);

	return ret;
}

static ssize_t type_show(struct device *dev,
			 struct device_attribute *attr, char *buf)
{
	struct siox_device *sdev = to_siox_device(dev);

	return sprintf(buf, "%s\n", sdev->type);
}

static DEVICE_ATTR_RO(type);

static ssize_t inbytes_show(struct device *dev,
			    struct device_attribute *attr, char *buf)
{
	struct siox_device *sdev = to_siox_device(dev);

	return sprintf(buf, "%zu\n", sdev->inbytes);
}

static DEVICE_ATTR_RO(inbytes);

static ssize_t outbytes_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	struct siox_device *sdev = to_siox_device(dev);

	return sprintf(buf, "%zu\n", sdev->outbytes);
}

static DEVICE_ATTR_RO(outbytes);

static ssize_t status_errors_show(struct device *dev,
				  struct device_attribute *attr, char *buf)
{
	struct siox_device *sdev = to_siox_device(dev);
	unsigned int status_errors;

	siox_master_lock(sdev->smaster);

	status_errors = sdev->status_errors;

	siox_master_unlock(sdev->smaster);

	return sprintf(buf, "%u\n", status_errors);
}

static DEVICE_ATTR_RO(status_errors);

static ssize_t connected_show(struct device *dev,
			      struct device_attribute *attr, char *buf)
{
	struct siox_device *sdev = to_siox_device(dev);
	bool connected;

	siox_master_lock(sdev->smaster);

	connected = sdev->connected;

	siox_master_unlock(sdev->smaster);

	return sprintf(buf, "%u\n", connected);
}

static DEVICE_ATTR_RO(connected);

static ssize_t watchdog_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	struct siox_device *sdev = to_siox_device(dev);
	u8 status;

	siox_master_lock(sdev->smaster);

	status = sdev->status_read_clean;

	siox_master_unlock(sdev->smaster);

	return sprintf(buf, "%d\n", status & SIOX_STATUS_WDG);
}

static DEVICE_ATTR_RO(watchdog);

static ssize_t watchdog_errors_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	struct siox_device *sdev = to_siox_device(dev);
	unsigned int watchdog_errors;

	siox_master_lock(sdev->smaster);

	watchdog_errors = sdev->watchdog_errors;

	siox_master_unlock(sdev->smaster);

	return sprintf(buf, "%u\n", watchdog_errors);
}

static DEVICE_ATTR_RO(watchdog_errors);

static struct attribute *siox_device_attrs[] = {
	&dev_attr_type.attr,
	&dev_attr_inbytes.attr,
	&dev_attr_outbytes.attr,
	&dev_attr_status_errors.attr,
	&dev_attr_connected.attr,
	&dev_attr_watchdog.attr,
	&dev_attr_watchdog_errors.attr,
	NULL
};
ATTRIBUTE_GROUPS(siox_device);

static void siox_device_release(struct device *dev)
{
	struct siox_device *sdevice = to_siox_device(dev);

	kfree(sdevice);
}

static struct device_type siox_device_type = {
	.groups = siox_device_groups,
	.release = siox_device_release,
};

static int siox_match(struct device *dev, struct device_driver *drv)
{
	if (dev->type != &siox_device_type)
		return 0;

	/* up to now there is only a single driver so keeping this simple */
	return 1;
}

static int siox_probe(struct device *dev)
{
	struct siox_driver *sdriver = to_siox_driver(dev->driver);
	struct siox_device *sdevice = to_siox_device(dev);

	return sdriver->probe(sdevice);
}

static void siox_remove(struct device *dev)
{
	struct siox_driver *sdriver =
		container_of(dev->driver, struct siox_driver, driver);
	struct siox_device *sdevice = to_siox_device(dev);

	if (sdriver->remove)
		sdriver->remove(sdevice);
}

static void siox_shutdown(struct device *dev)
{
	struct siox_device *sdevice = to_siox_device(dev);
	struct siox_driver *sdriver;

	if (!dev->driver)
		return;

	sdriver = container_of(dev->driver, struct siox_driver, driver);
	if (sdriver->shutdown)
		sdriver->shutdown(sdevice);
}

static struct bus_type siox_bus_type = {
	.name = "siox",
	.match = siox_match,
	.probe = siox_probe,
	.remove = siox_remove,
	.shutdown = siox_shutdown,
};

static ssize_t active_show(struct device *dev,
			   struct device_attribute *attr, char *buf)
{
	struct siox_master *smaster = to_siox_master(dev);

	return sprintf(buf, "%d\n", smaster->active);
}

static ssize_t active_store(struct device *dev,
			    struct device_attribute *attr,
			    const char *buf, size_t count)
{
	struct siox_master *smaster = to_siox_master(dev);
	int ret;
	int active;

	ret = kstrtoint(buf, 0, &active);
	if (ret < 0)
		return ret;

	if (active)
		ret = siox_start(smaster);
	else
		ret = siox_stop(smaster);

	if (ret < 0)
		return ret;

	return count;
}

static DEVICE_ATTR_RW(active);

static struct siox_device *siox_device_add(struct siox_master *smaster,
					   const char *type, size_t inbytes,
					   size_t outbytes, u8 statustype);

static ssize_t device_add_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct siox_master *smaster = to_siox_master(dev);
	int ret;
	char type[20] = "";
	size_t inbytes = 0, outbytes = 0;
	u8 statustype = 0;

	ret = sscanf(buf, "%19s %zu %zu %hhu", type, &inbytes,
		     &outbytes, &statustype);
	if (ret != 3 && ret != 4)
		return -EINVAL;

	if (strcmp(type, "siox-12x8") || inbytes != 2 || outbytes != 4)
		return -EINVAL;

	siox_device_add(smaster, "siox-12x8", inbytes, outbytes, statustype);

	return count;
}

static DEVICE_ATTR_WO(device_add);

static void siox_device_remove(struct siox_master *smaster);

static ssize_t device_remove_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t count)
{
	struct siox_master *smaster = to_siox_master(dev);

	/* XXX? require to write <type> <inbytes> <outbytes> */
	siox_device_remove(smaster);

	return count;
}

static DEVICE_ATTR_WO(device_remove);

static ssize_t poll_interval_ns_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
{
	struct siox_master *smaster = to_siox_master(dev);

	return sprintf(buf, "%lld\n", jiffies_to_nsecs(smaster->poll_interval));
}

static ssize_t poll_interval_ns_store(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf, size_t count)
{
	struct siox_master *smaster = to_siox_master(dev);
	int ret;
	u64 val;

	ret = kstrtou64(buf, 0, &val);
	if (ret < 0)
		return ret;

	siox_master_lock(smaster);

	smaster->poll_interval = nsecs_to_jiffies(val);

	siox_master_unlock(smaster);

	return count;
}

static DEVICE_ATTR_RW(poll_interval_ns);

static struct attribute *siox_master_attrs[] = {
	&dev_attr_active.attr,
	&dev_attr_device_add.attr,
	&dev_attr_device_remove.attr,
	&dev_attr_poll_interval_ns.attr,
	NULL
};
ATTRIBUTE_GROUPS(siox_master);

static void siox_master_release(struct device *dev)
{
	struct siox_master *smaster = to_siox_master(dev);

	kfree(smaster);
}

static struct device_type siox_master_type = {
	.groups = siox_master_groups,
	.release = siox_master_release,
};

struct siox_master *siox_master_alloc(struct device *dev,
				      size_t size)
{
	struct siox_master *smaster;

	if (!dev)
		return NULL;

	smaster = kzalloc(sizeof(*smaster) + size, GFP_KERNEL);
	if (!smaster)
		return NULL;

	device_initialize(&smaster->dev);

	smaster->busno = -1;
	smaster->dev.bus = &siox_bus_type;
	smaster->dev.type = &siox_master_type;
	smaster->dev.parent = dev;
	smaster->poll_interval = DIV_ROUND_UP(HZ, 40);

	dev_set_drvdata(&smaster->dev, &smaster[1]);

	return smaster;
}
EXPORT_SYMBOL_GPL(siox_master_alloc);

int siox_master_register(struct siox_master *smaster)
{
	int ret;

	if (!siox_is_registered)
		return -EPROBE_DEFER;

	if (!smaster->pushpull)
		return -EINVAL;

	dev_set_name(&smaster->dev, "siox-%d", smaster->busno);

	mutex_init(&smaster->lock);
	INIT_LIST_HEAD(&smaster->devices);

	smaster->last_poll = jiffies;
	smaster->poll_thread = kthread_run(siox_poll_thread, smaster,
					   "siox-%d", smaster->busno);
	if (IS_ERR(smaster->poll_thread)) {
		smaster->active = 0;
		return PTR_ERR(smaster->poll_thread);
	}

	ret = device_add(&smaster->dev);
	if (ret)
		kthread_stop(smaster->poll_thread);

	return ret;
}
EXPORT_SYMBOL_GPL(siox_master_register);

void siox_master_unregister(struct siox_master *smaster)
{
	/* remove device */
	device_del(&smaster->dev);

	siox_master_lock(smaster);

	__siox_stop(smaster);

	while (smaster->num_devices) {
		struct siox_device *sdevice;

		sdevice = container_of(smaster->devices.prev,
				       struct siox_device, node);
		list_del(&sdevice->node);
		smaster->num_devices--;

		siox_master_unlock(smaster);

		device_unregister(&sdevice->dev);

		siox_master_lock(smaster);
	}

	siox_master_unlock(smaster);

	put_device(&smaster->dev);
}
EXPORT_SYMBOL_GPL(siox_master_unregister);

static struct siox_device *siox_device_add(struct siox_master *smaster,
					   const char *type, size_t inbytes,
					   size_t outbytes, u8 statustype)
{
	struct siox_device *sdevice;
	int ret;
	size_t buf_len;

	sdevice = kzalloc(sizeof(*sdevice), GFP_KERNEL);
	if (!sdevice)
		return ERR_PTR(-ENOMEM);

	sdevice->type = type;
	sdevice->inbytes = inbytes;
	sdevice->outbytes = outbytes;
	sdevice->statustype = statustype;

	sdevice->smaster = smaster;
	sdevice->dev.parent = &smaster->dev;
	sdevice->dev.bus = &siox_bus_type;
	sdevice->dev.type = &siox_device_type;

	siox_master_lock(smaster);

	dev_set_name(&sdevice->dev, "siox-%d-%d",
		     smaster->busno, smaster->num_devices);

	buf_len = smaster->setbuf_len + inbytes +
		smaster->getbuf_len + outbytes;
	if (smaster->buf_len < buf_len) {
		u8 *buf = krealloc(smaster->buf, buf_len, GFP_KERNEL);

		if (!buf) {
			dev_err(&smaster->dev,
				"failed to realloc buffer to %zu\n", buf_len);
			ret = -ENOMEM;
			goto err_buf_alloc;
		}

		smaster->buf_len = buf_len;
		smaster->buf = buf;
	}

	ret = device_register(&sdevice->dev);
	if (ret) {
		dev_err(&smaster->dev, "failed to register device: %d\n", ret);

		goto err_device_register;
	}

	smaster->num_devices++;
	list_add_tail(&sdevice->node, &smaster->devices);

	smaster->setbuf_len += sdevice->inbytes;
	smaster->getbuf_len += sdevice->outbytes;

	sdevice->status_errors_kn = sysfs_get_dirent(sdevice->dev.kobj.sd,
						     "status_errors");
	sdevice->watchdog_kn = sysfs_get_dirent(sdevice->dev.kobj.sd,
						"watchdog");
	sdevice->watchdog_errors_kn = sysfs_get_dirent(sdevice->dev.kobj.sd,
						       "watchdog_errors");
	sdevice->connected_kn = sysfs_get_dirent(sdevice->dev.kobj.sd,
						 "connected");

	siox_master_unlock(smaster);

	return sdevice;

err_device_register:
	/* don't care to make the buffer smaller again */

err_buf_alloc:
	siox_master_unlock(smaster);

	kfree(sdevice);

	return ERR_PTR(ret);
}

static void siox_device_remove(struct siox_master *smaster)
{
	struct siox_device *sdevice;

	siox_master_lock(smaster);

	if (!smaster->num_devices) {
		siox_master_unlock(smaster);
		return;
	}

	sdevice = container_of(smaster->devices.prev, struct siox_device, node);
	list_del(&sdevice->node);
	smaster->num_devices--;

	smaster->setbuf_len -= sdevice->inbytes;
	smaster->getbuf_len -= sdevice->outbytes;

	if (!smaster->num_devices)
		__siox_stop(smaster);

	siox_master_unlock(smaster);

	/*
	 * This must be done without holding the master lock because we're
	 * called from device_remove_store which also holds a sysfs mutex.
	 * device_unregister tries to aquire the same lock.
	 */
	device_unregister(&sdevice->dev);
}

int __siox_driver_register(struct siox_driver *sdriver, struct module *owner)
{
	int ret;

	if (unlikely(!siox_is_registered))
		return -EPROBE_DEFER;

	if (!sdriver->probe ||
	    (!sdriver->set_data && !sdriver->get_data)) {
		pr_err("Driver %s doesn't provide needed callbacks\n",
		       sdriver->driver.name);
		return -EINVAL;
	}

	sdriver->driver.owner = owner;
	sdriver->driver.bus = &siox_bus_type;

	ret = driver_register(&sdriver->driver);
	if (ret)
		pr_err("Failed to register siox driver %s (%d)\n",
		       sdriver->driver.name, ret);

	return ret;
}
EXPORT_SYMBOL_GPL(__siox_driver_register);

static int __init siox_init(void)
{
	int ret;

	ret = bus_register(&siox_bus_type);
	if (ret) {
		pr_err("Registration of SIOX bus type failed: %d\n", ret);
		return ret;
	}

	siox_is_registered = true;

	return 0;
}
subsys_initcall(siox_init);

static void __exit siox_exit(void)
{
	bus_unregister(&siox_bus_type);
}
module_exit(siox_exit);

MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
MODULE_DESCRIPTION("Eckelmann SIOX driver core");
MODULE_LICENSE("GPL v2");
