aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-24 12:30:20 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-24 12:30:20 -0400
commite264ac8cad5a3f2e717ac68eb300766eef61f568 (patch)
treef6230e79ef751783d9a723c826dd64efde7d53c0 /drivers
parent200460067d19db4aab7f1d9f5c95dd644d260337 (diff)
parent06fb01fd1dc624d891cbe039a88a44bc8a8a9ec1 (diff)
Merge branch 'devicetree/merge' of git://git.secretlab.ca/git/linux-2.6
* 'devicetree/merge' of git://git.secretlab.ca/git/linux-2.6: spi/pl022: Add loopback support for the SPI on 5500 spi/omap_mcspi: Fix broken last word xfer of/flattree: minor cleanups dt: eliminate OF_NO_DEEP_PROBE and test for NULL match table dt: protect against NULL matches passed to of_match_node() dt: Refactor of_platform_bus_probe()
Diffstat (limited to 'drivers')
-rw-r--r--drivers/of/base.c3
-rw-r--r--drivers/of/fdt.c6
-rw-r--r--drivers/of/platform.c72
-rw-r--r--drivers/spi/amba-pl022.c20
-rw-r--r--drivers/spi/omap2_mcspi.c6
5 files changed, 52 insertions, 55 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 710b53bfac6d..632ebae7f17a 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -496,6 +496,9 @@ EXPORT_SYMBOL(of_find_node_with_property);
496const struct of_device_id *of_match_node(const struct of_device_id *matches, 496const struct of_device_id *of_match_node(const struct of_device_id *matches,
497 const struct device_node *node) 497 const struct device_node *node)
498{ 498{
499 if (!matches)
500 return NULL;
501
499 while (matches->name[0] || matches->type[0] || matches->compatible[0]) { 502 while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
500 int match = 1; 503 int match = 1;
501 if (matches->name[0]) 504 if (matches->name[0])
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index af824e7e0367..c9db49c10f45 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -139,12 +139,13 @@ static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
139/** 139/**
140 * unflatten_dt_node - Alloc and populate a device_node from the flat tree 140 * unflatten_dt_node - Alloc and populate a device_node from the flat tree
141 * @blob: The parent device tree blob 141 * @blob: The parent device tree blob
142 * @mem: Memory chunk to use for allocating device nodes and properties
142 * @p: pointer to node in flat tree 143 * @p: pointer to node in flat tree
143 * @dad: Parent struct device_node 144 * @dad: Parent struct device_node
144 * @allnextpp: pointer to ->allnext from last allocated device_node 145 * @allnextpp: pointer to ->allnext from last allocated device_node
145 * @fpsize: Size of the node path up at the current depth. 146 * @fpsize: Size of the node path up at the current depth.
146 */ 147 */
147unsigned long unflatten_dt_node(struct boot_param_header *blob, 148static unsigned long unflatten_dt_node(struct boot_param_header *blob,
148 unsigned long mem, 149 unsigned long mem,
149 unsigned long *p, 150 unsigned long *p,
150 struct device_node *dad, 151 struct device_node *dad,
@@ -230,6 +231,7 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob,
230 } 231 }
231 kref_init(&np->kref); 232 kref_init(&np->kref);
232 } 233 }
234 /* process properties */
233 while (1) { 235 while (1) {
234 u32 sz, noff; 236 u32 sz, noff;
235 char *pname; 237 char *pname;
@@ -351,7 +353,7 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob,
351 * @dt_alloc: An allocator that provides a virtual address to memory 353 * @dt_alloc: An allocator that provides a virtual address to memory
352 * for the resulting tree 354 * for the resulting tree
353 */ 355 */
354void __unflatten_device_tree(struct boot_param_header *blob, 356static void __unflatten_device_tree(struct boot_param_header *blob,
355 struct device_node **mynodes, 357 struct device_node **mynodes,
356 void * (*dt_alloc)(u64 size, u64 align)) 358 void * (*dt_alloc)(u64 size, u64 align))
357{ 359{
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 1ce4c45c4ab2..63d3cb73bdb9 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -210,13 +210,16 @@ struct platform_device *of_platform_device_create(struct device_node *np,
210EXPORT_SYMBOL(of_platform_device_create); 210EXPORT_SYMBOL(of_platform_device_create);
211 211
212/** 212/**
213 * of_platform_bus_create - Create an OF device for a bus node and all its 213 * of_platform_bus_create() - Create a device for a node and its children.
214 * children. Optionally recursively instantiate matching busses.
215 * @bus: device node of the bus to instantiate 214 * @bus: device node of the bus to instantiate
216 * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to 215 * @matches: match table for bus nodes
217 * disallow recursive creation of child busses 216 * disallow recursive creation of child buses
217 * @parent: parent for new device, or NULL for top level.
218 *
219 * Creates a platform_device for the provided device_node, and optionally
220 * recursively create devices for all the child nodes.
218 */ 221 */
219static int of_platform_bus_create(const struct device_node *bus, 222static int of_platform_bus_create(struct device_node *bus,
220 const struct of_device_id *matches, 223 const struct of_device_id *matches,
221 struct device *parent) 224 struct device *parent)
222{ 225{
@@ -224,18 +227,13 @@ static int of_platform_bus_create(const struct device_node *bus,
224 struct platform_device *dev; 227 struct platform_device *dev;
225 int rc = 0; 228 int rc = 0;
226 229
230 dev = of_platform_device_create(bus, NULL, parent);
231 if (!dev || !of_match_node(matches, bus))
232 return 0;
233
227 for_each_child_of_node(bus, child) { 234 for_each_child_of_node(bus, child) {
228 pr_debug(" create child: %s\n", child->full_name); 235 pr_debug(" create child: %s\n", child->full_name);
229 dev = of_platform_device_create(child, NULL, parent); 236 rc = of_platform_bus_create(child, matches, &dev->dev);
230 if (dev == NULL)
231 continue;
232
233 if (!of_match_node(matches, child))
234 continue;
235 if (rc == 0) {
236 pr_debug(" and sub busses\n");
237 rc = of_platform_bus_create(child, matches, &dev->dev);
238 }
239 if (rc) { 237 if (rc) {
240 of_node_put(child); 238 of_node_put(child);
241 break; 239 break;
@@ -245,9 +243,9 @@ static int of_platform_bus_create(const struct device_node *bus,
245} 243}
246 244
247/** 245/**
248 * of_platform_bus_probe - Probe the device-tree for platform busses 246 * of_platform_bus_probe() - Probe the device-tree for platform buses
249 * @root: parent of the first level to probe or NULL for the root of the tree 247 * @root: parent of the first level to probe or NULL for the root of the tree
250 * @matches: match table, NULL to use the default 248 * @matches: match table for bus nodes
251 * @parent: parent to hook devices from, NULL for toplevel 249 * @parent: parent to hook devices from, NULL for toplevel
252 * 250 *
253 * Note that children of the provided root are not instantiated as devices 251 * Note that children of the provided root are not instantiated as devices
@@ -258,50 +256,26 @@ int of_platform_bus_probe(struct device_node *root,
258 struct device *parent) 256 struct device *parent)
259{ 257{
260 struct device_node *child; 258 struct device_node *child;
261 struct platform_device *dev;
262 int rc = 0; 259 int rc = 0;
263 260
264 if (WARN_ON(!matches || matches == OF_NO_DEEP_PROBE)) 261 root = root ? of_node_get(root) : of_find_node_by_path("/");
265 return -EINVAL; 262 if (!root)
266 if (root == NULL)
267 root = of_find_node_by_path("/");
268 else
269 of_node_get(root);
270 if (root == NULL)
271 return -EINVAL; 263 return -EINVAL;
272 264
273 pr_debug("of_platform_bus_probe()\n"); 265 pr_debug("of_platform_bus_probe()\n");
274 pr_debug(" starting at: %s\n", root->full_name); 266 pr_debug(" starting at: %s\n", root->full_name);
275 267
276 /* Do a self check of bus type, if there's a match, create 268 /* Do a self check of bus type, if there's a match, create children */
277 * children
278 */
279 if (of_match_node(matches, root)) { 269 if (of_match_node(matches, root)) {
280 pr_debug(" root match, create all sub devices\n"); 270 rc = of_platform_bus_create(root, matches, parent);
281 dev = of_platform_device_create(root, NULL, parent); 271 } else for_each_child_of_node(root, child) {
282 if (dev == NULL)
283 goto bail;
284
285 pr_debug(" create all sub busses\n");
286 rc = of_platform_bus_create(root, matches, &dev->dev);
287 goto bail;
288 }
289 for_each_child_of_node(root, child) {
290 if (!of_match_node(matches, child)) 272 if (!of_match_node(matches, child))
291 continue; 273 continue;
292 274 rc = of_platform_bus_create(child, matches, parent);
293 pr_debug(" match: %s\n", child->full_name); 275 if (rc)
294 dev = of_platform_device_create(child, NULL, parent);
295 if (dev == NULL)
296 continue;
297
298 rc = of_platform_bus_create(child, matches, &dev->dev);
299 if (rc) {
300 of_node_put(child);
301 break; 276 break;
302 }
303 } 277 }
304 bail: 278
305 of_node_put(root); 279 of_node_put(root);
306 return rc; 280 return rc;
307} 281}
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
index 5c2b092a915e..5a4e0afb9ad6 100644
--- a/drivers/spi/amba-pl022.c
+++ b/drivers/spi/amba-pl022.c
@@ -324,6 +324,7 @@ struct vendor_data {
324 bool unidir; 324 bool unidir;
325 bool extended_cr; 325 bool extended_cr;
326 bool pl023; 326 bool pl023;
327 bool loopback;
327}; 328};
328 329
329/** 330/**
@@ -1983,7 +1984,7 @@ static int pl022_setup(struct spi_device *spi)
1983 1984
1984 SSP_WRITE_BITS(chip->cr0, clk_freq.scr, SSP_CR0_MASK_SCR, 8); 1985 SSP_WRITE_BITS(chip->cr0, clk_freq.scr, SSP_CR0_MASK_SCR, 8);
1985 /* Loopback is available on all versions except PL023 */ 1986 /* Loopback is available on all versions except PL023 */
1986 if (!pl022->vendor->pl023) { 1987 if (pl022->vendor->loopback) {
1987 if (spi->mode & SPI_LOOP) 1988 if (spi->mode & SPI_LOOP)
1988 tmp = LOOPBACK_ENABLED; 1989 tmp = LOOPBACK_ENABLED;
1989 else 1990 else
@@ -2233,6 +2234,7 @@ static struct vendor_data vendor_arm = {
2233 .unidir = false, 2234 .unidir = false,
2234 .extended_cr = false, 2235 .extended_cr = false,
2235 .pl023 = false, 2236 .pl023 = false,
2237 .loopback = true,
2236}; 2238};
2237 2239
2238 2240
@@ -2242,6 +2244,7 @@ static struct vendor_data vendor_st = {
2242 .unidir = false, 2244 .unidir = false,
2243 .extended_cr = true, 2245 .extended_cr = true,
2244 .pl023 = false, 2246 .pl023 = false,
2247 .loopback = true,
2245}; 2248};
2246 2249
2247static struct vendor_data vendor_st_pl023 = { 2250static struct vendor_data vendor_st_pl023 = {
@@ -2250,6 +2253,16 @@ static struct vendor_data vendor_st_pl023 = {
2250 .unidir = false, 2253 .unidir = false,
2251 .extended_cr = true, 2254 .extended_cr = true,
2252 .pl023 = true, 2255 .pl023 = true,
2256 .loopback = false,
2257};
2258
2259static struct vendor_data vendor_db5500_pl023 = {
2260 .fifodepth = 32,
2261 .max_bpw = 32,
2262 .unidir = false,
2263 .extended_cr = true,
2264 .pl023 = true,
2265 .loopback = true,
2253}; 2266};
2254 2267
2255static struct amba_id pl022_ids[] = { 2268static struct amba_id pl022_ids[] = {
@@ -2283,6 +2296,11 @@ static struct amba_id pl022_ids[] = {
2283 .mask = 0xffffffff, 2296 .mask = 0xffffffff,
2284 .data = &vendor_st_pl023, 2297 .data = &vendor_st_pl023,
2285 }, 2298 },
2299 {
2300 .id = 0x10080023,
2301 .mask = 0xffffffff,
2302 .data = &vendor_db5500_pl023,
2303 },
2286 { 0, 0 }, 2304 { 0, 0 },
2287}; 2305};
2288 2306
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 3a5ed06d3d2f..6f86ba0175ac 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -517,7 +517,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
517 dev_vdbg(&spi->dev, "read-%d %02x\n", 517 dev_vdbg(&spi->dev, "read-%d %02x\n",
518 word_len, *(rx - 1)); 518 word_len, *(rx - 1));
519 } 519 }
520 } while (c > (word_len>>3)); 520 } while (c);
521 } else if (word_len <= 16) { 521 } else if (word_len <= 16) {
522 u16 *rx; 522 u16 *rx;
523 const u16 *tx; 523 const u16 *tx;
@@ -564,7 +564,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
564 dev_vdbg(&spi->dev, "read-%d %04x\n", 564 dev_vdbg(&spi->dev, "read-%d %04x\n",
565 word_len, *(rx - 1)); 565 word_len, *(rx - 1));
566 } 566 }
567 } while (c > (word_len>>3)); 567 } while (c >= 2);
568 } else if (word_len <= 32) { 568 } else if (word_len <= 32) {
569 u32 *rx; 569 u32 *rx;
570 const u32 *tx; 570 const u32 *tx;
@@ -611,7 +611,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
611 dev_vdbg(&spi->dev, "read-%d %08x\n", 611 dev_vdbg(&spi->dev, "read-%d %08x\n",
612 word_len, *(rx - 1)); 612 word_len, *(rx - 1));
613 } 613 }
614 } while (c > (word_len>>3)); 614 } while (c >= 4);
615 } 615 }
616 616
617 /* for TX_ONLY mode, be sure all words have shifted out */ 617 /* for TX_ONLY mode, be sure all words have shifted out */