diff options
Diffstat (limited to 'drivers/spi')
| -rw-r--r-- | drivers/spi/spi-fsl-espi.c | 1 | ||||
| -rw-r--r-- | drivers/spi/spi-fsl-lib.c | 2 | ||||
| -rw-r--r-- | drivers/spi/spi-ppc4xx.c | 1 | ||||
| -rw-r--r-- | drivers/spi/spi.c | 92 | 
4 files changed, 92 insertions, 4 deletions
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index 7523a2429d0..27bdc47b525 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -17,7 +17,6 @@  #include <linux/mm.h>  #include <linux/of.h>  #include <linux/of_platform.h> -#include <linux/of_spi.h>  #include <linux/interrupt.h>  #include <linux/err.h>  #include <sysdev/fsl_soc.h> diff --git a/drivers/spi/spi-fsl-lib.c b/drivers/spi/spi-fsl-lib.c index 2674fad7f68..1503574b215 100644 --- a/drivers/spi/spi-fsl-lib.c +++ b/drivers/spi/spi-fsl-lib.c @@ -22,7 +22,7 @@  #include <linux/dma-mapping.h>  #include <linux/mm.h>  #include <linux/of_platform.h> -#include <linux/of_spi.h> +#include <linux/spi/spi.h>  #include <sysdev/fsl_soc.h>  #include "spi-fsl-lib.h" diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c index 98ec53285fc..d95d307a110 100644 --- a/drivers/spi/spi-ppc4xx.c +++ b/drivers/spi/spi-ppc4xx.c @@ -30,7 +30,6 @@  #include <linux/errno.h>  #include <linux/wait.h>  #include <linux/of_platform.h> -#include <linux/of_spi.h>  #include <linux/of_gpio.h>  #include <linux/interrupt.h>  #include <linux/delay.h> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 3d8f662e4fe..37c555ec59a 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2,6 +2,7 @@   * SPI init/core code   *   * Copyright (C) 2005 David Brownell + * Copyright (C) 2008 Secret Lab Technologies Ltd.   *   * 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 @@ -19,15 +20,16 @@   */  #include <linux/kernel.h> +#include <linux/kmod.h>  #include <linux/device.h>  #include <linux/init.h>  #include <linux/cache.h>  #include <linux/mutex.h>  #include <linux/of_device.h> +#include <linux/of_irq.h>  #include <linux/slab.h>  #include <linux/mod_devicetable.h>  #include <linux/spi/spi.h> -#include <linux/of_spi.h>  #include <linux/pm_runtime.h>  #include <linux/export.h>  #include <linux/sched.h> @@ -798,6 +800,94 @@ err_init_queue:  /*-------------------------------------------------------------------------*/ +#if defined(CONFIG_OF) && !defined(CONFIG_SPARC) +/** + * of_register_spi_devices() - Register child devices onto the SPI bus + * @master:	Pointer to spi_master device + * + * Registers an spi_device for each child node of master node which has a 'reg' + * property. + */ +static void of_register_spi_devices(struct spi_master *master) +{ +	struct spi_device *spi; +	struct device_node *nc; +	const __be32 *prop; +	int rc; +	int len; + +	if (!master->dev.of_node) +		return; + +	for_each_child_of_node(master->dev.of_node, nc) { +		/* Alloc an spi_device */ +		spi = spi_alloc_device(master); +		if (!spi) { +			dev_err(&master->dev, "spi_device alloc error for %s\n", +				nc->full_name); +			spi_dev_put(spi); +			continue; +		} + +		/* Select device driver */ +		if (of_modalias_node(nc, spi->modalias, +				     sizeof(spi->modalias)) < 0) { +			dev_err(&master->dev, "cannot find modalias for %s\n", +				nc->full_name); +			spi_dev_put(spi); +			continue; +		} + +		/* Device address */ +		prop = of_get_property(nc, "reg", &len); +		if (!prop || len < sizeof(*prop)) { +			dev_err(&master->dev, "%s has no 'reg' property\n", +				nc->full_name); +			spi_dev_put(spi); +			continue; +		} +		spi->chip_select = be32_to_cpup(prop); + +		/* Mode (clock phase/polarity/etc.) */ +		if (of_find_property(nc, "spi-cpha", NULL)) +			spi->mode |= SPI_CPHA; +		if (of_find_property(nc, "spi-cpol", NULL)) +			spi->mode |= SPI_CPOL; +		if (of_find_property(nc, "spi-cs-high", NULL)) +			spi->mode |= SPI_CS_HIGH; + +		/* Device speed */ +		prop = of_get_property(nc, "spi-max-frequency", &len); +		if (!prop || len < sizeof(*prop)) { +			dev_err(&master->dev, "%s has no 'spi-max-frequency' property\n", +				nc->full_name); +			spi_dev_put(spi); +			continue; +		} +		spi->max_speed_hz = be32_to_cpup(prop); + +		/* IRQ */ +		spi->irq = irq_of_parse_and_map(nc, 0); + +		/* Store a pointer to the node in the device structure */ +		of_node_get(nc); +		spi->dev.of_node = nc; + +		/* Register the new device */ +		request_module(spi->modalias); +		rc = spi_add_device(spi); +		if (rc) { +			dev_err(&master->dev, "spi_device register error %s\n", +				nc->full_name); +			spi_dev_put(spi); +		} + +	} +} +#else +static void of_register_spi_devices(struct spi_master *master) { } +#endif +  static void spi_master_release(struct device *dev)  {  	struct spi_master *master;  |