diff options
author | David Brownell <david-b@pacbell.net> | 2007-10-27 08:47:20 -0400 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2007-10-27 08:47:20 -0400 |
commit | 460cd0589df8aa9b89599905b13c2010db627012 (patch) | |
tree | 0d0cbf523d6513f43fca8a0bfb24070271b9215c /drivers | |
parent | 1fa8dd146f6bf57902602522c212040f8fa6fcd3 (diff) |
mmc_spi: Fix mmc-over-spi regression
Patch 49dce689ad4ef0fd1f970ef762168e4bd46f69a3 changed the sysfs data
structures for SPI in a way which broke the MMC-over-SPI host driver.
This patch fixes that regression by changing the scheme used to keep
from knowingly trying to use a shared bus segment, and updates the
adjacent comments slightly to better explain the issue.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/host/mmc_spi.c | 52 |
1 files changed, 33 insertions, 19 deletions
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 12c2d807c145..a6469218f194 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
@@ -1165,6 +1165,23 @@ mmc_spi_detect_irq(int irq, void *mmc) | |||
1165 | return IRQ_HANDLED; | 1165 | return IRQ_HANDLED; |
1166 | } | 1166 | } |
1167 | 1167 | ||
1168 | struct count_children { | ||
1169 | unsigned n; | ||
1170 | struct bus_type *bus; | ||
1171 | }; | ||
1172 | |||
1173 | static int maybe_count_child(struct device *dev, void *c) | ||
1174 | { | ||
1175 | struct count_children *ccp = c; | ||
1176 | |||
1177 | if (dev->bus == ccp->bus) { | ||
1178 | if (ccp->n) | ||
1179 | return -EBUSY; | ||
1180 | ccp->n++; | ||
1181 | } | ||
1182 | return 0; | ||
1183 | } | ||
1184 | |||
1168 | static int mmc_spi_probe(struct spi_device *spi) | 1185 | static int mmc_spi_probe(struct spi_device *spi) |
1169 | { | 1186 | { |
1170 | void *ones; | 1187 | void *ones; |
@@ -1188,33 +1205,30 @@ static int mmc_spi_probe(struct spi_device *spi) | |||
1188 | return status; | 1205 | return status; |
1189 | } | 1206 | } |
1190 | 1207 | ||
1191 | /* We can use the bus safely iff nobody else will interfere with | 1208 | /* We can use the bus safely iff nobody else will interfere with us. |
1192 | * us. That is, either we have the experimental exclusive access | 1209 | * Most commands consist of one SPI message to issue a command, then |
1193 | * primitives ... or else there's nobody to share it with. | 1210 | * several more to collect its response, then possibly more for data |
1211 | * transfer. Clocking access to other devices during that period will | ||
1212 | * corrupt the command execution. | ||
1213 | * | ||
1214 | * Until we have software primitives which guarantee non-interference, | ||
1215 | * we'll aim for a hardware-level guarantee. | ||
1216 | * | ||
1217 | * REVISIT we can't guarantee another device won't be added later... | ||
1194 | */ | 1218 | */ |
1195 | if (spi->master->num_chipselect > 1) { | 1219 | if (spi->master->num_chipselect > 1) { |
1196 | struct device *parent = spi->dev.parent; | 1220 | struct count_children cc; |
1197 | 1221 | ||
1198 | /* If there are multiple devices on this bus, we | 1222 | cc.n = 0; |
1199 | * can't proceed. | 1223 | cc.bus = spi->dev.bus; |
1200 | */ | 1224 | status = device_for_each_child(spi->dev.parent, &cc, |
1201 | spin_lock(&parent->klist_children.k_lock); | 1225 | maybe_count_child); |
1202 | if (parent->klist_children.k_list.next | ||
1203 | != parent->klist_children.k_list.prev) | ||
1204 | status = -EMLINK; | ||
1205 | else | ||
1206 | status = 0; | ||
1207 | spin_unlock(&parent->klist_children.k_lock); | ||
1208 | if (status < 0) { | 1226 | if (status < 0) { |
1209 | dev_err(&spi->dev, "can't share SPI bus\n"); | 1227 | dev_err(&spi->dev, "can't share SPI bus\n"); |
1210 | return status; | 1228 | return status; |
1211 | } | 1229 | } |
1212 | 1230 | ||
1213 | /* REVISIT we can't guarantee another device won't | 1231 | dev_warn(&spi->dev, "ASSUMING SPI bus stays unshared!\n"); |
1214 | * be added later. It's uncommon though ... for now, | ||
1215 | * work as if this is safe. | ||
1216 | */ | ||
1217 | dev_warn(&spi->dev, "ASSUMING unshared SPI bus!\n"); | ||
1218 | } | 1232 | } |
1219 | 1233 | ||
1220 | /* We need a supply of ones to transmit. This is the only time | 1234 | /* We need a supply of ones to transmit. This is the only time |