diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-09-05 12:56:57 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-09-05 12:56:57 -0400 |
| commit | 616ad8c44281c0c6711a72b560e01ec335ff27e0 (patch) | |
| tree | 0a20453ffedb09db6fb41a0c2208ccc2c7751d3a /drivers/spi/spi.c | |
| parent | 99809963c99e1ed868d9ebeb4a5e7ee1cbe0309f (diff) | |
| parent | b380b0d4f7dffcc235c0facefa537d4655619101 (diff) | |
Merge branch 'linus' into x86/defconfig
Diffstat (limited to 'drivers/spi/spi.c')
| -rw-r--r-- | drivers/spi/spi.c | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 964124b60db2..75e86865234c 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
| @@ -226,10 +226,11 @@ EXPORT_SYMBOL_GPL(spi_alloc_device); | |||
| 226 | * Companion function to spi_alloc_device. Devices allocated with | 226 | * Companion function to spi_alloc_device. Devices allocated with |
| 227 | * spi_alloc_device can be added onto the spi bus with this function. | 227 | * spi_alloc_device can be added onto the spi bus with this function. |
| 228 | * | 228 | * |
| 229 | * Returns 0 on success; non-zero on failure | 229 | * Returns 0 on success; negative errno on failure |
| 230 | */ | 230 | */ |
| 231 | int spi_add_device(struct spi_device *spi) | 231 | int spi_add_device(struct spi_device *spi) |
| 232 | { | 232 | { |
| 233 | static DEFINE_MUTEX(spi_add_lock); | ||
| 233 | struct device *dev = spi->master->dev.parent; | 234 | struct device *dev = spi->master->dev.parent; |
| 234 | int status; | 235 | int status; |
| 235 | 236 | ||
| @@ -246,26 +247,43 @@ int spi_add_device(struct spi_device *spi) | |||
| 246 | "%s.%u", spi->master->dev.bus_id, | 247 | "%s.%u", spi->master->dev.bus_id, |
| 247 | spi->chip_select); | 248 | spi->chip_select); |
| 248 | 249 | ||
| 249 | /* drivers may modify this initial i/o setup */ | 250 | |
| 251 | /* We need to make sure there's no other device with this | ||
| 252 | * chipselect **BEFORE** we call setup(), else we'll trash | ||
| 253 | * its configuration. Lock against concurrent add() calls. | ||
| 254 | */ | ||
| 255 | mutex_lock(&spi_add_lock); | ||
| 256 | |||
| 257 | if (bus_find_device_by_name(&spi_bus_type, NULL, spi->dev.bus_id) | ||
| 258 | != NULL) { | ||
| 259 | dev_err(dev, "chipselect %d already in use\n", | ||
| 260 | spi->chip_select); | ||
| 261 | status = -EBUSY; | ||
| 262 | goto done; | ||
| 263 | } | ||
| 264 | |||
| 265 | /* Drivers may modify this initial i/o setup, but will | ||
| 266 | * normally rely on the device being setup. Devices | ||
| 267 | * using SPI_CS_HIGH can't coexist well otherwise... | ||
| 268 | */ | ||
| 250 | status = spi->master->setup(spi); | 269 | status = spi->master->setup(spi); |
| 251 | if (status < 0) { | 270 | if (status < 0) { |
| 252 | dev_err(dev, "can't %s %s, status %d\n", | 271 | dev_err(dev, "can't %s %s, status %d\n", |
| 253 | "setup", spi->dev.bus_id, status); | 272 | "setup", spi->dev.bus_id, status); |
| 254 | return status; | 273 | goto done; |
| 255 | } | 274 | } |
| 256 | 275 | ||
| 257 | /* driver core catches callers that misbehave by defining | 276 | /* Device may be bound to an active driver when this returns */ |
| 258 | * devices that already exist. | ||
| 259 | */ | ||
| 260 | status = device_add(&spi->dev); | 277 | status = device_add(&spi->dev); |
| 261 | if (status < 0) { | 278 | if (status < 0) |
| 262 | dev_err(dev, "can't %s %s, status %d\n", | 279 | dev_err(dev, "can't %s %s, status %d\n", |
| 263 | "add", spi->dev.bus_id, status); | 280 | "add", spi->dev.bus_id, status); |
| 264 | return status; | 281 | else |
| 265 | } | 282 | dev_dbg(dev, "registered child %s\n", spi->dev.bus_id); |
| 266 | 283 | ||
| 267 | dev_dbg(dev, "registered child %s\n", spi->dev.bus_id); | 284 | done: |
| 268 | return 0; | 285 | mutex_unlock(&spi_add_lock); |
| 286 | return status; | ||
| 269 | } | 287 | } |
| 270 | EXPORT_SYMBOL_GPL(spi_add_device); | 288 | EXPORT_SYMBOL_GPL(spi_add_device); |
| 271 | 289 | ||
