// 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 struct bus_type siox_bus_type = {
	.name = "siox",
	.match = siox_match,
};

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

	ret = sdriver->probe(sdevice);
	return ret;
}

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

	ret = sdriver->remove(sdevice);
	return ret;
}

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

	sdriver->shutdown(sdevice);
}

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->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;

	if (sdriver->probe)
		sdriver->driver.probe = siox_driver_probe;
	if (sdriver->remove)
		sdriver->driver.remove = siox_driver_remove;
	if (sdriver->shutdown)
		sdriver->driver.shutdown = siox_driver_shutdown;

	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");
