aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-07-28 02:30:40 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-07-28 02:30:40 -0400
commitd65d830ca06040ffe6a35ce7cb06ee642ddbd6a8 (patch)
tree27cda8b58a24eb8b1acdc3c14f902b90ab3d9eb1 /drivers
parent837b41b5de356aa67abb2cadb5eef3efc7776f91 (diff)
parent284b01897340974000bcc84de87a4e1becc8a83d (diff)
Merge commit 'gcl/gcl-next'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/of/Kconfig6
-rw-r--r--drivers/of/Makefile1
-rw-r--r--drivers/of/base.c88
-rw-r--r--drivers/of/of_i2c.c64
-rw-r--r--drivers/of/of_spi.c93
-rw-r--r--drivers/spi/spi.c139
6 files changed, 286 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
17config 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
2obj-$(CONFIG_OF_DEVICE) += device.o platform.o 2obj-$(CONFIG_OF_DEVICE) += device.o platform.o
3obj-$(CONFIG_OF_GPIO) += gpio.o 3obj-$(CONFIG_OF_GPIO) += gpio.o
4obj-$(CONFIG_OF_I2C) += of_i2c.o 4obj-$(CONFIG_OF_I2C) += of_i2c.o
5obj-$(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}
387EXPORT_SYMBOL(of_find_matching_node); 387EXPORT_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 */
408struct of_modalias_table {
409 char *of_device;
410 char *modalias;
411};
412static 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 */
433int 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}
474EXPORT_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
19struct i2c_driver_device {
20 char *of_device;
21 char *i2c_type;
22};
23
24static struct i2c_driver_device i2c_devices[] = {
25};
26
27static 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
75void of_register_i2c_devices(struct i2c_adapter *adap, 19void 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 */
22void 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}
93EXPORT_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 {
178static LIST_HEAD(board_list); 178static LIST_HEAD(board_list);
179static DEFINE_MUTEX(board_lock); 179static 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 */
198struct 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}
220EXPORT_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 */
231int 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}
270EXPORT_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
266fail:
267 spi_master_put(master);
268 kfree(proxy);
269 return NULL;
270} 321}
271EXPORT_SYMBOL_GPL(spi_new_device); 322EXPORT_SYMBOL_GPL(spi_new_device);
272 323