/*
 * Xilinx SPI OF device driver
 *
 * Copyright (c) 2009 Intel Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* Supports:
 * Xilinx SPI devices as OF devices
 *
 * Inspired by xilinx_spi.c, 2002-2007 (c) MontaVista Software, Inc.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/slab.h>

#include <linux/of_platform.h>
#include <linux/of_device.h>
#include <linux/of_spi.h>

#include <linux/spi/xilinx_spi.h>
#include "xilinx_spi.h"


static int __devinit xilinx_spi_of_probe(struct of_device *ofdev,
	const struct of_device_id *match)
{
	struct spi_master *master;
	struct xspi_platform_data *pdata;
	struct resource r_mem;
	struct resource r_irq;
	int rc = 0;
	const u32 *prop;
	int len;

	rc = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem);
	if (rc) {
		dev_warn(&ofdev->dev, "invalid address\n");
		return rc;
	}

	rc = of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq);
	if (rc == NO_IRQ) {
		dev_warn(&ofdev->dev, "no IRQ found\n");
		return -ENODEV;
	}

	ofdev->dev.platform_data =
		kzalloc(sizeof(struct xspi_platform_data), GFP_KERNEL);
	pdata = ofdev->dev.platform_data;
	if (!pdata)
		return -ENOMEM;

	/* number of slave select bits is required */
	prop = of_get_property(ofdev->dev.of_node, "xlnx,num-ss-bits", &len);
	if (!prop || len < sizeof(*prop)) {
		dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n");
		return -EINVAL;
	}
	pdata->num_chipselect = *prop;
	pdata->bits_per_word = 8;
	master = xilinx_spi_init(&ofdev->dev, &r_mem, r_irq.start, -1);
	if (!master)
		return -ENODEV;

	dev_set_drvdata(&ofdev->dev, master);

	/* Add any subnodes on the SPI bus */
	of_register_spi_devices(master, ofdev->dev.of_node);

	return 0;
}

static int __devexit xilinx_spi_remove(struct of_device *ofdev)
{
	xilinx_spi_deinit(dev_get_drvdata(&ofdev->dev));
	dev_set_drvdata(&ofdev->dev, 0);
	kfree(ofdev->dev.platform_data);
	ofdev->dev.platform_data = NULL;
	return 0;
}

static int __exit xilinx_spi_of_remove(struct of_device *op)
{
	return xilinx_spi_remove(op);
}

static const struct of_device_id xilinx_spi_of_match[] = {
	{ .compatible = "xlnx,xps-spi-2.00.a", },
	{ .compatible = "xlnx,xps-spi-2.00.b", },
	{}
};

MODULE_DEVICE_TABLE(of, xilinx_spi_of_match);

static struct of_platform_driver xilinx_spi_of_driver = {
	.probe = xilinx_spi_of_probe,
	.remove = __exit_p(xilinx_spi_of_remove),
	.driver = {
		.name = "xilinx-xps-spi",
		.owner = THIS_MODULE,
		.of_match_table = xilinx_spi_of_match,
	},
};

static int __init xilinx_spi_of_init(void)
{
	return of_register_platform_driver(&xilinx_spi_of_driver);
}
module_init(xilinx_spi_of_init);

static void __exit xilinx_spi_of_exit(void)
{
	of_unregister_platform_driver(&xilinx_spi_of_driver);
}
module_exit(xilinx_spi_of_exit);

MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
MODULE_DESCRIPTION("Xilinx SPI platform driver");
MODULE_LICENSE("GPL v2");
