diff options
author | Pantelis Antoniou <pantelis.antoniou@konsulko.com> | 2014-10-29 04:40:37 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@linaro.org> | 2014-11-25 10:35:43 -0500 |
commit | aff5e3f89a0b07e7edf9243f913378cc27e4110d (patch) | |
tree | 1d3cc8af2aa2ac1046909e341468464426fcf2e1 /drivers/spi/spi.c | |
parent | ea7513bbc04170f1cbf42953187a4d8b731c71c4 (diff) |
spi/of: Create new device registration method and accessors
Dynamically inserting spi device nodes requires the use of a single
device registration method. Refactor the existing
of_register_spi_devices() to split out the core functionality for a
single device into a separate function; of_register_spi_device(). This
function will be used by the OF_DYNAMIC overlay code to make live
modifications to the tree.
Methods to lookup a device/master using a device node are added
as well, of_find_spi_master_by_node() & of_find_spi_device_by_node().
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
[grant.likely] Split patch into two pieces for clarity
Signed-off-by: Grant Likely <grant.likely@linaro.org>
Reviewed-by: Mark Brown <broonie@kernel.org>
Cc: <linux-spi@vger.kernel.org>
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r-- | drivers/spi/spi.c | 222 |
1 files changed, 118 insertions, 104 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index ebcb33df2eb2..a3557c57d4f7 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -1220,6 +1220,121 @@ err_init_queue: | |||
1220 | /*-------------------------------------------------------------------------*/ | 1220 | /*-------------------------------------------------------------------------*/ |
1221 | 1221 | ||
1222 | #if defined(CONFIG_OF) | 1222 | #if defined(CONFIG_OF) |
1223 | static struct spi_device * | ||
1224 | of_register_spi_device(struct spi_master *master, struct device_node *nc) | ||
1225 | { | ||
1226 | struct spi_device *spi; | ||
1227 | int rc; | ||
1228 | u32 value; | ||
1229 | |||
1230 | /* Alloc an spi_device */ | ||
1231 | spi = spi_alloc_device(master); | ||
1232 | if (!spi) { | ||
1233 | dev_err(&master->dev, "spi_device alloc error for %s\n", | ||
1234 | nc->full_name); | ||
1235 | rc = -ENOMEM; | ||
1236 | goto err_out; | ||
1237 | } | ||
1238 | |||
1239 | /* Select device driver */ | ||
1240 | rc = of_modalias_node(nc, spi->modalias, | ||
1241 | sizeof(spi->modalias)); | ||
1242 | if (rc < 0) { | ||
1243 | dev_err(&master->dev, "cannot find modalias for %s\n", | ||
1244 | nc->full_name); | ||
1245 | goto err_out; | ||
1246 | } | ||
1247 | |||
1248 | /* Device address */ | ||
1249 | rc = of_property_read_u32(nc, "reg", &value); | ||
1250 | if (rc) { | ||
1251 | dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", | ||
1252 | nc->full_name, rc); | ||
1253 | goto err_out; | ||
1254 | } | ||
1255 | spi->chip_select = value; | ||
1256 | |||
1257 | /* Mode (clock phase/polarity/etc.) */ | ||
1258 | if (of_find_property(nc, "spi-cpha", NULL)) | ||
1259 | spi->mode |= SPI_CPHA; | ||
1260 | if (of_find_property(nc, "spi-cpol", NULL)) | ||
1261 | spi->mode |= SPI_CPOL; | ||
1262 | if (of_find_property(nc, "spi-cs-high", NULL)) | ||
1263 | spi->mode |= SPI_CS_HIGH; | ||
1264 | if (of_find_property(nc, "spi-3wire", NULL)) | ||
1265 | spi->mode |= SPI_3WIRE; | ||
1266 | if (of_find_property(nc, "spi-lsb-first", NULL)) | ||
1267 | spi->mode |= SPI_LSB_FIRST; | ||
1268 | |||
1269 | /* Device DUAL/QUAD mode */ | ||
1270 | if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) { | ||
1271 | switch (value) { | ||
1272 | case 1: | ||
1273 | break; | ||
1274 | case 2: | ||
1275 | spi->mode |= SPI_TX_DUAL; | ||
1276 | break; | ||
1277 | case 4: | ||
1278 | spi->mode |= SPI_TX_QUAD; | ||
1279 | break; | ||
1280 | default: | ||
1281 | dev_warn(&master->dev, | ||
1282 | "spi-tx-bus-width %d not supported\n", | ||
1283 | value); | ||
1284 | break; | ||
1285 | } | ||
1286 | } | ||
1287 | |||
1288 | if (!of_property_read_u32(nc, "spi-rx-bus-width", &value)) { | ||
1289 | switch (value) { | ||
1290 | case 1: | ||
1291 | break; | ||
1292 | case 2: | ||
1293 | spi->mode |= SPI_RX_DUAL; | ||
1294 | break; | ||
1295 | case 4: | ||
1296 | spi->mode |= SPI_RX_QUAD; | ||
1297 | break; | ||
1298 | default: | ||
1299 | dev_warn(&master->dev, | ||
1300 | "spi-rx-bus-width %d not supported\n", | ||
1301 | value); | ||
1302 | break; | ||
1303 | } | ||
1304 | } | ||
1305 | |||
1306 | /* Device speed */ | ||
1307 | rc = of_property_read_u32(nc, "spi-max-frequency", &value); | ||
1308 | if (rc) { | ||
1309 | dev_err(&master->dev, "%s has no valid 'spi-max-frequency' property (%d)\n", | ||
1310 | nc->full_name, rc); | ||
1311 | goto err_out; | ||
1312 | } | ||
1313 | spi->max_speed_hz = value; | ||
1314 | |||
1315 | /* IRQ */ | ||
1316 | spi->irq = irq_of_parse_and_map(nc, 0); | ||
1317 | |||
1318 | /* Store a pointer to the node in the device structure */ | ||
1319 | of_node_get(nc); | ||
1320 | spi->dev.of_node = nc; | ||
1321 | |||
1322 | /* Register the new device */ | ||
1323 | request_module("%s%s", SPI_MODULE_PREFIX, spi->modalias); | ||
1324 | rc = spi_add_device(spi); | ||
1325 | if (rc) { | ||
1326 | dev_err(&master->dev, "spi_device register error %s\n", | ||
1327 | nc->full_name); | ||
1328 | goto err_out; | ||
1329 | } | ||
1330 | |||
1331 | return spi; | ||
1332 | |||
1333 | err_out: | ||
1334 | spi_dev_put(spi); | ||
1335 | return ERR_PTR(rc); | ||
1336 | } | ||
1337 | |||
1223 | /** | 1338 | /** |
1224 | * of_register_spi_devices() - Register child devices onto the SPI bus | 1339 | * of_register_spi_devices() - Register child devices onto the SPI bus |
1225 | * @master: Pointer to spi_master device | 1340 | * @master: Pointer to spi_master device |
@@ -1231,116 +1346,15 @@ static void of_register_spi_devices(struct spi_master *master) | |||
1231 | { | 1346 | { |
1232 | struct spi_device *spi; | 1347 | struct spi_device *spi; |
1233 | struct device_node *nc; | 1348 | struct device_node *nc; |
1234 | int rc; | ||
1235 | u32 value; | ||
1236 | 1349 | ||
1237 | if (!master->dev.of_node) | 1350 | if (!master->dev.of_node) |
1238 | return; | 1351 | return; |
1239 | 1352 | ||
1240 | for_each_available_child_of_node(master->dev.of_node, nc) { | 1353 | for_each_available_child_of_node(master->dev.of_node, nc) { |
1241 | /* Alloc an spi_device */ | 1354 | spi = of_register_spi_device(master, nc); |
1242 | spi = spi_alloc_device(master); | 1355 | if (IS_ERR(spi)) |
1243 | if (!spi) { | 1356 | dev_warn(&master->dev, "Failed to create SPI device for %s\n", |
1244 | dev_err(&master->dev, "spi_device alloc error for %s\n", | ||
1245 | nc->full_name); | 1357 | nc->full_name); |
1246 | spi_dev_put(spi); | ||
1247 | continue; | ||
1248 | } | ||
1249 | |||
1250 | /* Select device driver */ | ||
1251 | if (of_modalias_node(nc, spi->modalias, | ||
1252 | sizeof(spi->modalias)) < 0) { | ||
1253 | dev_err(&master->dev, "cannot find modalias for %s\n", | ||
1254 | nc->full_name); | ||
1255 | spi_dev_put(spi); | ||
1256 | continue; | ||
1257 | } | ||
1258 | |||
1259 | /* Device address */ | ||
1260 | rc = of_property_read_u32(nc, "reg", &value); | ||
1261 | if (rc) { | ||
1262 | dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", | ||
1263 | nc->full_name, rc); | ||
1264 | spi_dev_put(spi); | ||
1265 | continue; | ||
1266 | } | ||
1267 | spi->chip_select = value; | ||
1268 | |||
1269 | /* Mode (clock phase/polarity/etc.) */ | ||
1270 | if (of_find_property(nc, "spi-cpha", NULL)) | ||
1271 | spi->mode |= SPI_CPHA; | ||
1272 | if (of_find_property(nc, "spi-cpol", NULL)) | ||
1273 | spi->mode |= SPI_CPOL; | ||
1274 | if (of_find_property(nc, "spi-cs-high", NULL)) | ||
1275 | spi->mode |= SPI_CS_HIGH; | ||
1276 | if (of_find_property(nc, "spi-3wire", NULL)) | ||
1277 | spi->mode |= SPI_3WIRE; | ||
1278 | if (of_find_property(nc, "spi-lsb-first", NULL)) | ||
1279 | spi->mode |= SPI_LSB_FIRST; | ||
1280 | |||
1281 | /* Device DUAL/QUAD mode */ | ||
1282 | if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) { | ||
1283 | switch (value) { | ||
1284 | case 1: | ||
1285 | break; | ||
1286 | case 2: | ||
1287 | spi->mode |= SPI_TX_DUAL; | ||
1288 | break; | ||
1289 | case 4: | ||
1290 | spi->mode |= SPI_TX_QUAD; | ||
1291 | break; | ||
1292 | default: | ||
1293 | dev_warn(&master->dev, | ||
1294 | "spi-tx-bus-width %d not supported\n", | ||
1295 | value); | ||
1296 | break; | ||
1297 | } | ||
1298 | } | ||
1299 | |||
1300 | if (!of_property_read_u32(nc, "spi-rx-bus-width", &value)) { | ||
1301 | switch (value) { | ||
1302 | case 1: | ||
1303 | break; | ||
1304 | case 2: | ||
1305 | spi->mode |= SPI_RX_DUAL; | ||
1306 | break; | ||
1307 | case 4: | ||
1308 | spi->mode |= SPI_RX_QUAD; | ||
1309 | break; | ||
1310 | default: | ||
1311 | dev_warn(&master->dev, | ||
1312 | "spi-rx-bus-width %d not supported\n", | ||
1313 | value); | ||
1314 | break; | ||
1315 | } | ||
1316 | } | ||
1317 | |||
1318 | /* Device speed */ | ||
1319 | rc = of_property_read_u32(nc, "spi-max-frequency", &value); | ||
1320 | if (rc) { | ||
1321 | dev_err(&master->dev, "%s has no valid 'spi-max-frequency' property (%d)\n", | ||
1322 | nc->full_name, rc); | ||
1323 | spi_dev_put(spi); | ||
1324 | continue; | ||
1325 | } | ||
1326 | spi->max_speed_hz = value; | ||
1327 | |||
1328 | /* IRQ */ | ||
1329 | spi->irq = irq_of_parse_and_map(nc, 0); | ||
1330 | |||
1331 | /* Store a pointer to the node in the device structure */ | ||
1332 | of_node_get(nc); | ||
1333 | spi->dev.of_node = nc; | ||
1334 | |||
1335 | /* Register the new device */ | ||
1336 | request_module("%s%s", SPI_MODULE_PREFIX, spi->modalias); | ||
1337 | rc = spi_add_device(spi); | ||
1338 | if (rc) { | ||
1339 | dev_err(&master->dev, "spi_device register error %s\n", | ||
1340 | nc->full_name); | ||
1341 | spi_dev_put(spi); | ||
1342 | } | ||
1343 | |||
1344 | } | 1358 | } |
1345 | } | 1359 | } |
1346 | #else | 1360 | #else |