/*
 * 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/delay.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/irq.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 CONFIG_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 = resource_size(regs_res);
	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);
