/*
 * Copyright (C) 2006, 2007 Eugene Konev <ejka@openwrt.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Parts of the VLYNQ specification can be found here:
 * http://www.ti.com/litv/pdf/sprue36a
 */

#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/io.h>

#include <linux/vlynq.h>

#define VLYNQ_CTRL_PM_ENABLE		0x80000000
#define VLYNQ_CTRL_CLOCK_INT		0x00008000
#define VLYNQ_CTRL_CLOCK_DIV(x)		(((x) & 7) << 16)
#define VLYNQ_CTRL_INT_LOCAL		0x00004000
#define VLYNQ_CTRL_INT_ENABLE		0x00002000
#define VLYNQ_CTRL_INT_VECTOR(x)	(((x) & 0x1f) << 8)
#define VLYNQ_CTRL_INT2CFG		0x00000080
#define VLYNQ_CTRL_RESET		0x00000001

#define VLYNQ_CTRL_CLOCK_MASK          (0x7 << 16)

#define VLYNQ_INT_OFFSET		0x00000014
#define VLYNQ_REMOTE_OFFSET		0x00000080

#define VLYNQ_STATUS_LINK		0x00000001
#define VLYNQ_STATUS_LERROR		0x00000080
#define VLYNQ_STATUS_RERROR		0x00000100

#define VINT_ENABLE			0x00000100
#define VINT_TYPE_EDGE			0x00000080
#define VINT_LEVEL_LOW			0x00000040
#define VINT_VECTOR(x)			((x) & 0x1f)
#define VINT_OFFSET(irq)		(8 * ((irq) % 4))

#define VLYNQ_AUTONEGO_V2		0x00010000

struct vlynq_regs {
	u32 revision;
	u32 control;
	u32 status;
	u32 int_prio;
	u32 int_status;
	u32 int_pending;
	u32 int_ptr;
	u32 tx_offset;
	struct vlynq_mapping rx_mapping[4];
	u32 chip;
	u32 autonego;
	u32 unused[6];
	u32 int_device[8];
};

#ifdef VLYNQ_DEBUG
static void vlynq_dump_regs(struct vlynq_device *dev)
{
	int i;

	printk(KERN_DEBUG "VLYNQ local=%p remote=%p\n",
			dev->local, dev->remote);
	for (i = 0; i < 32; i++) {
		printk(KERN_DEBUG "VLYNQ: local %d: %08x\n",
			i + 1, ((u32 *)dev->local)[i]);
		printk(KERN_DEBUG "VLYNQ: remote %d: %08x\n",
			i + 1, ((u32 *)dev->remote)[i]);
	}
}

static void vlynq_dump_mem(u32 *base, int count)
{
	int i;

	for (i = 0; i < (count + 3) / 4; i++) {
		if (i % 4 == 0)
			printk(KERN_DEBUG "\nMEM[0x%04x]:", i * 4);
		printk(KERN_DEBUG " 0x%08x", *(base + i));
	}
	printk(KERN_DEBUG "\n");
}
#endif

/* Check the VLYNQ link status with a given device */
static int vlynq_linked(struct vlynq_device *dev)
{
	int i;

	for (i = 0; i < 100; i++)
		if (readl(&dev->local->status) & VLYNQ_STATUS_LINK)
			return 1;
		else
			cpu_relax();

	return 0;
}

static void vlynq_reset(struct vlynq_device *dev)
{
	writel(readl(&dev->local->control) | VLYNQ_CTRL_RESET,
			&dev->local->control);

	/* Wait for the devices to finish resetting */
	msleep(5);

	/* Remove reset bit */
	writel(readl(&dev->local->control) & ~VLYNQ_CTRL_RESET,
			&dev->local->control);

	/* Give some time for the devices to settle */
	msleep(5);
}

static void vlynq_irq_unmask(unsigned int irq)
{
	u32 val;
	struct vlynq_device *dev = get_irq_chip_data(irq);
	int virq;

	BUG_ON(!dev);
	virq = irq - dev->irq_start;
	val = readl(&dev->remote->int_device[virq >> 2]);
	val |= (VINT_ENABLE | virq) << VINT_OFFSET(virq);
	writel(val, &dev->remote->int_device[virq >> 2]);
}

static void vlynq_irq_mask(unsigned int irq)
{
	u32 val;
	struct vlynq_device *dev = get_irq_chip_data(irq);
	int virq;

	BUG_ON(!dev);
	virq = irq - dev->irq_start;
	val = readl(&dev->remote->int_device[virq >> 2]);
	val &= ~(VINT_ENABLE << VINT_OFFSET(virq));
	writel(val, &dev->remote->int_device[virq >> 2]);
}

static int vlynq_irq_type(unsigned int irq, unsigned int flow_type)
{
	u32 val;
	struct vlynq_device *dev = get_irq_chip_data(irq);
	int virq;

	BUG_ON(!dev);
	virq = irq - dev->irq_start;
	val = readl(&dev->remote->int_device[virq >> 2]);
	switch (flow_type & IRQ_TYPE_SENSE_MASK) {
	case IRQ_TYPE_EDGE_RISING:
	case IRQ_TYPE_EDGE_FALLING:
	case IRQ_TYPE_EDGE_BOTH:
		val |= VINT_TYPE_EDGE << VINT_OFFSET(virq);
		val &= ~(VINT_LEVEL_LOW << VINT_OFFSET(virq));
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		val &= ~(VINT_TYPE_EDGE << VINT_OFFSET(virq));
		val &= ~(VINT_LEVEL_LOW << VINT_OFFSET(virq));
		break;
	case IRQ_TYPE_LEVEL_LOW:
		val &= ~(VINT_TYPE_EDGE << VINT_OFFSET(virq));
		val |= VINT_LEVEL_LOW << VINT_OFFSET(virq);
		break;
	default:
		return -EINVAL;
	}
	writel(val, &dev->remote->int_device[virq >> 2]);
	return 0;
}

static void vlynq_local_ack(unsigned int irq)
{
	struct vlynq_device *dev = get_irq_chip_data(irq);

	u32 status = readl(&dev->local->status);

	pr_debug("%s: local status: 0x%08x\n",
		       dev_name(&dev->dev), status);
	writel(status, &dev->local->status);
}

static void vlynq_remote_ack(unsigned int irq)
{
	struct vlynq_device *dev = get_irq_chip_data(irq);

	u32 status = readl(&dev->remote->status);

	pr_debug("%s: remote status: 0x%08x\n",
		       dev_name(&dev->dev), status);
	writel(status, &dev->remote->status);
}

static irqreturn_t vlynq_irq(int irq, void *dev_id)
{
	struct vlynq_device *dev = dev_id;
	u32 status;
	int virq = 0;

	status = readl(&dev->local->int_status);
	writel(status, &dev->local->int_status);

	if (unlikely(!status))
		spurious_interrupt();

	while (status) {
		if (status & 1)
			do_IRQ(dev->irq_start + virq);
		status >>= 1;
		virq++;
	}

	return IRQ_HANDLED;
}

static struct irq_chip vlynq_irq_chip = {
	.name = "vlynq",
	.unmask = vlynq_irq_unmask,
	.mask = vlynq_irq_mask,
	.set_type = vlynq_irq_type,
};

static struct irq_chip vlynq_local_chip = {
	.name = "vlynq local error",
	.unmask = vlynq_irq_unmask,
	.mask = vlynq_irq_mask,
	.ack = vlynq_local_ack,
};

static struct irq_chip vlynq_remote_chip = {
	.name = "vlynq local error",
	.unmask = vlynq_irq_unmask,
	.mask = vlynq_irq_mask,
	.ack = vlynq_remote_ack,
};

static int vlynq_setup_irq(struct vlynq_device *dev)
{
	u32 val;
	int i, virq;

	if (dev->local_irq == dev->remote_irq) {
		printk(KERN_ERR
		       "%s: local vlynq irq should be different from remote\n",
		       dev_name(&dev->dev));
		return -EINVAL;
	}

	/* Clear local and remote error bits */
	writel(readl(&dev->local->status), &dev->local->status);
	writel(readl(&dev->remote->status), &dev->remote->status);

	/* Now setup interrupts */
	val = VLYNQ_CTRL_INT_VECTOR(dev->local_irq);
	val |= VLYNQ_CTRL_INT_ENABLE | VLYNQ_CTRL_INT_LOCAL |
		VLYNQ_CTRL_INT2CFG;
	val |= readl(&dev->local->control);
	writel(VLYNQ_INT_OFFSET, &dev->local->int_ptr);
	writel(val, &dev->local->control);

	val = VLYNQ_CTRL_INT_VECTOR(dev->remote_irq);
	val |= VLYNQ_CTRL_INT_ENABLE;
	val |= readl(&dev->remote->control);
	writel(VLYNQ_INT_OFFSET, &dev->remote->int_ptr);
	writel(val, &dev->remote->int_ptr);
	writel(val, &dev->remote->control);

	for (i = dev->irq_start; i <= dev->irq_end; i++) {
		virq = i - dev->irq_start;
		if (virq == dev->local_irq) {
			set_irq_chip_and_handler(i, &vlynq_local_chip,
						 handle_level_irq);
			set_irq_chip_data(i, dev);
		} else if (virq == dev->remote_irq) {
			set_irq_chip_and_handler(i, &vlynq_remote_chip,
						 handle_level_irq);
			set_irq_chip_data(i, dev);
		} else {
			set_irq_chip_and_handler(i, &vlynq_irq_chip,
						 handle_simple_irq);
			set_irq_chip_data(i, dev);
			writel(0, &dev->remote->int_device[virq >> 2]);
		}
	}

	if (request_irq(dev->irq, vlynq_irq, IRQF_SHARED, "vlynq", dev)) {
		printk(KERN_ERR "%s: request_irq failed\n",
					dev_name(&dev->dev));
		return -EAGAIN;
	}

	return 0;
}

static void vlynq_device_release(struct device *dev)
{
	struct vlynq_device *vdev = to_vlynq_device(dev);
	kfree(vdev);
}

static int vlynq_device_match(struct device *dev,
			      struct device_driver *drv)
{
	struct vlynq_device *vdev = to_vlynq_device(dev);
	struct vlynq_driver *vdrv = to_vlynq_driver(drv);
	struct vlynq_device_id *ids = vdrv->id_table;

	while (ids->id) {
		if (ids->id == vdev->dev_id) {
			vdev->divisor = ids->divisor;
			vlynq_set_drvdata(vdev, ids);
			printk(KERN_INFO "Driver found for VLYNQ "
				"device: %08x\n", vdev->dev_id);
			return 1;
		}
		printk(KERN_DEBUG "Not using the %08x VLYNQ device's driver"
			" for VLYNQ device: %08x\n", ids->id, vdev->dev_id);
		ids++;
	}
	return 0;
}

static int vlynq_device_probe(struct device *dev)
{
	struct vlynq_device *vdev = to_vlynq_device(dev);
	struct vlynq_driver *drv = to_vlynq_driver(dev->driver);
	struct vlynq_device_id *id = vlynq_get_drvdata(vdev);
	int result = -ENODEV;

	if (drv->probe)
		result = drv->probe(vdev, id);
	if (result)
		put_device(dev);
	return result;
}

static int vlynq_device_remove(struct device *dev)
{
	struct vlynq_driver *drv = to_vlynq_driver(dev->driver);

	if (drv->remove)
		drv->remove(to_vlynq_device(dev));

	return 0;
}

int __vlynq_register_driver(struct vlynq_driver *driver, struct module *owner)
{
	driver->driver.name = driver->name;
	driver->driver.bus = &vlynq_bus_type;
	return driver_register(&driver->driver);
}
EXPORT_SYMBOL(__vlynq_register_driver);

void vlynq_unregister_driver(struct vlynq_driver *driver)
{
	driver_unregister(&driver->driver);
}
EXPORT_SYMBOL(vlynq_unregister_driver);

/*
 * A VLYNQ remote device can clock the VLYNQ bus master
 * using a dedicated clock line. In that case, both the
 * remove device and the bus master should have the same
 * serial clock dividers configured. Iterate through the
 * 8 possible dividers until we actually link with the
 * device.
 */
static int __vlynq_try_remote(struct vlynq_device *dev)
{
	int i;

	vlynq_reset(dev);
	for (i = dev->dev_id ? vlynq_rdiv2 : vlynq_rdiv8; dev->dev_id ?
			i <= vlynq_rdiv8 : i >= vlynq_rdiv2;
		dev->dev_id ? i++ : i--) {

		if (!vlynq_linked(dev))
			break;

		writel((readl(&dev->remote->control) &
				~VLYNQ_CTRL_CLOCK_MASK) |
				VLYNQ_CTRL_CLOCK_INT |
				VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1),
				&dev->remote->control);
		writel((readl(&dev->local->control)
				& ~(VLYNQ_CTRL_CLOCK_INT |
				VLYNQ_CTRL_CLOCK_MASK)) |
				VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1),
				&dev->local->control);

		if (vlynq_linked(dev)) {
			printk(KERN_DEBUG
				"%s: using remote clock divisor %d\n",
				dev_name(&dev->dev), i - vlynq_rdiv1 + 1);
			dev->divisor = i;
			return 0;
		} else {
			vlynq_reset(dev);
		}
	}

	return -ENODEV;
}

/*
 * A VLYNQ remote device can be clocked by the VLYNQ bus
 * master using a dedicated clock line. In that case, only
 * the bus master configures the serial clock divider.
 * Iterate through the 8 possible dividers until we
 * actually get a link with the device.
 */
static int __vlynq_try_local(struct vlynq_device *dev)
{
	int i;

	vlynq_reset(dev);

	for (i = dev->dev_id ? vlynq_ldiv2 : vlynq_ldiv8; dev->dev_id ?
			i <= vlynq_ldiv8 : i >= vlynq_ldiv2;
		dev->dev_id ? i++ : i--) {

		writel((readl(&dev->local->control) &
				~VLYNQ_CTRL_CLOCK_MASK) |
				VLYNQ_CTRL_CLOCK_INT |
				VLYNQ_CTRL_CLOCK_DIV(i - vlynq_ldiv1),
				&dev->local->control);

		if (vlynq_linked(dev)) {
			printk(KERN_DEBUG
				"%s: using local clock divisor %d\n",
				dev_name(&dev->dev), i - vlynq_ldiv1 + 1);
			dev->divisor = i;
			return 0;
		} else {
			vlynq_reset(dev);
		}
	}

	return -ENODEV;
}

/*
 * When using external clocking method, serial clock
 * is supplied by an external oscillator, therefore we
 * should mask the local clock bit in the clock control
 * register for both the bus master and the remote device.
 */
static int __vlynq_try_external(struct vlynq_device *dev)
{
	vlynq_reset(dev);
	if (!vlynq_linked(dev))
		return -ENODEV;

	writel((readl(&dev->remote->control) &
			~VLYNQ_CTRL_CLOCK_INT),
			&dev->remote->control);

	writel((readl(&dev->local->control) &
			~VLYNQ_CTRL_CLOCK_INT),
			&dev->local->control);

	if (vlynq_linked(dev)) {
		printk(KERN_DEBUG "%s: using external clock\n",
			dev_name(&dev->dev));
			dev->divisor = vlynq_div_external;
		return 0;
	}

	return -ENODEV;
}

static int __vlynq_enable_device(struct vlynq_device *dev)
{
	int result;
	struct plat_vlynq_ops *ops = dev->dev.platform_data;

	result = ops->on(dev);
	if (result)
		return result;

	switch (dev->divisor) {
	case vlynq_div_external:
	case vlynq_div_auto:
		/* When the device is brought from reset it should have clock
		 * generation negotiated by hardware.
		 * Check which device is generating clocks and perform setup
		 * accordingly */
		if (vlynq_linked(dev) && readl(&dev->remote->control) &
		   VLYNQ_CTRL_CLOCK_INT) {
			if (!__vlynq_try_remote(dev) ||
				!__vlynq_try_local(dev)  ||
				!__vlynq_try_external(dev))
				return 0;
		} else {
			if (!__vlynq_try_external(dev) ||
				!__vlynq_try_local(dev)    ||
				!__vlynq_try_remote(dev))
				return 0;
		}
		break;
	case vlynq_ldiv1:
	case vlynq_ldiv2:
	case vlynq_ldiv3:
	case vlynq_ldiv4:
	case vlynq_ldiv5:
	case vlynq_ldiv6:
	case vlynq_ldiv7:
	case vlynq_ldiv8:
		writel(VLYNQ_CTRL_CLOCK_INT |
			VLYNQ_CTRL_CLOCK_DIV(dev->divisor -
			vlynq_ldiv1), &dev->local->control);
		writel(0, &dev->remote->control);
		if (vlynq_linked(dev)) {
			printk(KERN_DEBUG
				"%s: using local clock divisor %d\n",
				dev_name(&dev->dev),
				dev->divisor - vlynq_ldiv1 + 1);
			return 0;
		}
		break;
	case vlynq_rdiv1:
	case vlynq_rdiv2:
	case vlynq_rdiv3:
	case vlynq_rdiv4:
	case vlynq_rdiv5:
	case vlynq_rdiv6:
	case vlynq_rdiv7:
	case vlynq_rdiv8:
		writel(0, &dev->local->control);
		writel(VLYNQ_CTRL_CLOCK_INT |
			VLYNQ_CTRL_CLOCK_DIV(dev->divisor -
			vlynq_rdiv1), &dev->remote->control);
		if (vlynq_linked(dev)) {
			printk(KERN_DEBUG
				"%s: using remote clock divisor %d\n",
				dev_name(&dev->dev),
				dev->divisor - vlynq_rdiv1 + 1);
			return 0;
		}
		break;
	}

	ops->off(dev);
	return -ENODEV;
}

int vlynq_enable_device(struct vlynq_device *dev)
{
	struct plat_vlynq_ops *ops = dev->dev.platform_data;
	int result = -ENODEV;

	result = __vlynq_enable_device(dev);
	if (result)
		return result;

	result = vlynq_setup_irq(dev);
	if (result)
		ops->off(dev);

	dev->enabled = !result;
	return result;
}
EXPORT_SYMBOL(vlynq_enable_device);


void vlynq_disable_device(struct vlynq_device *dev)
{
	struct plat_vlynq_ops *ops = dev->dev.platform_data;

	dev->enabled = 0;
	free_irq(dev->irq, dev);
	ops->off(dev);
}
EXPORT_SYMBOL(vlynq_disable_device);

int vlynq_set_local_mapping(struct vlynq_device *dev, u32 tx_offset,
			    struct vlynq_mapping *mapping)
{
	int i;

	if (!dev->enabled)
		return -ENXIO;

	writel(tx_offset, &dev->local->tx_offset);
	for (i = 0; i < 4; i++) {
		writel(mapping[i].offset, &dev->local->rx_mapping[i].offset);
		writel(mapping[i].size, &dev->local->rx_mapping[i].size);
	}
	return 0;
}
EXPORT_SYMBOL(vlynq_set_local_mapping);

int vlynq_set_remote_mapping(struct vlynq_device *dev, u32 tx_offset,
			     struct vlynq_mapping *mapping)
{
	int i;

	if (!dev->enabled)
		return -ENXIO;

	writel(tx_offset, &dev->remote->tx_offset);
	for (i = 0; i < 4; i++) {
		writel(mapping[i].offset, &dev->remote->rx_mapping[i].offset);
		writel(mapping[i].size, &dev->remote->rx_mapping[i].size);
	}
	return 0;
}
EXPORT_SYMBOL(vlynq_set_remote_mapping);

int vlynq_set_local_irq(struct vlynq_device *dev, int virq)
{
	int irq = dev->irq_start + virq;
	if (dev->enabled)
		return -EBUSY;

	if ((irq < dev->irq_start) || (irq > dev->irq_end))
		return -EINVAL;

	if (virq == dev->remote_irq)
		return -EINVAL;

	dev->local_irq = virq;

	return 0;
}
EXPORT_SYMBOL(vlynq_set_local_irq);

int vlynq_set_remote_irq(struct vlynq_device *dev, int virq)
{
	int irq = dev->irq_start + virq;
	if (dev->enabled)
		return -EBUSY;

	if ((irq < dev->irq_start) || (irq > dev->irq_end))
		return -EINVAL;

	if (virq == dev->local_irq)
		return -EINVAL;

	dev->remote_irq = virq;

	return 0;
}
EXPORT_SYMBOL(vlynq_set_remote_irq);

static int vlynq_probe(struct platform_device *pdev)
{
	struct vlynq_device *dev;
	struct resource *regs_res, *mem_res, *irq_res;
	int len, result;

	regs_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
	if (!regs_res)
		return -ENODEV;

	mem_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem");
	if (!mem_res)
		return -ENODEV;

	irq_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "devirq");
	if (!irq_res)
		return -ENODEV;

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev) {
		printk(KERN_ERR
		       "vlynq: failed to allocate device structure\n");
		return -ENOMEM;
	}

	dev->id = pdev->id;
	dev->dev.bus = &vlynq_bus_type;
	dev->dev.parent = &pdev->dev;
	dev_set_name(&dev->dev, "vlynq%d", dev->id);
	dev->dev.platform_data = pdev->dev.platform_data;
	dev->dev.release = vlynq_device_release;

	dev->regs_start = regs_res->start;
	dev->regs_end = regs_res->end;
	dev->mem_start = mem_res->start;
	dev->mem_end = mem_res->end;

	len = regs_res->end - regs_res->start;
	if (!request_mem_region(regs_res->start, len, dev_name(&dev->dev))) {
		printk(KERN_ERR "%s: Can't request vlynq registers\n",
		       dev_name(&dev->dev));
		result = -ENXIO;
		goto fail_request;
	}

	dev->local = ioremap(regs_res->start, len);
	if (!dev->local) {
		printk(KERN_ERR "%s: Can't remap vlynq registers\n",
		       dev_name(&dev->dev));
		result = -ENXIO;
		goto fail_remap;
	}

	dev->remote = (struct vlynq_regs *)((void *)dev->local +
					    VLYNQ_REMOTE_OFFSET);

	dev->irq = platform_get_irq_byname(pdev, "irq");
	dev->irq_start = irq_res->start;
	dev->irq_end = irq_res->end;
	dev->local_irq = dev->irq_end - dev->irq_start;
	dev->remote_irq = dev->local_irq - 1;

	if (device_register(&dev->dev))
		goto fail_register;
	platform_set_drvdata(pdev, dev);

	printk(KERN_INFO "%s: regs 0x%p, irq %d, mem 0x%p\n",
	       dev_name(&dev->dev), (void *)dev->regs_start, dev->irq,
	       (void *)dev->mem_start);

	dev->dev_id = 0;
	dev->divisor = vlynq_div_auto;
	result = __vlynq_enable_device(dev);
	if (result == 0) {
		dev->dev_id = readl(&dev->remote->chip);
		((struct plat_vlynq_ops *)(dev->dev.platform_data))->off(dev);
	}
	if (dev->dev_id)
		printk(KERN_INFO "Found a VLYNQ device: %08x\n", dev->dev_id);

	return 0;

fail_register:
	iounmap(dev->local);
fail_remap:
fail_request:
	release_mem_region(regs_res->start, len);
	kfree(dev);
	return result;
}

static int vlynq_remove(struct platform_device *pdev)
{
	struct vlynq_device *dev = platform_get_drvdata(pdev);

	device_unregister(&dev->dev);
	iounmap(dev->local);
	release_mem_region(dev->regs_start, dev->regs_end - dev->regs_start);

	kfree(dev);

	return 0;
}

static struct platform_driver vlynq_platform_driver = {
	.driver.name = "vlynq",
	.probe = vlynq_probe,
	.remove = __devexit_p(vlynq_remove),
};

struct bus_type vlynq_bus_type = {
	.name = "vlynq",
	.match = vlynq_device_match,
	.probe = vlynq_device_probe,
	.remove = vlynq_device_remove,
};
EXPORT_SYMBOL(vlynq_bus_type);

static int __devinit vlynq_init(void)
{
	int res = 0;

	res = bus_register(&vlynq_bus_type);
	if (res)
		goto fail_bus;

	res = platform_driver_register(&vlynq_platform_driver);
	if (res)
		goto fail_platform;

	return 0;

fail_platform:
	bus_unregister(&vlynq_bus_type);
fail_bus:
	return res;
}

static void __devexit vlynq_exit(void)
{
	platform_driver_unregister(&vlynq_platform_driver);
	bus_unregister(&vlynq_bus_type);
}

module_init(vlynq_init);
module_exit(vlynq_exit);
