From d57a4282d04810417c4ed2a49cbbeda8b3569b18 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 7 Apr 2012 14:16:53 -0600 Subject: spi/devicetree: Move devicetree support code into spi directory The SPI device tree support code isn't shared by any other subsystem. It can be moved into the core drivers/spi directory and the exported symbol can be removed. Signed-off-by: Grant Likely Cc: Rob Herring --- drivers/spi/spi.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) (limited to 'drivers/spi/spi.c') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 3d8f662e4fe9..37c555ec59ab 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 +#include #include #include #include #include #include +#include #include #include #include -#include #include #include #include @@ -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; -- cgit v1.2.3 From 7dfd2bd70228d1f8d468d58cb3d12ecd618479ed Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Thu, 10 May 2012 19:20:41 +0530 Subject: spi: Dont call prepare/unprepare transfer if not populated Currently the prepare/unprepare transfer are called unconditionally. The assumption is that every driver using the spi core queue infrastructure has to populate the prepare and unprepare functions. This encourages drivers to populate empty functions to prevent crashing. This patch prevents the call to prepare/unprepare if not populated. Signed-off-by: Shubhrajyoti D Acked-by: Linus Walleij [grant.likely: fix whitespace defect] Signed-off-by: Grant Likely --- drivers/spi/spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/spi/spi.c') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 37c555ec59ab..2d65b1684cdc 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -532,7 +532,7 @@ static void spi_pump_messages(struct kthread_work *work) /* Lock queue and check for queue work */ spin_lock_irqsave(&master->queue_lock, flags); if (list_empty(&master->queue) || !master->running) { - if (master->busy) { + if (master->busy && master->unprepare_transfer_hardware) { ret = master->unprepare_transfer_hardware(master); if (ret) { spin_unlock_irqrestore(&master->queue_lock, flags); @@ -562,7 +562,7 @@ static void spi_pump_messages(struct kthread_work *work) master->busy = true; spin_unlock_irqrestore(&master->queue_lock, flags); - if (!was_busy) { + if (!was_busy && master->prepare_transfer_hardware) { ret = master->prepare_transfer_hardware(master); if (ret) { dev_err(&master->dev, -- cgit v1.2.3 From 1e8a52e18cfb381bc9cc1f0b720540364d2a6edd Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 19 May 2012 23:42:08 -0600 Subject: spi: By default setup spi_masters with 1 chipselect and dynamics bus number Trivial simplification. Instead of requiring spi master drivers to always set the bus number (even when a dynamic number is desired), this patch modifies spi_alloc_master() to initialize num_chipselect to 1 (because there will always be at least one CS) and bus_num to -1 for dynamic allocation. This simplifies the code needed to be written for drivers. Signed-off-by: Grant Likely --- drivers/spi/spi-ath79.c | 3 --- drivers/spi/spi-lm70llp.c | 3 --- drivers/spi/spi-mpc52xx.c | 3 --- drivers/spi/spi-ppc4xx.c | 3 --- drivers/spi/spi-topcliff-pch.c | 1 - drivers/spi/spi.c | 2 ++ 6 files changed, 2 insertions(+), 13 deletions(-) (limited to 'drivers/spi/spi.c') diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index acc88b4d2869..249077e5cc48 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c @@ -216,9 +216,6 @@ static __devinit int ath79_spi_probe(struct platform_device *pdev) if (pdata) { master->bus_num = pdata->bus_num; master->num_chipselect = pdata->num_chipselect; - } else { - master->bus_num = -1; - master->num_chipselect = 1; } sp->bitbang.master = spi_master_get(master); diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c index 933eb9d9ddd4..0759b5db9883 100644 --- a/drivers/spi/spi-lm70llp.c +++ b/drivers/spi/spi-lm70llp.c @@ -219,9 +219,6 @@ static void spi_lm70llp_attach(struct parport *p) } pp = spi_master_get_devdata(master); - master->bus_num = -1; /* dynamic alloc of a bus number */ - master->num_chipselect = 1; - /* * SPI and bitbang hookup. */ diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index 57633d963456..cb3a3830b0a5 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -433,7 +433,6 @@ static int __devinit mpc52xx_spi_probe(struct platform_device *op) goto err_alloc; } - master->bus_num = -1; master->setup = mpc52xx_spi_setup; master->transfer = mpc52xx_spi_transfer; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; @@ -479,8 +478,6 @@ static int __devinit mpc52xx_spi_probe(struct platform_device *op) gpio_direction_output(gpio_cs, 1); ms->gpio_cs[i] = gpio_cs; } - } else { - master->num_chipselect = 1; } spin_lock_init(&ms->lock); diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c index d95d307a1100..75ac9d48ef46 100644 --- a/drivers/spi/spi-ppc4xx.c +++ b/drivers/spi/spi-ppc4xx.c @@ -466,9 +466,6 @@ static int __init spi_ppc4xx_of_probe(struct platform_device *op) bbp->master->setup = spi_ppc4xx_setup; bbp->master->cleanup = spi_ppc4xx_cleanup; - /* Allocate bus num dynamically. */ - bbp->master->bus_num = -1; - /* the spi->mode bits understood by this driver: */ bbp->master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_LSB_FIRST; diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 77c4562ac9d3..cd56dcf46320 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -1438,7 +1438,6 @@ static int __devinit pch_spi_pd_probe(struct platform_device *plat_dev) plat_dev->id, data->io_remap_addr); /* initialize members of SPI master */ - master->bus_num = -1; master->num_chipselect = PCH_MAX_CS; master->setup = pch_spi_setup; master->transfer = pch_spi_transfer; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 2d65b1684cdc..1041cb83d67a 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -936,6 +936,8 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size) return NULL; device_initialize(&master->dev); + master->bus_num = -1; + master->num_chipselect = 1; master->dev.class = &spi_master_class; master->dev.parent = get_device(dev); spi_master_set_devdata(master, &master[1]); -- cgit v1.2.3