aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/common
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-01-29 04:31:31 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-03-24 07:30:12 -0400
commit09a2ba2fa0eba3da747db860ac1c8c0956665316 (patch)
treedc6ff8dccb13f30812dadeb24cb04633d95efaa9 /arch/arm/common
parent2213536d78a2ed96e870396b06ee53f4a54a1e42 (diff)
ARM: sa1111: register sa1111 devices with dmabounce in bus notifier
Use the bus notifier to register sa1111 devices with dmabounce, rather than after the device has been registered, potentially racing with driver binding. Acked-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/common')
-rw-r--r--arch/arm/common/sa1111.c129
1 files changed, 74 insertions, 55 deletions
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 17694cf64aa6..7b4351b28a5e 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -603,36 +603,6 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac,
603} 603}
604#endif 604#endif
605 605
606#ifdef CONFIG_DMABOUNCE
607/*
608 * According to the "Intel StrongARM SA-1111 Microprocessor Companion
609 * Chip Specification Update" (June 2000), erratum #7, there is a
610 * significant bug in the SA1111 SDRAM shared memory controller. If
611 * an access to a region of memory above 1MB relative to the bank base,
612 * it is important that address bit 10 _NOT_ be asserted. Depending
613 * on the configuration of the RAM, bit 10 may correspond to one
614 * of several different (processor-relative) address bits.
615 *
616 * This routine only identifies whether or not a given DMA address
617 * is susceptible to the bug.
618 *
619 * This should only get called for sa1111_device types due to the
620 * way we configure our device dma_masks.
621 */
622static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
623{
624 /*
625 * Section 4.6 of the "Intel StrongARM SA-1111 Development Module
626 * User's Guide" mentions that jumpers R51 and R52 control the
627 * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or
628 * SDRAM bank 1 on Neponset). The default configuration selects
629 * Assabet, so any address in bank 1 is necessarily invalid.
630 */
631 return (machine_is_assabet() || machine_is_pfs168()) &&
632 (addr >= 0xc8000000 || (addr + size) >= 0xc8000000);
633}
634#endif
635
636static void sa1111_dev_release(struct device *_dev) 606static void sa1111_dev_release(struct device *_dev)
637{ 607{
638 struct sa1111_dev *dev = SA1111_DEV(_dev); 608 struct sa1111_dev *dev = SA1111_DEV(_dev);
@@ -660,7 +630,6 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
660 dev->dev.parent = sachip->dev; 630 dev->dev.parent = sachip->dev;
661 dev->dev.bus = &sa1111_bus_type; 631 dev->dev.bus = &sa1111_bus_type;
662 dev->dev.release = sa1111_dev_release; 632 dev->dev.release = sa1111_dev_release;
663 dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask;
664 dev->res.start = sachip->phys + info->offset; 633 dev->res.start = sachip->phys + info->offset;
665 dev->res.end = dev->res.start + 511; 634 dev->res.end = dev->res.start + 511;
666 dev->res.name = dev_name(&dev->dev); 635 dev->res.name = dev_name(&dev->dev);
@@ -671,6 +640,16 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
671 for (i = 0; i < ARRAY_SIZE(info->irq); i++) 640 for (i = 0; i < ARRAY_SIZE(info->irq); i++)
672 dev->irq[i] = sachip->irq_base + info->irq[i]; 641 dev->irq[i] = sachip->irq_base + info->irq[i];
673 642
643 /*
644 * If the parent device has a DMA mask associated with it,
645 * propagate it down to the children.
646 */
647 if (sachip->dev->dma_mask) {
648 dev->dma_mask = *sachip->dev->dma_mask;
649 dev->dev.dma_mask = &dev->dma_mask;
650 dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask;
651 }
652
674 ret = request_resource(parent, &dev->res); 653 ret = request_resource(parent, &dev->res);
675 if (ret) { 654 if (ret) {
676 printk("SA1111: failed to allocate resource for %s\n", 655 printk("SA1111: failed to allocate resource for %s\n",
@@ -680,36 +659,12 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
680 goto out; 659 goto out;
681 } 660 }
682 661
683
684 ret = device_register(&dev->dev); 662 ret = device_register(&dev->dev);
685 if (ret) { 663 if (ret) {
686 release_resource(&dev->res); 664 release_resource(&dev->res);
687 kfree(dev); 665 kfree(dev);
688 goto out;
689 }
690
691#ifdef CONFIG_DMABOUNCE
692 /*
693 * If the parent device has a DMA mask associated with it,
694 * propagate it down to the children.
695 */
696 if (sachip->dev->dma_mask) {
697 dev->dma_mask = *sachip->dev->dma_mask;
698 dev->dev.dma_mask = &dev->dma_mask;
699
700 if (dev->dma_mask != 0xffffffffUL) {
701 ret = dmabounce_register_dev(&dev->dev, 1024, 4096,
702 sa1111_needs_bounce);
703 if (ret) {
704 dev_err(&dev->dev, "SA1111: Failed to register"
705 " with dmabounce\n");
706 device_unregister(&dev->dev);
707 }
708 }
709 } 666 }
710#endif
711 667
712out:
713 return ret; 668 return ret;
714} 669}
715 670
@@ -1411,9 +1366,70 @@ void sa1111_driver_unregister(struct sa1111_driver *driver)
1411} 1366}
1412EXPORT_SYMBOL(sa1111_driver_unregister); 1367EXPORT_SYMBOL(sa1111_driver_unregister);
1413 1368
1369#ifdef CONFIG_DMABOUNCE
1370/*
1371 * According to the "Intel StrongARM SA-1111 Microprocessor Companion
1372 * Chip Specification Update" (June 2000), erratum #7, there is a
1373 * significant bug in the SA1111 SDRAM shared memory controller. If
1374 * an access to a region of memory above 1MB relative to the bank base,
1375 * it is important that address bit 10 _NOT_ be asserted. Depending
1376 * on the configuration of the RAM, bit 10 may correspond to one
1377 * of several different (processor-relative) address bits.
1378 *
1379 * This routine only identifies whether or not a given DMA address
1380 * is susceptible to the bug.
1381 *
1382 * This should only get called for sa1111_device types due to the
1383 * way we configure our device dma_masks.
1384 */
1385static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
1386{
1387 /*
1388 * Section 4.6 of the "Intel StrongARM SA-1111 Development Module
1389 * User's Guide" mentions that jumpers R51 and R52 control the
1390 * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or
1391 * SDRAM bank 1 on Neponset). The default configuration selects
1392 * Assabet, so any address in bank 1 is necessarily invalid.
1393 */
1394 return (machine_is_assabet() || machine_is_pfs168()) &&
1395 (addr >= 0xc8000000 || (addr + size) >= 0xc8000000);
1396}
1397
1398static int sa1111_notifier_call(struct notifier_block *n, unsigned long action,
1399 void *data)
1400{
1401 struct sa1111_dev *dev = SA1111_DEV(data);
1402
1403 switch (action) {
1404 case BUS_NOTIFY_ADD_DEVICE:
1405 if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL) {
1406 int ret = dmabounce_register_dev(&dev->dev, 1024, 4096,
1407 sa1111_needs_bounce);
1408 if (ret)
1409 dev_err(&dev->dev, "failed to register with dmabounce: %d\n", ret);
1410 }
1411 break;
1412
1413 case BUS_NOTIFY_DEL_DEVICE:
1414 if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL)
1415 dmabounce_unregister_dev(&dev->dev);
1416 break;
1417 }
1418 return NOTIFY_OK;
1419}
1420
1421static struct notifier_block sa1111_bus_notifier = {
1422 .notifier_call = sa1111_notifier_call,
1423};
1424#endif
1425
1414static int __init sa1111_init(void) 1426static int __init sa1111_init(void)
1415{ 1427{
1416 int ret = bus_register(&sa1111_bus_type); 1428 int ret = bus_register(&sa1111_bus_type);
1429#ifdef CONFIG_DMABOUNCE
1430 if (ret == 0)
1431 bus_register_notifier(&sa1111_bus_type, &sa1111_bus_notifier);
1432#endif
1417 if (ret == 0) 1433 if (ret == 0)
1418 platform_driver_register(&sa1111_device_driver); 1434 platform_driver_register(&sa1111_device_driver);
1419 return ret; 1435 return ret;
@@ -1422,6 +1438,9 @@ static int __init sa1111_init(void)
1422static void __exit sa1111_exit(void) 1438static void __exit sa1111_exit(void)
1423{ 1439{
1424 platform_driver_unregister(&sa1111_device_driver); 1440 platform_driver_unregister(&sa1111_device_driver);
1441#ifdef CONFIG_DMABOUNCE
1442 bus_unregister_notifier(&sa1111_bus_type, &sa1111_bus_notifier);
1443#endif
1425 bus_unregister(&sa1111_bus_type); 1444 bus_unregister(&sa1111_bus_type);
1426} 1445}
1427 1446