diff options
| -rw-r--r-- | drivers/of/Kconfig | 6 | ||||
| -rw-r--r-- | drivers/of/Makefile | 1 | ||||
| -rw-r--r-- | drivers/of/base.c | 88 | ||||
| -rw-r--r-- | drivers/of/of_i2c.c | 64 | ||||
| -rw-r--r-- | drivers/of/of_spi.c | 93 | ||||
| -rw-r--r-- | drivers/spi/spi.c | 139 | ||||
| -rw-r--r-- | include/linux/of.h | 1 | ||||
| -rw-r--r-- | include/linux/of_spi.h | 18 | ||||
| -rw-r--r-- | include/linux/spi/spi.h | 12 |
9 files changed, 317 insertions, 105 deletions
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 1d7ec3129349..f821dbc952a4 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig | |||
| @@ -13,3 +13,9 @@ config OF_I2C | |||
| 13 | depends on PPC_OF && I2C | 13 | depends on PPC_OF && I2C |
| 14 | help | 14 | help |
| 15 | OpenFirmware I2C accessors | 15 | OpenFirmware I2C accessors |
| 16 | |||
| 17 | config OF_SPI | ||
| 18 | def_tristate SPI | ||
| 19 | depends on OF && PPC_OF && SPI | ||
| 20 | help | ||
| 21 | OpenFirmware SPI accessors | ||
diff --git a/drivers/of/Makefile b/drivers/of/Makefile index 548772e871fd..4c3c6f8e36f5 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile | |||
| @@ -2,3 +2,4 @@ obj-y = base.o | |||
| 2 | obj-$(CONFIG_OF_DEVICE) += device.o platform.o | 2 | obj-$(CONFIG_OF_DEVICE) += device.o platform.o |
| 3 | obj-$(CONFIG_OF_GPIO) += gpio.o | 3 | obj-$(CONFIG_OF_GPIO) += gpio.o |
| 4 | obj-$(CONFIG_OF_I2C) += of_i2c.o | 4 | obj-$(CONFIG_OF_I2C) += of_i2c.o |
| 5 | obj-$(CONFIG_OF_SPI) += of_spi.o | ||
diff --git a/drivers/of/base.c b/drivers/of/base.c index 23ffb7c0caf2..ad8ac1a8af28 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
| @@ -385,3 +385,91 @@ struct device_node *of_find_matching_node(struct device_node *from, | |||
| 385 | return np; | 385 | return np; |
| 386 | } | 386 | } |
| 387 | EXPORT_SYMBOL(of_find_matching_node); | 387 | EXPORT_SYMBOL(of_find_matching_node); |
| 388 | |||
| 389 | /** | ||
| 390 | * of_modalias_table: Table of explicit compatible ==> modalias mappings | ||
| 391 | * | ||
| 392 | * This table allows particulare compatible property values to be mapped | ||
| 393 | * to modalias strings. This is useful for busses which do not directly | ||
| 394 | * understand the OF device tree but are populated based on data contained | ||
| 395 | * within the device tree. SPI and I2C are the two current users of this | ||
| 396 | * table. | ||
| 397 | * | ||
| 398 | * In most cases, devices do not need to be listed in this table because | ||
| 399 | * the modalias value can be derived directly from the compatible table. | ||
| 400 | * However, if for any reason a value cannot be derived, then this table | ||
| 401 | * provides a method to override the implicit derivation. | ||
| 402 | * | ||
| 403 | * At the moment, a single table is used for all bus types because it is | ||
| 404 | * assumed that the data size is small and that the compatible values | ||
| 405 | * should already be distinct enough to differentiate between SPI, I2C | ||
| 406 | * and other devices. | ||
| 407 | */ | ||
| 408 | struct of_modalias_table { | ||
| 409 | char *of_device; | ||
| 410 | char *modalias; | ||
| 411 | }; | ||
| 412 | static struct of_modalias_table of_modalias_table[] = { | ||
| 413 | /* Empty for now; add entries as needed */ | ||
| 414 | }; | ||
| 415 | |||
| 416 | /** | ||
| 417 | * of_modalias_node - Lookup appropriate modalias for a device node | ||
| 418 | * @node: pointer to a device tree node | ||
| 419 | * @modalias: Pointer to buffer that modalias value will be copied into | ||
| 420 | * @len: Length of modalias value | ||
| 421 | * | ||
| 422 | * Based on the value of the compatible property, this routine will determine | ||
| 423 | * an appropriate modalias value for a particular device tree node. Three | ||
| 424 | * separate methods are used to derive a modalias value. | ||
| 425 | * | ||
| 426 | * First method is to lookup the compatible value in of_modalias_table. | ||
| 427 | * Second is to look for a "linux,<modalias>" entry in the compatible list | ||
| 428 | * and used that for modalias. Third is to strip off the manufacturer | ||
| 429 | * prefix from the first compatible entry and use the remainder as modalias | ||
| 430 | * | ||
| 431 | * This routine returns 0 on success | ||
| 432 | */ | ||
| 433 | int of_modalias_node(struct device_node *node, char *modalias, int len) | ||
| 434 | { | ||
| 435 | int i, cplen; | ||
| 436 | const char *compatible; | ||
| 437 | const char *p; | ||
| 438 | |||
| 439 | /* 1. search for exception list entry */ | ||
| 440 | for (i = 0; i < ARRAY_SIZE(of_modalias_table); i++) { | ||
| 441 | compatible = of_modalias_table[i].of_device; | ||
| 442 | if (!of_device_is_compatible(node, compatible)) | ||
| 443 | continue; | ||
| 444 | strlcpy(modalias, of_modalias_table[i].modalias, len); | ||
| 445 | return 0; | ||
| 446 | } | ||
| 447 | |||
| 448 | compatible = of_get_property(node, "compatible", &cplen); | ||
| 449 | if (!compatible) | ||
| 450 | return -ENODEV; | ||
| 451 | |||
| 452 | /* 2. search for linux,<modalias> entry */ | ||
| 453 | p = compatible; | ||
| 454 | while (cplen > 0) { | ||
| 455 | if (!strncmp(p, "linux,", 6)) { | ||
| 456 | p += 6; | ||
| 457 | strlcpy(modalias, p, len); | ||
| 458 | return 0; | ||
| 459 | } | ||
| 460 | |||
| 461 | i = strlen(p) + 1; | ||
| 462 | p += i; | ||
| 463 | cplen -= i; | ||
| 464 | } | ||
| 465 | |||
| 466 | /* 3. take first compatible entry and strip manufacturer */ | ||
| 467 | p = strchr(compatible, ','); | ||
| 468 | if (!p) | ||
| 469 | return -ENODEV; | ||
| 470 | p++; | ||
| 471 | strlcpy(modalias, p, len); | ||
| 472 | return 0; | ||
| 473 | } | ||
| 474 | EXPORT_SYMBOL_GPL(of_modalias_node); | ||
| 475 | |||
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index 344e1b03dd8b..6a98dc8aa30b 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c | |||
| @@ -16,62 +16,6 @@ | |||
| 16 | #include <linux/of_i2c.h> | 16 | #include <linux/of_i2c.h> |
| 17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 18 | 18 | ||
| 19 | struct i2c_driver_device { | ||
| 20 | char *of_device; | ||
| 21 | char *i2c_type; | ||
| 22 | }; | ||
| 23 | |||
| 24 | static struct i2c_driver_device i2c_devices[] = { | ||
| 25 | }; | ||
| 26 | |||
| 27 | static int of_find_i2c_driver(struct device_node *node, | ||
| 28 | struct i2c_board_info *info) | ||
| 29 | { | ||
| 30 | int i, cplen; | ||
| 31 | const char *compatible; | ||
| 32 | const char *p; | ||
| 33 | |||
| 34 | /* 1. search for exception list entry */ | ||
| 35 | for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) { | ||
| 36 | if (!of_device_is_compatible(node, i2c_devices[i].of_device)) | ||
| 37 | continue; | ||
| 38 | if (strlcpy(info->type, i2c_devices[i].i2c_type, | ||
| 39 | I2C_NAME_SIZE) >= I2C_NAME_SIZE) | ||
| 40 | return -ENOMEM; | ||
| 41 | |||
| 42 | return 0; | ||
| 43 | } | ||
| 44 | |||
| 45 | compatible = of_get_property(node, "compatible", &cplen); | ||
| 46 | if (!compatible) | ||
| 47 | return -ENODEV; | ||
| 48 | |||
| 49 | /* 2. search for linux,<i2c-type> entry */ | ||
| 50 | p = compatible; | ||
| 51 | while (cplen > 0) { | ||
| 52 | if (!strncmp(p, "linux,", 6)) { | ||
| 53 | p += 6; | ||
| 54 | if (strlcpy(info->type, p, | ||
| 55 | I2C_NAME_SIZE) >= I2C_NAME_SIZE) | ||
| 56 | return -ENOMEM; | ||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | i = strlen(p) + 1; | ||
| 61 | p += i; | ||
| 62 | cplen -= i; | ||
| 63 | } | ||
| 64 | |||
| 65 | /* 3. take fist compatible entry and strip manufacturer */ | ||
| 66 | p = strchr(compatible, ','); | ||
| 67 | if (!p) | ||
| 68 | return -ENODEV; | ||
| 69 | p++; | ||
| 70 | if (strlcpy(info->type, p, I2C_NAME_SIZE) >= I2C_NAME_SIZE) | ||
| 71 | return -ENOMEM; | ||
| 72 | return 0; | ||
| 73 | } | ||
| 74 | |||
| 75 | void of_register_i2c_devices(struct i2c_adapter *adap, | 19 | void of_register_i2c_devices(struct i2c_adapter *adap, |
| 76 | struct device_node *adap_node) | 20 | struct device_node *adap_node) |
| 77 | { | 21 | { |
| @@ -83,6 +27,9 @@ void of_register_i2c_devices(struct i2c_adapter *adap, | |||
| 83 | const u32 *addr; | 27 | const u32 *addr; |
| 84 | int len; | 28 | int len; |
| 85 | 29 | ||
| 30 | if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) | ||
| 31 | continue; | ||
| 32 | |||
| 86 | addr = of_get_property(node, "reg", &len); | 33 | addr = of_get_property(node, "reg", &len); |
| 87 | if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) { | 34 | if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) { |
| 88 | printk(KERN_ERR | 35 | printk(KERN_ERR |
| @@ -92,11 +39,6 @@ void of_register_i2c_devices(struct i2c_adapter *adap, | |||
| 92 | 39 | ||
| 93 | info.irq = irq_of_parse_and_map(node, 0); | 40 | info.irq = irq_of_parse_and_map(node, 0); |
| 94 | 41 | ||
| 95 | if (of_find_i2c_driver(node, &info) < 0) { | ||
| 96 | irq_dispose_mapping(info.irq); | ||
| 97 | continue; | ||
| 98 | } | ||
| 99 | |||
| 100 | info.addr = *addr; | 42 | info.addr = *addr; |
| 101 | 43 | ||
| 102 | request_module(info.type); | 44 | request_module(info.type); |
diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c new file mode 100644 index 000000000000..b01eec026f68 --- /dev/null +++ b/drivers/of/of_spi.c | |||
| @@ -0,0 +1,93 @@ | |||
| 1 | /* | ||
| 2 | * SPI OF support routines | ||
| 3 | * Copyright (C) 2008 Secret Lab Technologies Ltd. | ||
| 4 | * | ||
| 5 | * Support routines for deriving SPI device attachments from the device | ||
| 6 | * tree. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/of.h> | ||
| 10 | #include <linux/device.h> | ||
| 11 | #include <linux/spi/spi.h> | ||
| 12 | #include <linux/of_spi.h> | ||
| 13 | |||
| 14 | /** | ||
| 15 | * of_register_spi_devices - Register child devices onto the SPI bus | ||
| 16 | * @master: Pointer to spi_master device | ||
| 17 | * @np: parent node of SPI device nodes | ||
| 18 | * | ||
| 19 | * Registers an spi_device for each child node of 'np' which has a 'reg' | ||
| 20 | * property. | ||
| 21 | */ | ||
| 22 | void of_register_spi_devices(struct spi_master *master, struct device_node *np) | ||
| 23 | { | ||
| 24 | struct spi_device *spi; | ||
| 25 | struct device_node *nc; | ||
| 26 | const u32 *prop; | ||
| 27 | int rc; | ||
| 28 | int len; | ||
| 29 | |||
| 30 | for_each_child_of_node(np, nc) { | ||
| 31 | /* Alloc an spi_device */ | ||
| 32 | spi = spi_alloc_device(master); | ||
| 33 | if (!spi) { | ||
| 34 | dev_err(&master->dev, "spi_device alloc error for %s\n", | ||
| 35 | nc->full_name); | ||
| 36 | spi_dev_put(spi); | ||
| 37 | continue; | ||
| 38 | } | ||
| 39 | |||
| 40 | /* Select device driver */ | ||
| 41 | if (of_modalias_node(nc, spi->modalias, | ||
| 42 | sizeof(spi->modalias)) < 0) { | ||
| 43 | dev_err(&master->dev, "cannot find modalias for %s\n", | ||
| 44 | nc->full_name); | ||
| 45 | spi_dev_put(spi); | ||
| 46 | continue; | ||
| 47 | } | ||
| 48 | |||
| 49 | /* Device address */ | ||
| 50 | prop = of_get_property(nc, "reg", &len); | ||
| 51 | if (!prop || len < sizeof(*prop)) { | ||
| 52 | dev_err(&master->dev, "%s has no 'reg' property\n", | ||
| 53 | nc->full_name); | ||
| 54 | spi_dev_put(spi); | ||
| 55 | continue; | ||
| 56 | } | ||
| 57 | spi->chip_select = *prop; | ||
| 58 | |||
| 59 | /* Mode (clock phase/polarity/etc.) */ | ||
| 60 | if (of_find_property(nc, "spi-cpha", NULL)) | ||
| 61 | spi->mode |= SPI_CPHA; | ||
| 62 | if (of_find_property(nc, "spi-cpol", NULL)) | ||
| 63 | spi->mode |= SPI_CPOL; | ||
| 64 | |||
| 65 | /* Device speed */ | ||
| 66 | prop = of_get_property(nc, "spi-max-frequency", &len); | ||
| 67 | if (!prop || len < sizeof(*prop)) { | ||
| 68 | dev_err(&master->dev, "%s has no 'spi-max-frequency' property\n", | ||
| 69 | nc->full_name); | ||
| 70 | spi_dev_put(spi); | ||
| 71 | continue; | ||
| 72 | } | ||
| 73 | spi->max_speed_hz = *prop; | ||
| 74 | |||
| 75 | /* IRQ */ | ||
| 76 | spi->irq = irq_of_parse_and_map(nc, 0); | ||
| 77 | |||
| 78 | /* Store a pointer to the node in the device structure */ | ||
| 79 | of_node_get(nc); | ||
| 80 | spi->dev.archdata.of_node = nc; | ||
| 81 | |||
| 82 | /* Register the new device */ | ||
| 83 | request_module(spi->modalias); | ||
| 84 | rc = spi_add_device(spi); | ||
| 85 | if (rc) { | ||
| 86 | dev_err(&master->dev, "spi_device register error %s\n", | ||
| 87 | nc->full_name); | ||
| 88 | spi_dev_put(spi); | ||
| 89 | } | ||
| 90 | |||
| 91 | } | ||
| 92 | } | ||
| 93 | EXPORT_SYMBOL(of_register_spi_devices); | ||
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index ecca4a6a6f94..964124b60db2 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
| @@ -178,6 +178,96 @@ struct boardinfo { | |||
| 178 | static LIST_HEAD(board_list); | 178 | static LIST_HEAD(board_list); |
| 179 | static DEFINE_MUTEX(board_lock); | 179 | static DEFINE_MUTEX(board_lock); |
| 180 | 180 | ||
| 181 | /** | ||
| 182 | * spi_alloc_device - Allocate a new SPI device | ||
| 183 | * @master: Controller to which device is connected | ||
| 184 | * Context: can sleep | ||
| 185 | * | ||
| 186 | * Allows a driver to allocate and initialize a spi_device without | ||
| 187 | * registering it immediately. This allows a driver to directly | ||
| 188 | * fill the spi_device with device parameters before calling | ||
| 189 | * spi_add_device() on it. | ||
| 190 | * | ||
| 191 | * Caller is responsible to call spi_add_device() on the returned | ||
| 192 | * spi_device structure to add it to the SPI master. If the caller | ||
| 193 | * needs to discard the spi_device without adding it, then it should | ||
| 194 | * call spi_dev_put() on it. | ||
| 195 | * | ||
| 196 | * Returns a pointer to the new device, or NULL. | ||
| 197 | */ | ||
| 198 | struct spi_device *spi_alloc_device(struct spi_master *master) | ||
| 199 | { | ||
| 200 | struct spi_device *spi; | ||
| 201 | struct device *dev = master->dev.parent; | ||
| 202 | |||
| 203 | if (!spi_master_get(master)) | ||
| 204 | return NULL; | ||
| 205 | |||
| 206 | spi = kzalloc(sizeof *spi, GFP_KERNEL); | ||
| 207 | if (!spi) { | ||
| 208 | dev_err(dev, "cannot alloc spi_device\n"); | ||
| 209 | spi_master_put(master); | ||
| 210 | return NULL; | ||
| 211 | } | ||
| 212 | |||
| 213 | spi->master = master; | ||
| 214 | spi->dev.parent = dev; | ||
| 215 | spi->dev.bus = &spi_bus_type; | ||
| 216 | spi->dev.release = spidev_release; | ||
| 217 | device_initialize(&spi->dev); | ||
| 218 | return spi; | ||
| 219 | } | ||
| 220 | EXPORT_SYMBOL_GPL(spi_alloc_device); | ||
| 221 | |||
| 222 | /** | ||
| 223 | * spi_add_device - Add spi_device allocated with spi_alloc_device | ||
| 224 | * @spi: spi_device to register | ||
| 225 | * | ||
| 226 | * Companion function to spi_alloc_device. Devices allocated with | ||
| 227 | * spi_alloc_device can be added onto the spi bus with this function. | ||
| 228 | * | ||
| 229 | * Returns 0 on success; non-zero on failure | ||
| 230 | */ | ||
| 231 | int spi_add_device(struct spi_device *spi) | ||
| 232 | { | ||
| 233 | struct device *dev = spi->master->dev.parent; | ||
| 234 | int status; | ||
| 235 | |||
| 236 | /* Chipselects are numbered 0..max; validate. */ | ||
| 237 | if (spi->chip_select >= spi->master->num_chipselect) { | ||
| 238 | dev_err(dev, "cs%d >= max %d\n", | ||
| 239 | spi->chip_select, | ||
| 240 | spi->master->num_chipselect); | ||
| 241 | return -EINVAL; | ||
| 242 | } | ||
| 243 | |||
| 244 | /* Set the bus ID string */ | ||
| 245 | snprintf(spi->dev.bus_id, sizeof spi->dev.bus_id, | ||
| 246 | "%s.%u", spi->master->dev.bus_id, | ||
| 247 | spi->chip_select); | ||
| 248 | |||
| 249 | /* drivers may modify this initial i/o setup */ | ||
| 250 | status = spi->master->setup(spi); | ||
| 251 | if (status < 0) { | ||
| 252 | dev_err(dev, "can't %s %s, status %d\n", | ||
| 253 | "setup", spi->dev.bus_id, status); | ||
| 254 | return status; | ||
| 255 | } | ||
| 256 | |||
| 257 | /* driver core catches callers that misbehave by defining | ||
| 258 | * devices that already exist. | ||
| 259 | */ | ||
| 260 | status = device_add(&spi->dev); | ||
| 261 | if (status < 0) { | ||
| 262 | dev_err(dev, "can't %s %s, status %d\n", | ||
| 263 | "add", spi->dev.bus_id, status); | ||
| 264 | return status; | ||
| 265 | } | ||
| 266 | |||
| 267 | dev_dbg(dev, "registered child %s\n", spi->dev.bus_id); | ||
| 268 | return 0; | ||
| 269 | } | ||
| 270 | EXPORT_SYMBOL_GPL(spi_add_device); | ||
| 181 | 271 | ||
| 182 | /** | 272 | /** |
| 183 | * spi_new_device - instantiate one new SPI device | 273 | * spi_new_device - instantiate one new SPI device |
| @@ -197,7 +287,6 @@ struct spi_device *spi_new_device(struct spi_master *master, | |||
| 197 | struct spi_board_info *chip) | 287 | struct spi_board_info *chip) |
| 198 | { | 288 | { |
| 199 | struct spi_device *proxy; | 289 | struct spi_device *proxy; |
| 200 | struct device *dev = master->dev.parent; | ||
| 201 | int status; | 290 | int status; |
| 202 | 291 | ||
| 203 | /* NOTE: caller did any chip->bus_num checks necessary. | 292 | /* NOTE: caller did any chip->bus_num checks necessary. |
| @@ -207,66 +296,28 @@ struct spi_device *spi_new_device(struct spi_master *master, | |||
| 207 | * suggests syslogged diagnostics are best here (ugh). | 296 | * suggests syslogged diagnostics are best here (ugh). |
| 208 | */ | 297 | */ |
| 209 | 298 | ||
| 210 | /* Chipselects are numbered 0..max; validate. */ | 299 | proxy = spi_alloc_device(master); |
| 211 | if (chip->chip_select >= master->num_chipselect) { | 300 | if (!proxy) |
| 212 | dev_err(dev, "cs%d > max %d\n", | ||
| 213 | chip->chip_select, | ||
| 214 | master->num_chipselect); | ||
| 215 | return NULL; | ||
| 216 | } | ||
| 217 | |||
| 218 | if (!spi_master_get(master)) | ||
| 219 | return NULL; | 301 | return NULL; |
| 220 | 302 | ||
| 221 | WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias)); | 303 | WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias)); |
| 222 | 304 | ||
| 223 | proxy = kzalloc(sizeof *proxy, GFP_KERNEL); | ||
| 224 | if (!proxy) { | ||
| 225 | dev_err(dev, "can't alloc dev for cs%d\n", | ||
| 226 | chip->chip_select); | ||
| 227 | goto fail; | ||
| 228 | } | ||
| 229 | proxy->master = master; | ||
| 230 | proxy->chip_select = chip->chip_select; | 305 | proxy->chip_select = chip->chip_select; |
| 231 | proxy->max_speed_hz = chip->max_speed_hz; | 306 | proxy->max_speed_hz = chip->max_speed_hz; |
| 232 | proxy->mode = chip->mode; | 307 | proxy->mode = chip->mode; |
| 233 | proxy->irq = chip->irq; | 308 | proxy->irq = chip->irq; |
| 234 | strlcpy(proxy->modalias, chip->modalias, sizeof(proxy->modalias)); | 309 | strlcpy(proxy->modalias, chip->modalias, sizeof(proxy->modalias)); |
| 235 | |||
| 236 | snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id, | ||
| 237 | "%s.%u", master->dev.bus_id, | ||
| 238 | chip->chip_select); | ||
| 239 | proxy->dev.parent = dev; | ||
| 240 | proxy->dev.bus = &spi_bus_type; | ||
| 241 | proxy->dev.platform_data = (void *) chip->platform_data; | 310 | proxy->dev.platform_data = (void *) chip->platform_data; |
| 242 | proxy->controller_data = chip->controller_data; | 311 | proxy->controller_data = chip->controller_data; |
| 243 | proxy->controller_state = NULL; | 312 | proxy->controller_state = NULL; |
| 244 | proxy->dev.release = spidev_release; | ||
| 245 | 313 | ||
| 246 | /* drivers may modify this initial i/o setup */ | 314 | status = spi_add_device(proxy); |
| 247 | status = master->setup(proxy); | ||
| 248 | if (status < 0) { | 315 | if (status < 0) { |
| 249 | dev_err(dev, "can't %s %s, status %d\n", | 316 | spi_dev_put(proxy); |
| 250 | "setup", proxy->dev.bus_id, status); | 317 | return NULL; |
| 251 | goto fail; | ||
| 252 | } | 318 | } |
| 253 | 319 | ||
| 254 | /* driver core catches callers that misbehave by defining | ||
| 255 | * devices that already exist. | ||
| 256 | */ | ||
| 257 | status = device_register(&proxy->dev); | ||
| 258 | if (status < 0) { | ||
| 259 | dev_err(dev, "can't %s %s, status %d\n", | ||
| 260 | "add", proxy->dev.bus_id, status); | ||
| 261 | goto fail; | ||
| 262 | } | ||
| 263 | dev_dbg(dev, "registered child %s\n", proxy->dev.bus_id); | ||
| 264 | return proxy; | 320 | return proxy; |
| 265 | |||
| 266 | fail: | ||
| 267 | spi_master_put(master); | ||
| 268 | kfree(proxy); | ||
| 269 | return NULL; | ||
| 270 | } | 321 | } |
| 271 | EXPORT_SYMBOL_GPL(spi_new_device); | 322 | EXPORT_SYMBOL_GPL(spi_new_device); |
| 272 | 323 | ||
diff --git a/include/linux/of.h b/include/linux/of.h index 59a61bdc98b6..79886ade070f 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
| @@ -70,5 +70,6 @@ extern int of_n_addr_cells(struct device_node *np); | |||
| 70 | extern int of_n_size_cells(struct device_node *np); | 70 | extern int of_n_size_cells(struct device_node *np); |
| 71 | extern const struct of_device_id *of_match_node( | 71 | extern const struct of_device_id *of_match_node( |
| 72 | const struct of_device_id *matches, const struct device_node *node); | 72 | const struct of_device_id *matches, const struct device_node *node); |
| 73 | extern int of_modalias_node(struct device_node *node, char *modalias, int len); | ||
| 73 | 74 | ||
| 74 | #endif /* _LINUX_OF_H */ | 75 | #endif /* _LINUX_OF_H */ |
diff --git a/include/linux/of_spi.h b/include/linux/of_spi.h new file mode 100644 index 000000000000..5f71ee8c0868 --- /dev/null +++ b/include/linux/of_spi.h | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* | ||
| 2 | * OpenFirmware SPI support routines | ||
| 3 | * Copyright (C) 2008 Secret Lab Technologies Ltd. | ||
| 4 | * | ||
| 5 | * Support routines for deriving SPI device attachments from the device | ||
| 6 | * tree. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef __LINUX_OF_SPI_H | ||
| 10 | #define __LINUX_OF_SPI_H | ||
| 11 | |||
| 12 | #include <linux/of.h> | ||
| 13 | #include <linux/spi/spi.h> | ||
| 14 | |||
| 15 | extern void of_register_spi_devices(struct spi_master *master, | ||
| 16 | struct device_node *np); | ||
| 17 | |||
| 18 | #endif /* __LINUX_OF_SPI */ | ||
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index a9cc29d46653..4be01bb44377 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h | |||
| @@ -778,8 +778,20 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n) | |||
| 778 | * use spi_new_device() to describe each device. You can also call | 778 | * use spi_new_device() to describe each device. You can also call |
| 779 | * spi_unregister_device() to start making that device vanish, but | 779 | * spi_unregister_device() to start making that device vanish, but |
| 780 | * normally that would be handled by spi_unregister_master(). | 780 | * normally that would be handled by spi_unregister_master(). |
| 781 | * | ||
| 782 | * You can also use spi_alloc_device() and spi_add_device() to use a two | ||
| 783 | * stage registration sequence for each spi_device. This gives the caller | ||
| 784 | * some more control over the spi_device structure before it is registered, | ||
| 785 | * but requires that caller to initialize fields that would otherwise | ||
| 786 | * be defined using the board info. | ||
| 781 | */ | 787 | */ |
| 782 | extern struct spi_device * | 788 | extern struct spi_device * |
| 789 | spi_alloc_device(struct spi_master *master); | ||
| 790 | |||
| 791 | extern int | ||
| 792 | spi_add_device(struct spi_device *spi); | ||
| 793 | |||
| 794 | extern struct spi_device * | ||
| 783 | spi_new_device(struct spi_master *, struct spi_board_info *); | 795 | spi_new_device(struct spi_master *, struct spi_board_info *); |
| 784 | 796 | ||
| 785 | static inline void | 797 | static inline void |
