diff options
37 files changed, 2588 insertions, 2188 deletions
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 61691cdbdcf2..9173d112ea01 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c | |||
@@ -16,6 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/irq.h> | ||
19 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
20 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
21 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
@@ -28,9 +29,8 @@ | |||
28 | #include <linux/io.h> | 29 | #include <linux/io.h> |
29 | 30 | ||
30 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
31 | #include <asm/mach-types.h> | ||
32 | #include <asm/irq.h> | ||
33 | #include <asm/mach/irq.h> | 32 | #include <asm/mach/irq.h> |
33 | #include <asm/mach-types.h> | ||
34 | #include <asm/sizes.h> | 34 | #include <asm/sizes.h> |
35 | 35 | ||
36 | #include <asm/hardware/sa1111.h> | 36 | #include <asm/hardware/sa1111.h> |
@@ -86,8 +86,10 @@ | |||
86 | #define IRQ_S1_CD_VALID (52) | 86 | #define IRQ_S1_CD_VALID (52) |
87 | #define IRQ_S0_BVD1_STSCHG (53) | 87 | #define IRQ_S0_BVD1_STSCHG (53) |
88 | #define IRQ_S1_BVD1_STSCHG (54) | 88 | #define IRQ_S1_BVD1_STSCHG (54) |
89 | #define SA1111_IRQ_NR (55) | ||
89 | 90 | ||
90 | extern void __init sa1110_mb_enable(void); | 91 | extern void sa1110_mb_enable(void); |
92 | extern void sa1110_mb_disable(void); | ||
91 | 93 | ||
92 | /* | 94 | /* |
93 | * We keep the following data for the overall SA1111. Note that the | 95 | * We keep the following data for the overall SA1111. Note that the |
@@ -104,6 +106,7 @@ struct sa1111 { | |||
104 | int irq_base; /* base for cascaded on-chip IRQs */ | 106 | int irq_base; /* base for cascaded on-chip IRQs */ |
105 | spinlock_t lock; | 107 | spinlock_t lock; |
106 | void __iomem *base; | 108 | void __iomem *base; |
109 | struct sa1111_platform_data *pdata; | ||
107 | #ifdef CONFIG_PM | 110 | #ifdef CONFIG_PM |
108 | void *saved_state; | 111 | void *saved_state; |
109 | #endif | 112 | #endif |
@@ -118,6 +121,7 @@ static struct sa1111 *g_sa1111; | |||
118 | struct sa1111_dev_info { | 121 | struct sa1111_dev_info { |
119 | unsigned long offset; | 122 | unsigned long offset; |
120 | unsigned long skpcr_mask; | 123 | unsigned long skpcr_mask; |
124 | bool dma; | ||
121 | unsigned int devid; | 125 | unsigned int devid; |
122 | unsigned int irq[6]; | 126 | unsigned int irq[6]; |
123 | }; | 127 | }; |
@@ -126,6 +130,7 @@ static struct sa1111_dev_info sa1111_devices[] = { | |||
126 | { | 130 | { |
127 | .offset = SA1111_USB, | 131 | .offset = SA1111_USB, |
128 | .skpcr_mask = SKPCR_UCLKEN, | 132 | .skpcr_mask = SKPCR_UCLKEN, |
133 | .dma = true, | ||
129 | .devid = SA1111_DEVID_USB, | 134 | .devid = SA1111_DEVID_USB, |
130 | .irq = { | 135 | .irq = { |
131 | IRQ_USBPWR, | 136 | IRQ_USBPWR, |
@@ -139,6 +144,7 @@ static struct sa1111_dev_info sa1111_devices[] = { | |||
139 | { | 144 | { |
140 | .offset = 0x0600, | 145 | .offset = 0x0600, |
141 | .skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN, | 146 | .skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN, |
147 | .dma = true, | ||
142 | .devid = SA1111_DEVID_SAC, | 148 | .devid = SA1111_DEVID_SAC, |
143 | .irq = { | 149 | .irq = { |
144 | AUDXMTDMADONEA, | 150 | AUDXMTDMADONEA, |
@@ -155,7 +161,7 @@ static struct sa1111_dev_info sa1111_devices[] = { | |||
155 | { | 161 | { |
156 | .offset = SA1111_KBD, | 162 | .offset = SA1111_KBD, |
157 | .skpcr_mask = SKPCR_PTCLKEN, | 163 | .skpcr_mask = SKPCR_PTCLKEN, |
158 | .devid = SA1111_DEVID_PS2, | 164 | .devid = SA1111_DEVID_PS2_KBD, |
159 | .irq = { | 165 | .irq = { |
160 | IRQ_TPRXINT, | 166 | IRQ_TPRXINT, |
161 | IRQ_TPTXINT | 167 | IRQ_TPTXINT |
@@ -164,7 +170,7 @@ static struct sa1111_dev_info sa1111_devices[] = { | |||
164 | { | 170 | { |
165 | .offset = SA1111_MSE, | 171 | .offset = SA1111_MSE, |
166 | .skpcr_mask = SKPCR_PMCLKEN, | 172 | .skpcr_mask = SKPCR_PMCLKEN, |
167 | .devid = SA1111_DEVID_PS2, | 173 | .devid = SA1111_DEVID_PS2_MSE, |
168 | .irq = { | 174 | .irq = { |
169 | IRQ_MSRXINT, | 175 | IRQ_MSRXINT, |
170 | IRQ_MSTXINT | 176 | IRQ_MSTXINT |
@@ -434,16 +440,28 @@ static struct irq_chip sa1111_high_chip = { | |||
434 | .irq_set_wake = sa1111_wake_highirq, | 440 | .irq_set_wake = sa1111_wake_highirq, |
435 | }; | 441 | }; |
436 | 442 | ||
437 | static void sa1111_setup_irq(struct sa1111 *sachip) | 443 | static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base) |
438 | { | 444 | { |
439 | void __iomem *irqbase = sachip->base + SA1111_INTC; | 445 | void __iomem *irqbase = sachip->base + SA1111_INTC; |
440 | unsigned int irq; | 446 | unsigned i, irq; |
447 | int ret; | ||
441 | 448 | ||
442 | /* | 449 | /* |
443 | * We're guaranteed that this region hasn't been taken. | 450 | * We're guaranteed that this region hasn't been taken. |
444 | */ | 451 | */ |
445 | request_mem_region(sachip->phys + SA1111_INTC, 512, "irq"); | 452 | request_mem_region(sachip->phys + SA1111_INTC, 512, "irq"); |
446 | 453 | ||
454 | ret = irq_alloc_descs(-1, irq_base, SA1111_IRQ_NR, -1); | ||
455 | if (ret <= 0) { | ||
456 | dev_err(sachip->dev, "unable to allocate %u irqs: %d\n", | ||
457 | SA1111_IRQ_NR, ret); | ||
458 | if (ret == 0) | ||
459 | ret = -EINVAL; | ||
460 | return ret; | ||
461 | } | ||
462 | |||
463 | sachip->irq_base = ret; | ||
464 | |||
447 | /* disable all IRQs */ | 465 | /* disable all IRQs */ |
448 | sa1111_writel(0, irqbase + SA1111_INTEN0); | 466 | sa1111_writel(0, irqbase + SA1111_INTEN0); |
449 | sa1111_writel(0, irqbase + SA1111_INTEN1); | 467 | sa1111_writel(0, irqbase + SA1111_INTEN1); |
@@ -463,14 +481,16 @@ static void sa1111_setup_irq(struct sa1111 *sachip) | |||
463 | sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0); | 481 | sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0); |
464 | sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1); | 482 | sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1); |
465 | 483 | ||
466 | for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) { | 484 | for (i = IRQ_GPAIN0; i <= SSPROR; i++) { |
485 | irq = sachip->irq_base + i; | ||
467 | irq_set_chip_and_handler(irq, &sa1111_low_chip, | 486 | irq_set_chip_and_handler(irq, &sa1111_low_chip, |
468 | handle_edge_irq); | 487 | handle_edge_irq); |
469 | irq_set_chip_data(irq, sachip); | 488 | irq_set_chip_data(irq, sachip); |
470 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 489 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
471 | } | 490 | } |
472 | 491 | ||
473 | for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) { | 492 | for (i = AUDXMTDMADONEA; i <= IRQ_S1_BVD1_STSCHG; i++) { |
493 | irq = sachip->irq_base + i; | ||
474 | irq_set_chip_and_handler(irq, &sa1111_high_chip, | 494 | irq_set_chip_and_handler(irq, &sa1111_high_chip, |
475 | handle_edge_irq); | 495 | handle_edge_irq); |
476 | irq_set_chip_data(irq, sachip); | 496 | irq_set_chip_data(irq, sachip); |
@@ -483,6 +503,11 @@ static void sa1111_setup_irq(struct sa1111 *sachip) | |||
483 | irq_set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING); | 503 | irq_set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING); |
484 | irq_set_handler_data(sachip->irq, sachip); | 504 | irq_set_handler_data(sachip->irq, sachip); |
485 | irq_set_chained_handler(sachip->irq, sa1111_irq_handler); | 505 | irq_set_chained_handler(sachip->irq, sa1111_irq_handler); |
506 | |||
507 | dev_info(sachip->dev, "Providing IRQ%u-%u\n", | ||
508 | sachip->irq_base, sachip->irq_base + SA1111_IRQ_NR - 1); | ||
509 | |||
510 | return 0; | ||
486 | } | 511 | } |
487 | 512 | ||
488 | /* | 513 | /* |
@@ -581,41 +606,10 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac, | |||
581 | } | 606 | } |
582 | #endif | 607 | #endif |
583 | 608 | ||
584 | #ifdef CONFIG_DMABOUNCE | ||
585 | /* | ||
586 | * According to the "Intel StrongARM SA-1111 Microprocessor Companion | ||
587 | * Chip Specification Update" (June 2000), erratum #7, there is a | ||
588 | * significant bug in the SA1111 SDRAM shared memory controller. If | ||
589 | * an access to a region of memory above 1MB relative to the bank base, | ||
590 | * it is important that address bit 10 _NOT_ be asserted. Depending | ||
591 | * on the configuration of the RAM, bit 10 may correspond to one | ||
592 | * of several different (processor-relative) address bits. | ||
593 | * | ||
594 | * This routine only identifies whether or not a given DMA address | ||
595 | * is susceptible to the bug. | ||
596 | * | ||
597 | * This should only get called for sa1111_device types due to the | ||
598 | * way we configure our device dma_masks. | ||
599 | */ | ||
600 | static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size) | ||
601 | { | ||
602 | /* | ||
603 | * Section 4.6 of the "Intel StrongARM SA-1111 Development Module | ||
604 | * User's Guide" mentions that jumpers R51 and R52 control the | ||
605 | * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or | ||
606 | * SDRAM bank 1 on Neponset). The default configuration selects | ||
607 | * Assabet, so any address in bank 1 is necessarily invalid. | ||
608 | */ | ||
609 | return (machine_is_assabet() || machine_is_pfs168()) && | ||
610 | (addr >= 0xc8000000 || (addr + size) >= 0xc8000000); | ||
611 | } | ||
612 | #endif | ||
613 | |||
614 | static void sa1111_dev_release(struct device *_dev) | 609 | static void sa1111_dev_release(struct device *_dev) |
615 | { | 610 | { |
616 | struct sa1111_dev *dev = SA1111_DEV(_dev); | 611 | struct sa1111_dev *dev = SA1111_DEV(_dev); |
617 | 612 | ||
618 | release_resource(&dev->res); | ||
619 | kfree(dev); | 613 | kfree(dev); |
620 | } | 614 | } |
621 | 615 | ||
@@ -624,67 +618,58 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, | |||
624 | struct sa1111_dev_info *info) | 618 | struct sa1111_dev_info *info) |
625 | { | 619 | { |
626 | struct sa1111_dev *dev; | 620 | struct sa1111_dev *dev; |
621 | unsigned i; | ||
627 | int ret; | 622 | int ret; |
628 | 623 | ||
629 | dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL); | 624 | dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL); |
630 | if (!dev) { | 625 | if (!dev) { |
631 | ret = -ENOMEM; | 626 | ret = -ENOMEM; |
632 | goto out; | 627 | goto err_alloc; |
633 | } | 628 | } |
634 | 629 | ||
630 | device_initialize(&dev->dev); | ||
635 | dev_set_name(&dev->dev, "%4.4lx", info->offset); | 631 | dev_set_name(&dev->dev, "%4.4lx", info->offset); |
636 | dev->devid = info->devid; | 632 | dev->devid = info->devid; |
637 | dev->dev.parent = sachip->dev; | 633 | dev->dev.parent = sachip->dev; |
638 | dev->dev.bus = &sa1111_bus_type; | 634 | dev->dev.bus = &sa1111_bus_type; |
639 | dev->dev.release = sa1111_dev_release; | 635 | dev->dev.release = sa1111_dev_release; |
640 | dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask; | ||
641 | dev->res.start = sachip->phys + info->offset; | 636 | dev->res.start = sachip->phys + info->offset; |
642 | dev->res.end = dev->res.start + 511; | 637 | dev->res.end = dev->res.start + 511; |
643 | dev->res.name = dev_name(&dev->dev); | 638 | dev->res.name = dev_name(&dev->dev); |
644 | dev->res.flags = IORESOURCE_MEM; | 639 | dev->res.flags = IORESOURCE_MEM; |
645 | dev->mapbase = sachip->base + info->offset; | 640 | dev->mapbase = sachip->base + info->offset; |
646 | dev->skpcr_mask = info->skpcr_mask; | 641 | dev->skpcr_mask = info->skpcr_mask; |
647 | memmove(dev->irq, info->irq, sizeof(dev->irq)); | ||
648 | |||
649 | ret = request_resource(parent, &dev->res); | ||
650 | if (ret) { | ||
651 | printk("SA1111: failed to allocate resource for %s\n", | ||
652 | dev->res.name); | ||
653 | dev_set_name(&dev->dev, NULL); | ||
654 | kfree(dev); | ||
655 | goto out; | ||
656 | } | ||
657 | |||
658 | 642 | ||
659 | ret = device_register(&dev->dev); | 643 | for (i = 0; i < ARRAY_SIZE(info->irq); i++) |
660 | if (ret) { | 644 | dev->irq[i] = sachip->irq_base + info->irq[i]; |
661 | release_resource(&dev->res); | ||
662 | kfree(dev); | ||
663 | goto out; | ||
664 | } | ||
665 | 645 | ||
666 | #ifdef CONFIG_DMABOUNCE | ||
667 | /* | 646 | /* |
668 | * If the parent device has a DMA mask associated with it, | 647 | * If the parent device has a DMA mask associated with it, and |
669 | * propagate it down to the children. | 648 | * this child supports DMA, propagate it down to the children. |
670 | */ | 649 | */ |
671 | if (sachip->dev->dma_mask) { | 650 | if (info->dma && sachip->dev->dma_mask) { |
672 | dev->dma_mask = *sachip->dev->dma_mask; | 651 | dev->dma_mask = *sachip->dev->dma_mask; |
673 | dev->dev.dma_mask = &dev->dma_mask; | 652 | dev->dev.dma_mask = &dev->dma_mask; |
653 | dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask; | ||
654 | } | ||
674 | 655 | ||
675 | if (dev->dma_mask != 0xffffffffUL) { | 656 | ret = request_resource(parent, &dev->res); |
676 | ret = dmabounce_register_dev(&dev->dev, 1024, 4096, | 657 | if (ret) { |
677 | sa1111_needs_bounce); | 658 | dev_err(sachip->dev, "failed to allocate resource for %s\n", |
678 | if (ret) { | 659 | dev->res.name); |
679 | dev_err(&dev->dev, "SA1111: Failed to register" | 660 | goto err_resource; |
680 | " with dmabounce\n"); | ||
681 | device_unregister(&dev->dev); | ||
682 | } | ||
683 | } | ||
684 | } | 661 | } |
685 | #endif | ||
686 | 662 | ||
687 | out: | 663 | ret = device_add(&dev->dev); |
664 | if (ret) | ||
665 | goto err_add; | ||
666 | return 0; | ||
667 | |||
668 | err_add: | ||
669 | release_resource(&dev->res); | ||
670 | err_resource: | ||
671 | put_device(&dev->dev); | ||
672 | err_alloc: | ||
688 | return ret; | 673 | return ret; |
689 | } | 674 | } |
690 | 675 | ||
@@ -698,16 +683,21 @@ out: | |||
698 | * Returns: | 683 | * Returns: |
699 | * %-ENODEV device not found. | 684 | * %-ENODEV device not found. |
700 | * %-EBUSY physical address already marked in-use. | 685 | * %-EBUSY physical address already marked in-use. |
686 | * %-EINVAL no platform data passed | ||
701 | * %0 successful. | 687 | * %0 successful. |
702 | */ | 688 | */ |
703 | static int __devinit | 689 | static int __devinit |
704 | __sa1111_probe(struct device *me, struct resource *mem, int irq) | 690 | __sa1111_probe(struct device *me, struct resource *mem, int irq) |
705 | { | 691 | { |
692 | struct sa1111_platform_data *pd = me->platform_data; | ||
706 | struct sa1111 *sachip; | 693 | struct sa1111 *sachip; |
707 | unsigned long id; | 694 | unsigned long id; |
708 | unsigned int has_devs; | 695 | unsigned int has_devs; |
709 | int i, ret = -ENODEV; | 696 | int i, ret = -ENODEV; |
710 | 697 | ||
698 | if (!pd) | ||
699 | return -EINVAL; | ||
700 | |||
711 | sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL); | 701 | sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL); |
712 | if (!sachip) | 702 | if (!sachip) |
713 | return -ENOMEM; | 703 | return -ENOMEM; |
@@ -727,6 +717,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) | |||
727 | sachip->dev = me; | 717 | sachip->dev = me; |
728 | dev_set_drvdata(sachip->dev, sachip); | 718 | dev_set_drvdata(sachip->dev, sachip); |
729 | 719 | ||
720 | sachip->pdata = pd; | ||
730 | sachip->phys = mem->start; | 721 | sachip->phys = mem->start; |
731 | sachip->irq = irq; | 722 | sachip->irq = irq; |
732 | 723 | ||
@@ -759,6 +750,16 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) | |||
759 | */ | 750 | */ |
760 | sa1111_wake(sachip); | 751 | sa1111_wake(sachip); |
761 | 752 | ||
753 | /* | ||
754 | * The interrupt controller must be initialised before any | ||
755 | * other device to ensure that the interrupts are available. | ||
756 | */ | ||
757 | if (sachip->irq != NO_IRQ) { | ||
758 | ret = sa1111_setup_irq(sachip, pd->irq_base); | ||
759 | if (ret) | ||
760 | goto err_unmap; | ||
761 | } | ||
762 | |||
762 | #ifdef CONFIG_ARCH_SA1100 | 763 | #ifdef CONFIG_ARCH_SA1100 |
763 | { | 764 | { |
764 | unsigned int val; | 765 | unsigned int val; |
@@ -789,24 +790,14 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) | |||
789 | } | 790 | } |
790 | #endif | 791 | #endif |
791 | 792 | ||
792 | /* | ||
793 | * The interrupt controller must be initialised before any | ||
794 | * other device to ensure that the interrupts are available. | ||
795 | */ | ||
796 | if (sachip->irq != NO_IRQ) | ||
797 | sa1111_setup_irq(sachip); | ||
798 | |||
799 | g_sa1111 = sachip; | 793 | g_sa1111 = sachip; |
800 | 794 | ||
801 | has_devs = ~0; | 795 | has_devs = ~0; |
802 | if (machine_is_assabet() || machine_is_jornada720() || | 796 | if (pd) |
803 | machine_is_badge4()) | 797 | has_devs &= ~pd->disable_devs; |
804 | has_devs &= ~(1 << 4); | ||
805 | else | ||
806 | has_devs &= ~(1 << 1); | ||
807 | 798 | ||
808 | for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++) | 799 | for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++) |
809 | if (has_devs & (1 << i)) | 800 | if (sa1111_devices[i].devid & has_devs) |
810 | sa1111_init_one_child(sachip, mem, &sa1111_devices[i]); | 801 | sa1111_init_one_child(sachip, mem, &sa1111_devices[i]); |
811 | 802 | ||
812 | return 0; | 803 | return 0; |
@@ -824,7 +815,10 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) | |||
824 | 815 | ||
825 | static int sa1111_remove_one(struct device *dev, void *data) | 816 | static int sa1111_remove_one(struct device *dev, void *data) |
826 | { | 817 | { |
827 | device_unregister(dev); | 818 | struct sa1111_dev *sadev = SA1111_DEV(dev); |
819 | device_del(&sadev->dev); | ||
820 | release_resource(&sadev->res); | ||
821 | put_device(&sadev->dev); | ||
828 | return 0; | 822 | return 0; |
829 | } | 823 | } |
830 | 824 | ||
@@ -846,6 +840,7 @@ static void __sa1111_remove(struct sa1111 *sachip) | |||
846 | if (sachip->irq != NO_IRQ) { | 840 | if (sachip->irq != NO_IRQ) { |
847 | irq_set_chained_handler(sachip->irq, NULL); | 841 | irq_set_chained_handler(sachip->irq, NULL); |
848 | irq_set_handler_data(sachip->irq, NULL); | 842 | irq_set_handler_data(sachip->irq, NULL); |
843 | irq_free_descs(sachip->irq_base, SA1111_IRQ_NR); | ||
849 | 844 | ||
850 | release_mem_region(sachip->phys + SA1111_INTC, 512); | 845 | release_mem_region(sachip->phys + SA1111_INTC, 512); |
851 | } | 846 | } |
@@ -904,6 +899,9 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state) | |||
904 | save->skpwm0 = sa1111_readl(base + SA1111_SKPWM0); | 899 | save->skpwm0 = sa1111_readl(base + SA1111_SKPWM0); |
905 | save->skpwm1 = sa1111_readl(base + SA1111_SKPWM1); | 900 | save->skpwm1 = sa1111_readl(base + SA1111_SKPWM1); |
906 | 901 | ||
902 | sa1111_writel(0, sachip->base + SA1111_SKPWM0); | ||
903 | sa1111_writel(0, sachip->base + SA1111_SKPWM1); | ||
904 | |||
907 | base = sachip->base + SA1111_INTC; | 905 | base = sachip->base + SA1111_INTC; |
908 | save->intpol0 = sa1111_readl(base + SA1111_INTPOL0); | 906 | save->intpol0 = sa1111_readl(base + SA1111_INTPOL0); |
909 | save->intpol1 = sa1111_readl(base + SA1111_INTPOL1); | 907 | save->intpol1 = sa1111_readl(base + SA1111_INTPOL1); |
@@ -919,13 +917,15 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state) | |||
919 | */ | 917 | */ |
920 | val = sa1111_readl(sachip->base + SA1111_SKCR); | 918 | val = sa1111_readl(sachip->base + SA1111_SKCR); |
921 | sa1111_writel(val | SKCR_SLEEP, sachip->base + SA1111_SKCR); | 919 | sa1111_writel(val | SKCR_SLEEP, sachip->base + SA1111_SKCR); |
922 | sa1111_writel(0, sachip->base + SA1111_SKPWM0); | ||
923 | sa1111_writel(0, sachip->base + SA1111_SKPWM1); | ||
924 | 920 | ||
925 | clk_disable(sachip->clk); | 921 | clk_disable(sachip->clk); |
926 | 922 | ||
927 | spin_unlock_irqrestore(&sachip->lock, flags); | 923 | spin_unlock_irqrestore(&sachip->lock, flags); |
928 | 924 | ||
925 | #ifdef CONFIG_ARCH_SA1100 | ||
926 | sa1110_mb_disable(); | ||
927 | #endif | ||
928 | |||
929 | return 0; | 929 | return 0; |
930 | } | 930 | } |
931 | 931 | ||
@@ -966,6 +966,11 @@ static int sa1111_resume(struct platform_device *dev) | |||
966 | */ | 966 | */ |
967 | sa1111_wake(sachip); | 967 | sa1111_wake(sachip); |
968 | 968 | ||
969 | #ifdef CONFIG_ARCH_SA1100 | ||
970 | /* Enable the memory bus request/grant signals */ | ||
971 | sa1110_mb_enable(); | ||
972 | #endif | ||
973 | |||
969 | /* | 974 | /* |
970 | * Only lock for write ops. Also, sa1111_wake must be called with | 975 | * Only lock for write ops. Also, sa1111_wake must be called with |
971 | * released spinlock! | 976 | * released spinlock! |
@@ -1053,6 +1058,7 @@ static struct platform_driver sa1111_device_driver = { | |||
1053 | .resume = sa1111_resume, | 1058 | .resume = sa1111_resume, |
1054 | .driver = { | 1059 | .driver = { |
1055 | .name = "sa1111", | 1060 | .name = "sa1111", |
1061 | .owner = THIS_MODULE, | ||
1056 | }, | 1062 | }, |
1057 | }; | 1063 | }; |
1058 | 1064 | ||
@@ -1238,16 +1244,23 @@ EXPORT_SYMBOL(sa1111_set_sleep_io); | |||
1238 | * sa1111_enable_device - enable an on-chip SA1111 function block | 1244 | * sa1111_enable_device - enable an on-chip SA1111 function block |
1239 | * @sadev: SA1111 function block device to enable | 1245 | * @sadev: SA1111 function block device to enable |
1240 | */ | 1246 | */ |
1241 | void sa1111_enable_device(struct sa1111_dev *sadev) | 1247 | int sa1111_enable_device(struct sa1111_dev *sadev) |
1242 | { | 1248 | { |
1243 | struct sa1111 *sachip = sa1111_chip_driver(sadev); | 1249 | struct sa1111 *sachip = sa1111_chip_driver(sadev); |
1244 | unsigned long flags; | 1250 | unsigned long flags; |
1245 | unsigned int val; | 1251 | unsigned int val; |
1252 | int ret = 0; | ||
1246 | 1253 | ||
1247 | spin_lock_irqsave(&sachip->lock, flags); | 1254 | if (sachip->pdata && sachip->pdata->enable) |
1248 | val = sa1111_readl(sachip->base + SA1111_SKPCR); | 1255 | ret = sachip->pdata->enable(sachip->pdata->data, sadev->devid); |
1249 | sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR); | 1256 | |
1250 | spin_unlock_irqrestore(&sachip->lock, flags); | 1257 | if (ret == 0) { |
1258 | spin_lock_irqsave(&sachip->lock, flags); | ||
1259 | val = sa1111_readl(sachip->base + SA1111_SKPCR); | ||
1260 | sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR); | ||
1261 | spin_unlock_irqrestore(&sachip->lock, flags); | ||
1262 | } | ||
1263 | return ret; | ||
1251 | } | 1264 | } |
1252 | EXPORT_SYMBOL(sa1111_enable_device); | 1265 | EXPORT_SYMBOL(sa1111_enable_device); |
1253 | 1266 | ||
@@ -1265,6 +1278,9 @@ void sa1111_disable_device(struct sa1111_dev *sadev) | |||
1265 | val = sa1111_readl(sachip->base + SA1111_SKPCR); | 1278 | val = sa1111_readl(sachip->base + SA1111_SKPCR); |
1266 | sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR); | 1279 | sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR); |
1267 | spin_unlock_irqrestore(&sachip->lock, flags); | 1280 | spin_unlock_irqrestore(&sachip->lock, flags); |
1281 | |||
1282 | if (sachip->pdata && sachip->pdata->disable) | ||
1283 | sachip->pdata->disable(sachip->pdata->data, sadev->devid); | ||
1268 | } | 1284 | } |
1269 | EXPORT_SYMBOL(sa1111_disable_device); | 1285 | EXPORT_SYMBOL(sa1111_disable_device); |
1270 | 1286 | ||
@@ -1279,7 +1295,7 @@ static int sa1111_match(struct device *_dev, struct device_driver *_drv) | |||
1279 | struct sa1111_dev *dev = SA1111_DEV(_dev); | 1295 | struct sa1111_dev *dev = SA1111_DEV(_dev); |
1280 | struct sa1111_driver *drv = SA1111_DRV(_drv); | 1296 | struct sa1111_driver *drv = SA1111_DRV(_drv); |
1281 | 1297 | ||
1282 | return dev->devid == drv->devid; | 1298 | return dev->devid & drv->devid; |
1283 | } | 1299 | } |
1284 | 1300 | ||
1285 | static int sa1111_bus_suspend(struct device *dev, pm_message_t state) | 1301 | static int sa1111_bus_suspend(struct device *dev, pm_message_t state) |
@@ -1304,6 +1320,14 @@ static int sa1111_bus_resume(struct device *dev) | |||
1304 | return ret; | 1320 | return ret; |
1305 | } | 1321 | } |
1306 | 1322 | ||
1323 | static void sa1111_bus_shutdown(struct device *dev) | ||
1324 | { | ||
1325 | struct sa1111_driver *drv = SA1111_DRV(dev->driver); | ||
1326 | |||
1327 | if (drv && drv->shutdown) | ||
1328 | drv->shutdown(SA1111_DEV(dev)); | ||
1329 | } | ||
1330 | |||
1307 | static int sa1111_bus_probe(struct device *dev) | 1331 | static int sa1111_bus_probe(struct device *dev) |
1308 | { | 1332 | { |
1309 | struct sa1111_dev *sadev = SA1111_DEV(dev); | 1333 | struct sa1111_dev *sadev = SA1111_DEV(dev); |
@@ -1333,6 +1357,7 @@ struct bus_type sa1111_bus_type = { | |||
1333 | .remove = sa1111_bus_remove, | 1357 | .remove = sa1111_bus_remove, |
1334 | .suspend = sa1111_bus_suspend, | 1358 | .suspend = sa1111_bus_suspend, |
1335 | .resume = sa1111_bus_resume, | 1359 | .resume = sa1111_bus_resume, |
1360 | .shutdown = sa1111_bus_shutdown, | ||
1336 | }; | 1361 | }; |
1337 | EXPORT_SYMBOL(sa1111_bus_type); | 1362 | EXPORT_SYMBOL(sa1111_bus_type); |
1338 | 1363 | ||
@@ -1349,9 +1374,70 @@ void sa1111_driver_unregister(struct sa1111_driver *driver) | |||
1349 | } | 1374 | } |
1350 | EXPORT_SYMBOL(sa1111_driver_unregister); | 1375 | EXPORT_SYMBOL(sa1111_driver_unregister); |
1351 | 1376 | ||
1377 | #ifdef CONFIG_DMABOUNCE | ||
1378 | /* | ||
1379 | * According to the "Intel StrongARM SA-1111 Microprocessor Companion | ||
1380 | * Chip Specification Update" (June 2000), erratum #7, there is a | ||
1381 | * significant bug in the SA1111 SDRAM shared memory controller. If | ||
1382 | * an access to a region of memory above 1MB relative to the bank base, | ||
1383 | * it is important that address bit 10 _NOT_ be asserted. Depending | ||
1384 | * on the configuration of the RAM, bit 10 may correspond to one | ||
1385 | * of several different (processor-relative) address bits. | ||
1386 | * | ||
1387 | * This routine only identifies whether or not a given DMA address | ||
1388 | * is susceptible to the bug. | ||
1389 | * | ||
1390 | * This should only get called for sa1111_device types due to the | ||
1391 | * way we configure our device dma_masks. | ||
1392 | */ | ||
1393 | static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size) | ||
1394 | { | ||
1395 | /* | ||
1396 | * Section 4.6 of the "Intel StrongARM SA-1111 Development Module | ||
1397 | * User's Guide" mentions that jumpers R51 and R52 control the | ||
1398 | * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or | ||
1399 | * SDRAM bank 1 on Neponset). The default configuration selects | ||
1400 | * Assabet, so any address in bank 1 is necessarily invalid. | ||
1401 | */ | ||
1402 | return (machine_is_assabet() || machine_is_pfs168()) && | ||
1403 | (addr >= 0xc8000000 || (addr + size) >= 0xc8000000); | ||
1404 | } | ||
1405 | |||
1406 | static int sa1111_notifier_call(struct notifier_block *n, unsigned long action, | ||
1407 | void *data) | ||
1408 | { | ||
1409 | struct sa1111_dev *dev = SA1111_DEV(data); | ||
1410 | |||
1411 | switch (action) { | ||
1412 | case BUS_NOTIFY_ADD_DEVICE: | ||
1413 | if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL) { | ||
1414 | int ret = dmabounce_register_dev(&dev->dev, 1024, 4096, | ||
1415 | sa1111_needs_bounce); | ||
1416 | if (ret) | ||
1417 | dev_err(&dev->dev, "failed to register with dmabounce: %d\n", ret); | ||
1418 | } | ||
1419 | break; | ||
1420 | |||
1421 | case BUS_NOTIFY_DEL_DEVICE: | ||
1422 | if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL) | ||
1423 | dmabounce_unregister_dev(&dev->dev); | ||
1424 | break; | ||
1425 | } | ||
1426 | return NOTIFY_OK; | ||
1427 | } | ||
1428 | |||
1429 | static struct notifier_block sa1111_bus_notifier = { | ||
1430 | .notifier_call = sa1111_notifier_call, | ||
1431 | }; | ||
1432 | #endif | ||
1433 | |||
1352 | static int __init sa1111_init(void) | 1434 | static int __init sa1111_init(void) |
1353 | { | 1435 | { |
1354 | int ret = bus_register(&sa1111_bus_type); | 1436 | int ret = bus_register(&sa1111_bus_type); |
1437 | #ifdef CONFIG_DMABOUNCE | ||
1438 | if (ret == 0) | ||
1439 | bus_register_notifier(&sa1111_bus_type, &sa1111_bus_notifier); | ||
1440 | #endif | ||
1355 | if (ret == 0) | 1441 | if (ret == 0) |
1356 | platform_driver_register(&sa1111_device_driver); | 1442 | platform_driver_register(&sa1111_device_driver); |
1357 | return ret; | 1443 | return ret; |
@@ -1360,6 +1446,9 @@ static int __init sa1111_init(void) | |||
1360 | static void __exit sa1111_exit(void) | 1446 | static void __exit sa1111_exit(void) |
1361 | { | 1447 | { |
1362 | platform_driver_unregister(&sa1111_device_driver); | 1448 | platform_driver_unregister(&sa1111_device_driver); |
1449 | #ifdef CONFIG_DMABOUNCE | ||
1450 | bus_unregister_notifier(&sa1111_bus_type, &sa1111_bus_notifier); | ||
1451 | #endif | ||
1363 | bus_unregister(&sa1111_bus_type); | 1452 | bus_unregister(&sa1111_bus_type); |
1364 | } | 1453 | } |
1365 | 1454 | ||
diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h index 92ed254c175b..7c2bbc7f0be1 100644 --- a/arch/arm/include/asm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h | |||
@@ -132,34 +132,10 @@ | |||
132 | #define SKPCR_DCLKEN (1<<7) | 132 | #define SKPCR_DCLKEN (1<<7) |
133 | #define SKPCR_PWMCLKEN (1<<8) | 133 | #define SKPCR_PWMCLKEN (1<<8) |
134 | 134 | ||
135 | /* | 135 | /* USB Host controller */ |
136 | * USB Host controller | ||
137 | */ | ||
138 | #define SA1111_USB 0x0400 | 136 | #define SA1111_USB 0x0400 |
139 | 137 | ||
140 | /* | 138 | /* |
141 | * Offsets from SA1111_USB_BASE | ||
142 | */ | ||
143 | #define SA1111_USB_STATUS 0x0118 | ||
144 | #define SA1111_USB_RESET 0x011c | ||
145 | #define SA1111_USB_IRQTEST 0x0120 | ||
146 | |||
147 | #define USB_RESET_FORCEIFRESET (1 << 0) | ||
148 | #define USB_RESET_FORCEHCRESET (1 << 1) | ||
149 | #define USB_RESET_CLKGENRESET (1 << 2) | ||
150 | #define USB_RESET_SIMSCALEDOWN (1 << 3) | ||
151 | #define USB_RESET_USBINTTEST (1 << 4) | ||
152 | #define USB_RESET_SLEEPSTBYEN (1 << 5) | ||
153 | #define USB_RESET_PWRSENSELOW (1 << 6) | ||
154 | #define USB_RESET_PWRCTRLLOW (1 << 7) | ||
155 | |||
156 | #define USB_STATUS_IRQHCIRMTWKUP (1 << 7) | ||
157 | #define USB_STATUS_IRQHCIBUFFACC (1 << 8) | ||
158 | #define USB_STATUS_NIRQHCIM (1 << 9) | ||
159 | #define USB_STATUS_NHCIMFCLR (1 << 10) | ||
160 | #define USB_STATUS_USBPWRSENSE (1 << 11) | ||
161 | |||
162 | /* | ||
163 | * Serial Audio Controller | 139 | * Serial Audio Controller |
164 | * | 140 | * |
165 | * Registers | 141 | * Registers |
@@ -327,22 +303,6 @@ | |||
327 | * PC_SSR GPIO Block C Sleep State | 303 | * PC_SSR GPIO Block C Sleep State |
328 | */ | 304 | */ |
329 | 305 | ||
330 | #define _PA_DDR _SA1111( 0x1000 ) | ||
331 | #define _PA_DRR _SA1111( 0x1004 ) | ||
332 | #define _PA_DWR _SA1111( 0x1004 ) | ||
333 | #define _PA_SDR _SA1111( 0x1008 ) | ||
334 | #define _PA_SSR _SA1111( 0x100c ) | ||
335 | #define _PB_DDR _SA1111( 0x1010 ) | ||
336 | #define _PB_DRR _SA1111( 0x1014 ) | ||
337 | #define _PB_DWR _SA1111( 0x1014 ) | ||
338 | #define _PB_SDR _SA1111( 0x1018 ) | ||
339 | #define _PB_SSR _SA1111( 0x101c ) | ||
340 | #define _PC_DDR _SA1111( 0x1020 ) | ||
341 | #define _PC_DRR _SA1111( 0x1024 ) | ||
342 | #define _PC_DWR _SA1111( 0x1024 ) | ||
343 | #define _PC_SDR _SA1111( 0x1028 ) | ||
344 | #define _PC_SSR _SA1111( 0x102c ) | ||
345 | |||
346 | #define SA1111_GPIO 0x1000 | 306 | #define SA1111_GPIO 0x1000 |
347 | 307 | ||
348 | #define SA1111_GPIO_PADDR (0x000) | 308 | #define SA1111_GPIO_PADDR (0x000) |
@@ -425,106 +385,30 @@ | |||
425 | #define SA1111_WAKEPOL0 0x0034 | 385 | #define SA1111_WAKEPOL0 0x0034 |
426 | #define SA1111_WAKEPOL1 0x0038 | 386 | #define SA1111_WAKEPOL1 0x0038 |
427 | 387 | ||
428 | /* | 388 | /* PS/2 Trackpad and Mouse Interfaces */ |
429 | * PS/2 Trackpad and Mouse Interfaces | ||
430 | * | ||
431 | * Registers | ||
432 | * PS2CR Control Register | ||
433 | * PS2STAT Status Register | ||
434 | * PS2DATA Transmit/Receive Data register | ||
435 | * PS2CLKDIV Clock Division Register | ||
436 | * PS2PRECNT Clock Precount Register | ||
437 | * PS2TEST1 Test register 1 | ||
438 | * PS2TEST2 Test register 2 | ||
439 | * PS2TEST3 Test register 3 | ||
440 | * PS2TEST4 Test register 4 | ||
441 | */ | ||
442 | |||
443 | #define SA1111_KBD 0x0a00 | 389 | #define SA1111_KBD 0x0a00 |
444 | #define SA1111_MSE 0x0c00 | 390 | #define SA1111_MSE 0x0c00 |
445 | 391 | ||
446 | /* | 392 | /* PCMCIA Interface */ |
447 | * These are offsets from the above bases. | 393 | #define SA1111_PCMCIA 0x1600 |
448 | */ | ||
449 | #define SA1111_PS2CR 0x0000 | ||
450 | #define SA1111_PS2STAT 0x0004 | ||
451 | #define SA1111_PS2DATA 0x0008 | ||
452 | #define SA1111_PS2CLKDIV 0x000c | ||
453 | #define SA1111_PS2PRECNT 0x0010 | ||
454 | |||
455 | #define PS2CR_ENA 0x08 | ||
456 | #define PS2CR_FKD 0x02 | ||
457 | #define PS2CR_FKC 0x01 | ||
458 | |||
459 | #define PS2STAT_STP 0x0100 | ||
460 | #define PS2STAT_TXE 0x0080 | ||
461 | #define PS2STAT_TXB 0x0040 | ||
462 | #define PS2STAT_RXF 0x0020 | ||
463 | #define PS2STAT_RXB 0x0010 | ||
464 | #define PS2STAT_ENA 0x0008 | ||
465 | #define PS2STAT_RXP 0x0004 | ||
466 | #define PS2STAT_KBD 0x0002 | ||
467 | #define PS2STAT_KBC 0x0001 | ||
468 | 394 | ||
469 | /* | ||
470 | * PCMCIA Interface | ||
471 | * | ||
472 | * Registers | ||
473 | * PCSR Status Register | ||
474 | * PCCR Control Register | ||
475 | * PCSSR Sleep State Register | ||
476 | */ | ||
477 | |||
478 | #define SA1111_PCMCIA 0x1600 | ||
479 | |||
480 | /* | ||
481 | * These are offsets from the above base. | ||
482 | */ | ||
483 | #define SA1111_PCCR 0x0000 | ||
484 | #define SA1111_PCSSR 0x0004 | ||
485 | #define SA1111_PCSR 0x0008 | ||
486 | |||
487 | #define PCSR_S0_READY (1<<0) | ||
488 | #define PCSR_S1_READY (1<<1) | ||
489 | #define PCSR_S0_DETECT (1<<2) | ||
490 | #define PCSR_S1_DETECT (1<<3) | ||
491 | #define PCSR_S0_VS1 (1<<4) | ||
492 | #define PCSR_S0_VS2 (1<<5) | ||
493 | #define PCSR_S1_VS1 (1<<6) | ||
494 | #define PCSR_S1_VS2 (1<<7) | ||
495 | #define PCSR_S0_WP (1<<8) | ||
496 | #define PCSR_S1_WP (1<<9) | ||
497 | #define PCSR_S0_BVD1 (1<<10) | ||
498 | #define PCSR_S0_BVD2 (1<<11) | ||
499 | #define PCSR_S1_BVD1 (1<<12) | ||
500 | #define PCSR_S1_BVD2 (1<<13) | ||
501 | |||
502 | #define PCCR_S0_RST (1<<0) | ||
503 | #define PCCR_S1_RST (1<<1) | ||
504 | #define PCCR_S0_FLT (1<<2) | ||
505 | #define PCCR_S1_FLT (1<<3) | ||
506 | #define PCCR_S0_PWAITEN (1<<4) | ||
507 | #define PCCR_S1_PWAITEN (1<<5) | ||
508 | #define PCCR_S0_PSE (1<<6) | ||
509 | #define PCCR_S1_PSE (1<<7) | ||
510 | |||
511 | #define PCSSR_S0_SLEEP (1<<0) | ||
512 | #define PCSSR_S1_SLEEP (1<<1) | ||
513 | 395 | ||
514 | 396 | ||
515 | 397 | ||
516 | 398 | ||
517 | extern struct bus_type sa1111_bus_type; | 399 | extern struct bus_type sa1111_bus_type; |
518 | 400 | ||
519 | #define SA1111_DEVID_SBI 0 | 401 | #define SA1111_DEVID_SBI (1 << 0) |
520 | #define SA1111_DEVID_SK 1 | 402 | #define SA1111_DEVID_SK (1 << 1) |
521 | #define SA1111_DEVID_USB 2 | 403 | #define SA1111_DEVID_USB (1 << 2) |
522 | #define SA1111_DEVID_SAC 3 | 404 | #define SA1111_DEVID_SAC (1 << 3) |
523 | #define SA1111_DEVID_SSP 4 | 405 | #define SA1111_DEVID_SSP (1 << 4) |
524 | #define SA1111_DEVID_PS2 5 | 406 | #define SA1111_DEVID_PS2 (3 << 5) |
525 | #define SA1111_DEVID_GPIO 6 | 407 | #define SA1111_DEVID_PS2_KBD (1 << 5) |
526 | #define SA1111_DEVID_INT 7 | 408 | #define SA1111_DEVID_PS2_MSE (1 << 6) |
527 | #define SA1111_DEVID_PCMCIA 8 | 409 | #define SA1111_DEVID_GPIO (1 << 7) |
410 | #define SA1111_DEVID_INT (1 << 8) | ||
411 | #define SA1111_DEVID_PCMCIA (1 << 9) | ||
528 | 412 | ||
529 | struct sa1111_dev { | 413 | struct sa1111_dev { |
530 | struct device dev; | 414 | struct device dev; |
@@ -548,6 +432,7 @@ struct sa1111_driver { | |||
548 | int (*remove)(struct sa1111_dev *); | 432 | int (*remove)(struct sa1111_dev *); |
549 | int (*suspend)(struct sa1111_dev *, pm_message_t); | 433 | int (*suspend)(struct sa1111_dev *, pm_message_t); |
550 | int (*resume)(struct sa1111_dev *); | 434 | int (*resume)(struct sa1111_dev *); |
435 | void (*shutdown)(struct sa1111_dev *); | ||
551 | }; | 436 | }; |
552 | 437 | ||
553 | #define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv) | 438 | #define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv) |
@@ -555,9 +440,10 @@ struct sa1111_driver { | |||
555 | #define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name) | 440 | #define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name) |
556 | 441 | ||
557 | /* | 442 | /* |
558 | * These frob the SKPCR register. | 443 | * These frob the SKPCR register, and call platform specific |
444 | * enable/disable functions. | ||
559 | */ | 445 | */ |
560 | void sa1111_enable_device(struct sa1111_dev *); | 446 | int sa1111_enable_device(struct sa1111_dev *); |
561 | void sa1111_disable_device(struct sa1111_dev *); | 447 | void sa1111_disable_device(struct sa1111_dev *); |
562 | 448 | ||
563 | unsigned int sa1111_pll_clock(struct sa1111_dev *); | 449 | unsigned int sa1111_pll_clock(struct sa1111_dev *); |
@@ -580,6 +466,10 @@ void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned i | |||
580 | 466 | ||
581 | struct sa1111_platform_data { | 467 | struct sa1111_platform_data { |
582 | int irq_base; /* base for cascaded on-chip IRQs */ | 468 | int irq_base; /* base for cascaded on-chip IRQs */ |
469 | unsigned disable_devs; | ||
470 | void *data; | ||
471 | int (*enable)(void *, unsigned); | ||
472 | void (*disable)(void *, unsigned); | ||
583 | }; | 473 | }; |
584 | 474 | ||
585 | #endif /* _ASM_ARCH_SA1111 */ | 475 | #endif /* _ASM_ARCH_SA1111 */ |
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 6ebd276aebeb..6bb3f47b1f14 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c | |||
@@ -223,6 +223,7 @@ static struct resource sa1111_resources[] = { | |||
223 | 223 | ||
224 | static struct sa1111_platform_data sa1111_info = { | 224 | static struct sa1111_platform_data sa1111_info = { |
225 | .irq_base = LUBBOCK_SA1111_IRQ_BASE, | 225 | .irq_base = LUBBOCK_SA1111_IRQ_BASE, |
226 | .disable_devs = SA1111_DEVID_SAC, | ||
226 | }; | 227 | }; |
227 | 228 | ||
228 | static struct platform_device sa1111_device = { | 229 | static struct platform_device sa1111_device = { |
diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile index ed7408d3216c..60b97ec01676 100644 --- a/arch/arm/mach-sa1100/Makefile +++ b/arch/arm/mach-sa1100/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common support | 5 | # Common support |
6 | obj-y := clock.o generic.o irq.o dma.o time.o #nmi-oopser.o | 6 | obj-y := clock.o generic.o irq.o time.o #nmi-oopser.o |
7 | obj-m := | 7 | obj-m := |
8 | obj-n := | 8 | obj-n := |
9 | obj- := | 9 | obj- := |
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index 65b0a9a3fb9c..c3f5064df4bf 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c | |||
@@ -42,13 +42,13 @@ | |||
42 | #include "generic.h" | 42 | #include "generic.h" |
43 | 43 | ||
44 | #define ASSABET_BCR_DB1110 \ | 44 | #define ASSABET_BCR_DB1110 \ |
45 | (ASSABET_BCR_SPK_OFF | ASSABET_BCR_QMUTE | \ | 45 | (ASSABET_BCR_SPK_OFF | \ |
46 | ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ | 46 | ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ |
47 | ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ | 47 | ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ |
48 | ASSABET_BCR_IRDA_MD0) | 48 | ASSABET_BCR_IRDA_MD0) |
49 | 49 | ||
50 | #define ASSABET_BCR_DB1111 \ | 50 | #define ASSABET_BCR_DB1111 \ |
51 | (ASSABET_BCR_SPK_OFF | ASSABET_BCR_QMUTE | \ | 51 | (ASSABET_BCR_SPK_OFF | \ |
52 | ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ | 52 | ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ |
53 | ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ | 53 | ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ |
54 | ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \ | 54 | ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \ |
@@ -127,15 +127,8 @@ static struct flash_platform_data assabet_flash_data = { | |||
127 | }; | 127 | }; |
128 | 128 | ||
129 | static struct resource assabet_flash_resources[] = { | 129 | static struct resource assabet_flash_resources[] = { |
130 | { | 130 | DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M), |
131 | .start = SA1100_CS0_PHYS, | 131 | DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M), |
132 | .end = SA1100_CS0_PHYS + SZ_32M - 1, | ||
133 | .flags = IORESOURCE_MEM, | ||
134 | }, { | ||
135 | .start = SA1100_CS1_PHYS, | ||
136 | .end = SA1100_CS1_PHYS + SZ_32M - 1, | ||
137 | .flags = IORESOURCE_MEM, | ||
138 | } | ||
139 | }; | 132 | }; |
140 | 133 | ||
141 | 134 | ||
@@ -272,13 +265,22 @@ static struct sa1100fb_mach_info pal_info = { | |||
272 | }; | 265 | }; |
273 | #endif | 266 | #endif |
274 | 267 | ||
268 | #ifdef CONFIG_ASSABET_NEPONSET | ||
269 | static struct resource neponset_resources[] = { | ||
270 | DEFINE_RES_MEM(0x10000000, 0x08000000), | ||
271 | DEFINE_RES_MEM(0x18000000, 0x04000000), | ||
272 | DEFINE_RES_MEM(0x40000000, SZ_8K), | ||
273 | DEFINE_RES_IRQ(IRQ_GPIO25), | ||
274 | }; | ||
275 | #endif | ||
276 | |||
275 | static void __init assabet_init(void) | 277 | static void __init assabet_init(void) |
276 | { | 278 | { |
277 | /* | 279 | /* |
278 | * Ensure that the power supply is in "high power" mode. | 280 | * Ensure that the power supply is in "high power" mode. |
279 | */ | 281 | */ |
280 | GPDR |= GPIO_GPIO16; | ||
281 | GPSR = GPIO_GPIO16; | 282 | GPSR = GPIO_GPIO16; |
283 | GPDR |= GPIO_GPIO16; | ||
282 | 284 | ||
283 | /* | 285 | /* |
284 | * Ensure that these pins are set as outputs and are driving | 286 | * Ensure that these pins are set as outputs and are driving |
@@ -286,8 +288,16 @@ static void __init assabet_init(void) | |||
286 | * the WS latch in the CPLD, and we don't float causing | 288 | * the WS latch in the CPLD, and we don't float causing |
287 | * excessive power drain. --rmk | 289 | * excessive power drain. --rmk |
288 | */ | 290 | */ |
289 | GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; | ||
290 | GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; | 291 | GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; |
292 | GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; | ||
293 | |||
294 | /* | ||
295 | * Also set GPIO27 as an output; this is used to clock UART3 | ||
296 | * via the FPGA and as otherwise has no pullups or pulldowns, | ||
297 | * so stop it floating. | ||
298 | */ | ||
299 | GPCR = GPIO_GPIO27; | ||
300 | GPDR |= GPIO_GPIO27; | ||
291 | 301 | ||
292 | /* | 302 | /* |
293 | * Set up registers for sleep mode. | 303 | * Set up registers for sleep mode. |
@@ -311,6 +321,9 @@ static void __init assabet_init(void) | |||
311 | #ifndef CONFIG_ASSABET_NEPONSET | 321 | #ifndef CONFIG_ASSABET_NEPONSET |
312 | printk( "Warning: Neponset detected but full support " | 322 | printk( "Warning: Neponset detected but full support " |
313 | "hasn't been configured in the kernel\n" ); | 323 | "hasn't been configured in the kernel\n" ); |
324 | #else | ||
325 | platform_device_register_simple("neponset", 0, | ||
326 | neponset_resources, ARRAY_SIZE(neponset_resources)); | ||
314 | #endif | 327 | #endif |
315 | } | 328 | } |
316 | 329 | ||
@@ -482,21 +495,8 @@ static void __init assabet_map_io(void) | |||
482 | */ | 495 | */ |
483 | Ser1SDCR0 |= SDCR0_SUS; | 496 | Ser1SDCR0 |= SDCR0_SUS; |
484 | 497 | ||
485 | if (machine_has_neponset()) { | 498 | if (!machine_has_neponset()) |
486 | #ifdef CONFIG_ASSABET_NEPONSET | ||
487 | extern void neponset_map_io(void); | ||
488 | |||
489 | /* | ||
490 | * We map Neponset registers even if it isn't present since | ||
491 | * many drivers will try to probe their stuff (and fail). | ||
492 | * This is still more friendly than a kernel paging request | ||
493 | * crash. | ||
494 | */ | ||
495 | neponset_map_io(); | ||
496 | #endif | ||
497 | } else { | ||
498 | sa1100_register_uart_fns(&assabet_port_fns); | 499 | sa1100_register_uart_fns(&assabet_port_fns); |
499 | } | ||
500 | 500 | ||
501 | /* | 501 | /* |
502 | * When Neponset is attached, the first UART should be | 502 | * When Neponset is attached, the first UART should be |
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index b07a2c024cb7..5839c9d8bb92 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c | |||
@@ -39,20 +39,28 @@ | |||
39 | #include "generic.h" | 39 | #include "generic.h" |
40 | 40 | ||
41 | static struct resource sa1111_resources[] = { | 41 | static struct resource sa1111_resources[] = { |
42 | [0] = { | 42 | [0] = DEFINE_RES_MEM(BADGE4_SA1111_BASE, 0x2000), |
43 | .start = BADGE4_SA1111_BASE, | 43 | [1] = DEFINE_RES_IRQ(BADGE4_IRQ_GPIO_SA1111), |
44 | .end = BADGE4_SA1111_BASE + 0x00001fff, | ||
45 | .flags = IORESOURCE_MEM, | ||
46 | }, | ||
47 | [1] = { | ||
48 | .start = BADGE4_IRQ_GPIO_SA1111, | ||
49 | .end = BADGE4_IRQ_GPIO_SA1111, | ||
50 | .flags = IORESOURCE_IRQ, | ||
51 | }, | ||
52 | }; | 44 | }; |
53 | 45 | ||
46 | static int badge4_sa1111_enable(void *data, unsigned devid) | ||
47 | { | ||
48 | if (devid == SA1111_DEVID_USB) | ||
49 | badge4_set_5V(BADGE4_5V_USB, 1); | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | static void badge4_sa1111_disable(void *data, unsigned devid) | ||
54 | { | ||
55 | if (devid == SA1111_DEVID_USB) | ||
56 | badge4_set_5V(BADGE4_5V_USB, 0); | ||
57 | } | ||
58 | |||
54 | static struct sa1111_platform_data sa1111_info = { | 59 | static struct sa1111_platform_data sa1111_info = { |
55 | .irq_base = IRQ_BOARD_END, | 60 | .irq_base = IRQ_BOARD_END, |
61 | .disable_devs = SA1111_DEVID_PS2_MSE, | ||
62 | .enable = badge4_sa1111_enable, | ||
63 | .disable = badge4_sa1111_disable, | ||
56 | }; | 64 | }; |
57 | 65 | ||
58 | static u64 sa1111_dmamask = 0xffffffffUL; | 66 | static u64 sa1111_dmamask = 0xffffffffUL; |
@@ -121,11 +129,8 @@ static struct flash_platform_data badge4_flash_data = { | |||
121 | .nr_parts = ARRAY_SIZE(badge4_partitions), | 129 | .nr_parts = ARRAY_SIZE(badge4_partitions), |
122 | }; | 130 | }; |
123 | 131 | ||
124 | static struct resource badge4_flash_resource = { | 132 | static struct resource badge4_flash_resource = |
125 | .start = SA1100_CS0_PHYS, | 133 | DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_64M); |
126 | .end = SA1100_CS0_PHYS + SZ_64M - 1, | ||
127 | .flags = IORESOURCE_MEM, | ||
128 | }; | ||
129 | 134 | ||
130 | static int five_v_on __initdata = 0; | 135 | static int five_v_on __initdata = 0; |
131 | 136 | ||
@@ -269,11 +274,6 @@ static struct map_desc badge4_io_desc[] __initdata = { | |||
269 | .pfn = __phys_to_pfn(0x10000000), | 274 | .pfn = __phys_to_pfn(0x10000000), |
270 | .length = 0x00100000, | 275 | .length = 0x00100000, |
271 | .type = MT_DEVICE | 276 | .type = MT_DEVICE |
272 | }, { /* SA-1111 */ | ||
273 | .virtual = 0xf4000000, | ||
274 | .pfn = __phys_to_pfn(0x48000000), | ||
275 | .length = 0x00100000, | ||
276 | .type = MT_DEVICE | ||
277 | } | 277 | } |
278 | }; | 278 | }; |
279 | 279 | ||
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c index 11bb6d0b9be3..c2f9ba3a9578 100644 --- a/arch/arm/mach-sa1100/cerf.c +++ b/arch/arm/mach-sa1100/cerf.c | |||
@@ -33,11 +33,7 @@ | |||
33 | #include "generic.h" | 33 | #include "generic.h" |
34 | 34 | ||
35 | static struct resource cerfuart2_resources[] = { | 35 | static struct resource cerfuart2_resources[] = { |
36 | [0] = { | 36 | [0] = DEFINE_RES_MEM(0x80030000, SZ_64K), |
37 | .start = 0x80030000, | ||
38 | .end = 0x8003ffff, | ||
39 | .flags = IORESOURCE_MEM, | ||
40 | }, | ||
41 | }; | 37 | }; |
42 | 38 | ||
43 | static struct platform_device cerfuart2_device = { | 39 | static struct platform_device cerfuart2_device = { |
@@ -87,11 +83,8 @@ static struct flash_platform_data cerf_flash_data = { | |||
87 | .nr_parts = ARRAY_SIZE(cerf_partitions), | 83 | .nr_parts = ARRAY_SIZE(cerf_partitions), |
88 | }; | 84 | }; |
89 | 85 | ||
90 | static struct resource cerf_flash_resource = { | 86 | static struct resource cerf_flash_resource = |
91 | .start = SA1100_CS0_PHYS, | 87 | DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M); |
92 | .end = SA1100_CS0_PHYS + SZ_32M - 1, | ||
93 | .flags = IORESOURCE_MEM, | ||
94 | }; | ||
95 | 88 | ||
96 | static void __init cerf_init_irq(void) | 89 | static void __init cerf_init_irq(void) |
97 | { | 90 | { |
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index 70f6cdc9e63d..841041e11815 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c | |||
@@ -50,11 +50,7 @@ | |||
50 | #include "generic.h" | 50 | #include "generic.h" |
51 | 51 | ||
52 | static struct resource collie_scoop_resources[] = { | 52 | static struct resource collie_scoop_resources[] = { |
53 | [0] = { | 53 | [0] = DEFINE_RES_MEM(0x40800000, SZ_4K), |
54 | .start = 0x40800000, | ||
55 | .end = 0x40800fff, | ||
56 | .flags = IORESOURCE_MEM, | ||
57 | }, | ||
58 | }; | 54 | }; |
59 | 55 | ||
60 | static struct scoop_config collie_scoop_setup = { | 56 | static struct scoop_config collie_scoop_setup = { |
@@ -223,16 +219,8 @@ device_initcall(collie_uart_init); | |||
223 | 219 | ||
224 | 220 | ||
225 | static struct resource locomo_resources[] = { | 221 | static struct resource locomo_resources[] = { |
226 | [0] = { | 222 | [0] = DEFINE_RES_MEM(0x40000000, SZ_8K), |
227 | .start = 0x40000000, | 223 | [1] = DEFINE_RES_IRQ(IRQ_GPIO25), |
228 | .end = 0x40001fff, | ||
229 | .flags = IORESOURCE_MEM, | ||
230 | }, | ||
231 | [1] = { | ||
232 | .start = IRQ_GPIO25, | ||
233 | .end = IRQ_GPIO25, | ||
234 | .flags = IORESOURCE_IRQ, | ||
235 | }, | ||
236 | }; | 224 | }; |
237 | 225 | ||
238 | static struct locomo_platform_data locomo_info = { | 226 | static struct locomo_platform_data locomo_info = { |
@@ -305,11 +293,7 @@ static struct flash_platform_data collie_flash_data = { | |||
305 | }; | 293 | }; |
306 | 294 | ||
307 | static struct resource collie_flash_resources[] = { | 295 | static struct resource collie_flash_resources[] = { |
308 | { | 296 | DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M), |
309 | .start = SA1100_CS0_PHYS, | ||
310 | .end = SA1100_CS0_PHYS + SZ_32M - 1, | ||
311 | .flags = IORESOURCE_MEM, | ||
312 | } | ||
313 | }; | 297 | }; |
314 | 298 | ||
315 | static struct sa1100fb_mach_info collie_lcd_info = { | 299 | static struct sa1100fb_mach_info collie_lcd_info = { |
diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c deleted file mode 100644 index ad660350c296..000000000000 --- a/arch/arm/mach-sa1100/dma.c +++ /dev/null | |||
@@ -1,348 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-sa1100/dma.c | ||
3 | * | ||
4 | * Support functions for the SA11x0 internal DMA channels. | ||
5 | * | ||
6 | * Copyright (C) 2000, 2001 by Nicolas Pitre | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/spinlock.h> | ||
17 | #include <linux/errno.h> | ||
18 | |||
19 | #include <asm/system.h> | ||
20 | #include <asm/irq.h> | ||
21 | #include <mach/hardware.h> | ||
22 | #include <mach/dma.h> | ||
23 | |||
24 | |||
25 | #undef DEBUG | ||
26 | #ifdef DEBUG | ||
27 | #define DPRINTK( s, arg... ) printk( "dma<%p>: " s, regs , ##arg ) | ||
28 | #else | ||
29 | #define DPRINTK( x... ) | ||
30 | #endif | ||
31 | |||
32 | |||
33 | typedef struct { | ||
34 | const char *device_id; /* device name */ | ||
35 | u_long device; /* this channel device, 0 if unused*/ | ||
36 | dma_callback_t callback; /* to call when DMA completes */ | ||
37 | void *data; /* ... with private data ptr */ | ||
38 | } sa1100_dma_t; | ||
39 | |||
40 | static sa1100_dma_t dma_chan[SA1100_DMA_CHANNELS]; | ||
41 | |||
42 | static DEFINE_SPINLOCK(dma_list_lock); | ||
43 | |||
44 | |||
45 | static irqreturn_t dma_irq_handler(int irq, void *dev_id) | ||
46 | { | ||
47 | dma_regs_t *dma_regs = dev_id; | ||
48 | sa1100_dma_t *dma = dma_chan + (((u_int)dma_regs >> 5) & 7); | ||
49 | int status = dma_regs->RdDCSR; | ||
50 | |||
51 | if (status & (DCSR_ERROR)) { | ||
52 | printk(KERN_CRIT "DMA on \"%s\" caused an error\n", dma->device_id); | ||
53 | dma_regs->ClrDCSR = DCSR_ERROR; | ||
54 | } | ||
55 | |||
56 | dma_regs->ClrDCSR = status & (DCSR_DONEA | DCSR_DONEB); | ||
57 | if (dma->callback) { | ||
58 | if (status & DCSR_DONEA) | ||
59 | dma->callback(dma->data); | ||
60 | if (status & DCSR_DONEB) | ||
61 | dma->callback(dma->data); | ||
62 | } | ||
63 | return IRQ_HANDLED; | ||
64 | } | ||
65 | |||
66 | |||
67 | /** | ||
68 | * sa1100_request_dma - allocate one of the SA11x0's DMA channels | ||
69 | * @device: The SA11x0 peripheral targeted by this request | ||
70 | * @device_id: An ascii name for the claiming device | ||
71 | * @callback: Function to be called when the DMA completes | ||
72 | * @data: A cookie passed back to the callback function | ||
73 | * @dma_regs: Pointer to the location of the allocated channel's identifier | ||
74 | * | ||
75 | * This function will search for a free DMA channel and returns the | ||
76 | * address of the hardware registers for that channel as the channel | ||
77 | * identifier. This identifier is written to the location pointed by | ||
78 | * @dma_regs. The list of possible values for @device are listed into | ||
79 | * arch/arm/mach-sa1100/include/mach/dma.h as a dma_device_t enum. | ||
80 | * | ||
81 | * Note that reading from a port and writing to the same port are | ||
82 | * actually considered as two different streams requiring separate | ||
83 | * DMA registrations. | ||
84 | * | ||
85 | * The @callback function is called from interrupt context when one | ||
86 | * of the two possible DMA buffers in flight has terminated. That | ||
87 | * function has to be small and efficient while posponing more complex | ||
88 | * processing to a lower priority execution context. | ||
89 | * | ||
90 | * If no channels are available, or if the desired @device is already in | ||
91 | * use by another DMA channel, then an error code is returned. This | ||
92 | * function must be called before any other DMA calls. | ||
93 | **/ | ||
94 | |||
95 | int sa1100_request_dma (dma_device_t device, const char *device_id, | ||
96 | dma_callback_t callback, void *data, | ||
97 | dma_regs_t **dma_regs) | ||
98 | { | ||
99 | sa1100_dma_t *dma = NULL; | ||
100 | dma_regs_t *regs; | ||
101 | int i, err; | ||
102 | |||
103 | *dma_regs = NULL; | ||
104 | |||
105 | err = 0; | ||
106 | spin_lock(&dma_list_lock); | ||
107 | for (i = 0; i < SA1100_DMA_CHANNELS; i++) { | ||
108 | if (dma_chan[i].device == device) { | ||
109 | err = -EBUSY; | ||
110 | break; | ||
111 | } else if (!dma_chan[i].device && !dma) { | ||
112 | dma = &dma_chan[i]; | ||
113 | } | ||
114 | } | ||
115 | if (!err) { | ||
116 | if (dma) | ||
117 | dma->device = device; | ||
118 | else | ||
119 | err = -ENOSR; | ||
120 | } | ||
121 | spin_unlock(&dma_list_lock); | ||
122 | if (err) | ||
123 | return err; | ||
124 | |||
125 | i = dma - dma_chan; | ||
126 | regs = (dma_regs_t *)&DDAR(i); | ||
127 | err = request_irq(IRQ_DMA0 + i, dma_irq_handler, IRQF_DISABLED, | ||
128 | device_id, regs); | ||
129 | if (err) { | ||
130 | printk(KERN_ERR | ||
131 | "%s: unable to request IRQ %d for %s\n", | ||
132 | __func__, IRQ_DMA0 + i, device_id); | ||
133 | dma->device = 0; | ||
134 | return err; | ||
135 | } | ||
136 | |||
137 | *dma_regs = regs; | ||
138 | dma->device_id = device_id; | ||
139 | dma->callback = callback; | ||
140 | dma->data = data; | ||
141 | |||
142 | regs->ClrDCSR = | ||
143 | (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB | | ||
144 | DCSR_IE | DCSR_ERROR | DCSR_RUN); | ||
145 | regs->DDAR = device; | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | |||
151 | /** | ||
152 | * sa1100_free_dma - free a SA11x0 DMA channel | ||
153 | * @regs: identifier for the channel to free | ||
154 | * | ||
155 | * This clears all activities on a given DMA channel and releases it | ||
156 | * for future requests. The @regs identifier is provided by a | ||
157 | * successful call to sa1100_request_dma(). | ||
158 | **/ | ||
159 | |||
160 | void sa1100_free_dma(dma_regs_t *regs) | ||
161 | { | ||
162 | int i; | ||
163 | |||
164 | for (i = 0; i < SA1100_DMA_CHANNELS; i++) | ||
165 | if (regs == (dma_regs_t *)&DDAR(i)) | ||
166 | break; | ||
167 | if (i >= SA1100_DMA_CHANNELS) { | ||
168 | printk(KERN_ERR "%s: bad DMA identifier\n", __func__); | ||
169 | return; | ||
170 | } | ||
171 | |||
172 | if (!dma_chan[i].device) { | ||
173 | printk(KERN_ERR "%s: Trying to free free DMA\n", __func__); | ||
174 | return; | ||
175 | } | ||
176 | |||
177 | regs->ClrDCSR = | ||
178 | (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB | | ||
179 | DCSR_IE | DCSR_ERROR | DCSR_RUN); | ||
180 | free_irq(IRQ_DMA0 + i, regs); | ||
181 | dma_chan[i].device = 0; | ||
182 | } | ||
183 | |||
184 | |||
185 | /** | ||
186 | * sa1100_start_dma - submit a data buffer for DMA | ||
187 | * @regs: identifier for the channel to use | ||
188 | * @dma_ptr: buffer physical (or bus) start address | ||
189 | * @size: buffer size | ||
190 | * | ||
191 | * This function hands the given data buffer to the hardware for DMA | ||
192 | * access. If another buffer is already in flight then this buffer | ||
193 | * will be queued so the DMA engine will switch to it automatically | ||
194 | * when the previous one is done. The DMA engine is actually toggling | ||
195 | * between two buffers so at most 2 successful calls can be made before | ||
196 | * one of them terminates and the callback function is called. | ||
197 | * | ||
198 | * The @regs identifier is provided by a successful call to | ||
199 | * sa1100_request_dma(). | ||
200 | * | ||
201 | * The @size must not be larger than %MAX_DMA_SIZE. If a given buffer | ||
202 | * is larger than that then it's the caller's responsibility to split | ||
203 | * it into smaller chunks and submit them separately. If this is the | ||
204 | * case then a @size of %CUT_DMA_SIZE is recommended to avoid ending | ||
205 | * up with too small chunks. The callback function can be used to chain | ||
206 | * submissions of buffer chunks. | ||
207 | * | ||
208 | * Error return values: | ||
209 | * %-EOVERFLOW: Given buffer size is too big. | ||
210 | * %-EBUSY: Both DMA buffers are already in use. | ||
211 | * %-EAGAIN: Both buffers were busy but one of them just completed | ||
212 | * but the interrupt handler has to execute first. | ||
213 | * | ||
214 | * This function returs 0 on success. | ||
215 | **/ | ||
216 | |||
217 | int sa1100_start_dma(dma_regs_t *regs, dma_addr_t dma_ptr, u_int size) | ||
218 | { | ||
219 | unsigned long flags; | ||
220 | u_long status; | ||
221 | int ret; | ||
222 | |||
223 | if (dma_ptr & 3) | ||
224 | printk(KERN_WARNING "DMA: unaligned start address (0x%08lx)\n", | ||
225 | (unsigned long)dma_ptr); | ||
226 | |||
227 | if (size > MAX_DMA_SIZE) | ||
228 | return -EOVERFLOW; | ||
229 | |||
230 | local_irq_save(flags); | ||
231 | status = regs->RdDCSR; | ||
232 | |||
233 | /* If both DMA buffers are started, there's nothing else we can do. */ | ||
234 | if ((status & (DCSR_STRTA | DCSR_STRTB)) == (DCSR_STRTA | DCSR_STRTB)) { | ||
235 | DPRINTK("start: st %#x busy\n", status); | ||
236 | ret = -EBUSY; | ||
237 | goto out; | ||
238 | } | ||
239 | |||
240 | if (((status & DCSR_BIU) && (status & DCSR_STRTB)) || | ||
241 | (!(status & DCSR_BIU) && !(status & DCSR_STRTA))) { | ||
242 | if (status & DCSR_DONEA) { | ||
243 | /* give a chance for the interrupt to be processed */ | ||
244 | ret = -EAGAIN; | ||
245 | goto out; | ||
246 | } | ||
247 | regs->DBSA = dma_ptr; | ||
248 | regs->DBTA = size; | ||
249 | regs->SetDCSR = DCSR_STRTA | DCSR_IE | DCSR_RUN; | ||
250 | DPRINTK("start a=%#x s=%d on A\n", dma_ptr, size); | ||
251 | } else { | ||
252 | if (status & DCSR_DONEB) { | ||
253 | /* give a chance for the interrupt to be processed */ | ||
254 | ret = -EAGAIN; | ||
255 | goto out; | ||
256 | } | ||
257 | regs->DBSB = dma_ptr; | ||
258 | regs->DBTB = size; | ||
259 | regs->SetDCSR = DCSR_STRTB | DCSR_IE | DCSR_RUN; | ||
260 | DPRINTK("start a=%#x s=%d on B\n", dma_ptr, size); | ||
261 | } | ||
262 | ret = 0; | ||
263 | |||
264 | out: | ||
265 | local_irq_restore(flags); | ||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | |||
270 | /** | ||
271 | * sa1100_get_dma_pos - return current DMA position | ||
272 | * @regs: identifier for the channel to use | ||
273 | * | ||
274 | * This function returns the current physical (or bus) address for the | ||
275 | * given DMA channel. If the channel is running i.e. not in a stopped | ||
276 | * state then the caller must disable interrupts prior calling this | ||
277 | * function and process the returned value before re-enabling them to | ||
278 | * prevent races with the completion interrupt handler and the callback | ||
279 | * function. The validation of the returned value is the caller's | ||
280 | * responsibility as well -- the hardware seems to return out of range | ||
281 | * values when the DMA engine completes a buffer. | ||
282 | * | ||
283 | * The @regs identifier is provided by a successful call to | ||
284 | * sa1100_request_dma(). | ||
285 | **/ | ||
286 | |||
287 | dma_addr_t sa1100_get_dma_pos(dma_regs_t *regs) | ||
288 | { | ||
289 | int status; | ||
290 | |||
291 | /* | ||
292 | * We must determine whether buffer A or B is active. | ||
293 | * Two possibilities: either we are in the middle of | ||
294 | * a buffer, or the DMA controller just switched to the | ||
295 | * next toggle but the interrupt hasn't been serviced yet. | ||
296 | * The former case is straight forward. In the later case, | ||
297 | * we'll do like if DMA is just at the end of the previous | ||
298 | * toggle since all registers haven't been reset yet. | ||
299 | * This goes around the edge case and since we're always | ||
300 | * a little behind anyways it shouldn't make a big difference. | ||
301 | * If DMA has been stopped prior calling this then the | ||
302 | * position is exact. | ||
303 | */ | ||
304 | status = regs->RdDCSR; | ||
305 | if ((!(status & DCSR_BIU) && (status & DCSR_STRTA)) || | ||
306 | ( (status & DCSR_BIU) && !(status & DCSR_STRTB))) | ||
307 | return regs->DBSA; | ||
308 | else | ||
309 | return regs->DBSB; | ||
310 | } | ||
311 | |||
312 | |||
313 | /** | ||
314 | * sa1100_reset_dma - reset a DMA channel | ||
315 | * @regs: identifier for the channel to use | ||
316 | * | ||
317 | * This function resets and reconfigure the given DMA channel. This is | ||
318 | * particularly useful after a sleep/wakeup event. | ||
319 | * | ||
320 | * The @regs identifier is provided by a successful call to | ||
321 | * sa1100_request_dma(). | ||
322 | **/ | ||
323 | |||
324 | void sa1100_reset_dma(dma_regs_t *regs) | ||
325 | { | ||
326 | int i; | ||
327 | |||
328 | for (i = 0; i < SA1100_DMA_CHANNELS; i++) | ||
329 | if (regs == (dma_regs_t *)&DDAR(i)) | ||
330 | break; | ||
331 | if (i >= SA1100_DMA_CHANNELS) { | ||
332 | printk(KERN_ERR "%s: bad DMA identifier\n", __func__); | ||
333 | return; | ||
334 | } | ||
335 | |||
336 | regs->ClrDCSR = | ||
337 | (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB | | ||
338 | DCSR_IE | DCSR_ERROR | DCSR_RUN); | ||
339 | regs->DDAR = dma_chan[i].device; | ||
340 | } | ||
341 | |||
342 | |||
343 | EXPORT_SYMBOL(sa1100_request_dma); | ||
344 | EXPORT_SYMBOL(sa1100_free_dma); | ||
345 | EXPORT_SYMBOL(sa1100_start_dma); | ||
346 | EXPORT_SYMBOL(sa1100_get_dma_pos); | ||
347 | EXPORT_SYMBOL(sa1100_reset_dma); | ||
348 | |||
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 9cb4062b1e9b..0296d69622ac 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/dma-mapping.h> | ||
17 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
18 | #include <linux/cpufreq.h> | 19 | #include <linux/cpufreq.h> |
19 | #include <linux/ioport.h> | 20 | #include <linux/ioport.h> |
@@ -151,16 +152,8 @@ static void sa11x0_register_device(struct platform_device *dev, void *data) | |||
151 | 152 | ||
152 | 153 | ||
153 | static struct resource sa11x0udc_resources[] = { | 154 | static struct resource sa11x0udc_resources[] = { |
154 | [0] = { | 155 | [0] = DEFINE_RES_MEM(__PREG(Ser0UDCCR), SZ_64K), |
155 | .start = __PREG(Ser0UDCCR), | 156 | [1] = DEFINE_RES_IRQ(IRQ_Ser0UDC), |
156 | .end = __PREG(Ser0UDCCR) + 0xffff, | ||
157 | .flags = IORESOURCE_MEM, | ||
158 | }, | ||
159 | [1] = { | ||
160 | .start = IRQ_Ser0UDC, | ||
161 | .end = IRQ_Ser0UDC, | ||
162 | .flags = IORESOURCE_IRQ, | ||
163 | }, | ||
164 | }; | 157 | }; |
165 | 158 | ||
166 | static u64 sa11x0udc_dma_mask = 0xffffffffUL; | 159 | static u64 sa11x0udc_dma_mask = 0xffffffffUL; |
@@ -177,16 +170,8 @@ static struct platform_device sa11x0udc_device = { | |||
177 | }; | 170 | }; |
178 | 171 | ||
179 | static struct resource sa11x0uart1_resources[] = { | 172 | static struct resource sa11x0uart1_resources[] = { |
180 | [0] = { | 173 | [0] = DEFINE_RES_MEM(__PREG(Ser1UTCR0), SZ_64K), |
181 | .start = __PREG(Ser1UTCR0), | 174 | [1] = DEFINE_RES_IRQ(IRQ_Ser1UART), |
182 | .end = __PREG(Ser1UTCR0) + 0xffff, | ||
183 | .flags = IORESOURCE_MEM, | ||
184 | }, | ||
185 | [1] = { | ||
186 | .start = IRQ_Ser1UART, | ||
187 | .end = IRQ_Ser1UART, | ||
188 | .flags = IORESOURCE_IRQ, | ||
189 | }, | ||
190 | }; | 175 | }; |
191 | 176 | ||
192 | static struct platform_device sa11x0uart1_device = { | 177 | static struct platform_device sa11x0uart1_device = { |
@@ -197,16 +182,8 @@ static struct platform_device sa11x0uart1_device = { | |||
197 | }; | 182 | }; |
198 | 183 | ||
199 | static struct resource sa11x0uart3_resources[] = { | 184 | static struct resource sa11x0uart3_resources[] = { |
200 | [0] = { | 185 | [0] = DEFINE_RES_MEM(__PREG(Ser3UTCR0), SZ_64K), |
201 | .start = __PREG(Ser3UTCR0), | 186 | [1] = DEFINE_RES_IRQ(IRQ_Ser3UART), |
202 | .end = __PREG(Ser3UTCR0) + 0xffff, | ||
203 | .flags = IORESOURCE_MEM, | ||
204 | }, | ||
205 | [1] = { | ||
206 | .start = IRQ_Ser3UART, | ||
207 | .end = IRQ_Ser3UART, | ||
208 | .flags = IORESOURCE_IRQ, | ||
209 | }, | ||
210 | }; | 187 | }; |
211 | 188 | ||
212 | static struct platform_device sa11x0uart3_device = { | 189 | static struct platform_device sa11x0uart3_device = { |
@@ -217,16 +194,8 @@ static struct platform_device sa11x0uart3_device = { | |||
217 | }; | 194 | }; |
218 | 195 | ||
219 | static struct resource sa11x0mcp_resources[] = { | 196 | static struct resource sa11x0mcp_resources[] = { |
220 | [0] = { | 197 | [0] = DEFINE_RES_MEM(__PREG(Ser4MCCR0), SZ_64K), |
221 | .start = __PREG(Ser4MCCR0), | 198 | [1] = DEFINE_RES_IRQ(IRQ_Ser4MCP), |
222 | .end = __PREG(Ser4MCCR0) + 0xffff, | ||
223 | .flags = IORESOURCE_MEM, | ||
224 | }, | ||
225 | [1] = { | ||
226 | .start = IRQ_Ser4MCP, | ||
227 | .end = IRQ_Ser4MCP, | ||
228 | .flags = IORESOURCE_IRQ, | ||
229 | }, | ||
230 | }; | 199 | }; |
231 | 200 | ||
232 | static u64 sa11x0mcp_dma_mask = 0xffffffffUL; | 201 | static u64 sa11x0mcp_dma_mask = 0xffffffffUL; |
@@ -248,16 +217,8 @@ void sa11x0_register_mcp(struct mcp_plat_data *data) | |||
248 | } | 217 | } |
249 | 218 | ||
250 | static struct resource sa11x0ssp_resources[] = { | 219 | static struct resource sa11x0ssp_resources[] = { |
251 | [0] = { | 220 | [0] = DEFINE_RES_MEM(0x80070000, SZ_64K), |
252 | .start = 0x80070000, | 221 | [1] = DEFINE_RES_IRQ(IRQ_Ser4SSP), |
253 | .end = 0x8007ffff, | ||
254 | .flags = IORESOURCE_MEM, | ||
255 | }, | ||
256 | [1] = { | ||
257 | .start = IRQ_Ser4SSP, | ||
258 | .end = IRQ_Ser4SSP, | ||
259 | .flags = IORESOURCE_IRQ, | ||
260 | }, | ||
261 | }; | 222 | }; |
262 | 223 | ||
263 | static u64 sa11x0ssp_dma_mask = 0xffffffffUL; | 224 | static u64 sa11x0ssp_dma_mask = 0xffffffffUL; |
@@ -274,16 +235,8 @@ static struct platform_device sa11x0ssp_device = { | |||
274 | }; | 235 | }; |
275 | 236 | ||
276 | static struct resource sa11x0fb_resources[] = { | 237 | static struct resource sa11x0fb_resources[] = { |
277 | [0] = { | 238 | [0] = DEFINE_RES_MEM(0xb0100000, SZ_64K), |
278 | .start = 0xb0100000, | 239 | [1] = DEFINE_RES_IRQ(IRQ_LCD), |
279 | .end = 0xb010ffff, | ||
280 | .flags = IORESOURCE_MEM, | ||
281 | }, | ||
282 | [1] = { | ||
283 | .start = IRQ_LCD, | ||
284 | .end = IRQ_LCD, | ||
285 | .flags = IORESOURCE_IRQ, | ||
286 | }, | ||
287 | }; | 240 | }; |
288 | 241 | ||
289 | static struct platform_device sa11x0fb_device = { | 242 | static struct platform_device sa11x0fb_device = { |
@@ -321,23 +274,10 @@ void sa11x0_register_mtd(struct flash_platform_data *flash, | |||
321 | } | 274 | } |
322 | 275 | ||
323 | static struct resource sa11x0ir_resources[] = { | 276 | static struct resource sa11x0ir_resources[] = { |
324 | { | 277 | DEFINE_RES_MEM(__PREG(Ser2UTCR0), 0x24), |
325 | .start = __PREG(Ser2UTCR0), | 278 | DEFINE_RES_MEM(__PREG(Ser2HSCR0), 0x1c), |
326 | .end = __PREG(Ser2UTCR0) + 0x24 - 1, | 279 | DEFINE_RES_MEM(__PREG(Ser2HSCR2), 0x04), |
327 | .flags = IORESOURCE_MEM, | 280 | DEFINE_RES_IRQ(IRQ_Ser2ICP), |
328 | }, { | ||
329 | .start = __PREG(Ser2HSCR0), | ||
330 | .end = __PREG(Ser2HSCR0) + 0x1c - 1, | ||
331 | .flags = IORESOURCE_MEM, | ||
332 | }, { | ||
333 | .start = __PREG(Ser2HSCR2), | ||
334 | .end = __PREG(Ser2HSCR2) + 0x04 - 1, | ||
335 | .flags = IORESOURCE_MEM, | ||
336 | }, { | ||
337 | .start = IRQ_Ser2ICP, | ||
338 | .end = IRQ_Ser2ICP, | ||
339 | .flags = IORESOURCE_IRQ, | ||
340 | } | ||
341 | }; | 281 | }; |
342 | 282 | ||
343 | static struct platform_device sa11x0ir_device = { | 283 | static struct platform_device sa11x0ir_device = { |
@@ -357,6 +297,29 @@ static struct platform_device sa11x0rtc_device = { | |||
357 | .id = -1, | 297 | .id = -1, |
358 | }; | 298 | }; |
359 | 299 | ||
300 | static struct resource sa11x0dma_resources[] = { | ||
301 | DEFINE_RES_MEM(DMA_PHYS, DMA_SIZE), | ||
302 | DEFINE_RES_IRQ(IRQ_DMA0), | ||
303 | DEFINE_RES_IRQ(IRQ_DMA1), | ||
304 | DEFINE_RES_IRQ(IRQ_DMA2), | ||
305 | DEFINE_RES_IRQ(IRQ_DMA3), | ||
306 | DEFINE_RES_IRQ(IRQ_DMA4), | ||
307 | DEFINE_RES_IRQ(IRQ_DMA5), | ||
308 | }; | ||
309 | |||
310 | static u64 sa11x0dma_dma_mask = DMA_BIT_MASK(32); | ||
311 | |||
312 | static struct platform_device sa11x0dma_device = { | ||
313 | .name = "sa11x0-dma", | ||
314 | .id = -1, | ||
315 | .dev = { | ||
316 | .dma_mask = &sa11x0dma_dma_mask, | ||
317 | .coherent_dma_mask = 0xffffffff, | ||
318 | }, | ||
319 | .num_resources = ARRAY_SIZE(sa11x0dma_resources), | ||
320 | .resource = sa11x0dma_resources, | ||
321 | }; | ||
322 | |||
360 | static struct platform_device *sa11x0_devices[] __initdata = { | 323 | static struct platform_device *sa11x0_devices[] __initdata = { |
361 | &sa11x0udc_device, | 324 | &sa11x0udc_device, |
362 | &sa11x0uart1_device, | 325 | &sa11x0uart1_device, |
@@ -364,6 +327,7 @@ static struct platform_device *sa11x0_devices[] __initdata = { | |||
364 | &sa11x0ssp_device, | 327 | &sa11x0ssp_device, |
365 | &sa11x0pcmcia_device, | 328 | &sa11x0pcmcia_device, |
366 | &sa11x0rtc_device, | 329 | &sa11x0rtc_device, |
330 | &sa11x0dma_device, | ||
367 | }; | 331 | }; |
368 | 332 | ||
369 | static int __init sa1100_init(void) | 333 | static int __init sa1100_init(void) |
@@ -428,7 +392,7 @@ void __init sa1100_map_io(void) | |||
428 | * the MBGNT signal false to ensure the SA1111 doesn't own the | 392 | * the MBGNT signal false to ensure the SA1111 doesn't own the |
429 | * SDRAM bus. | 393 | * SDRAM bus. |
430 | */ | 394 | */ |
431 | void __init sa1110_mb_disable(void) | 395 | void sa1110_mb_disable(void) |
432 | { | 396 | { |
433 | unsigned long flags; | 397 | unsigned long flags; |
434 | 398 | ||
@@ -447,7 +411,7 @@ void __init sa1110_mb_disable(void) | |||
447 | * If the system is going to use the SA-1111 DMA engines, set up | 411 | * If the system is going to use the SA-1111 DMA engines, set up |
448 | * the memory bus request/grant pins. | 412 | * the memory bus request/grant pins. |
449 | */ | 413 | */ |
450 | void __devinit sa1110_mb_enable(void) | 414 | void sa1110_mb_enable(void) |
451 | { | 415 | { |
452 | unsigned long flags; | 416 | unsigned long flags; |
453 | 417 | ||
diff --git a/arch/arm/mach-sa1100/h3xxx.c b/arch/arm/mach-sa1100/h3xxx.c index b0784c974c2d..63150e1ffe9e 100644 --- a/arch/arm/mach-sa1100/h3xxx.c +++ b/arch/arm/mach-sa1100/h3xxx.c | |||
@@ -109,11 +109,8 @@ static struct flash_platform_data h3xxx_flash_data = { | |||
109 | .nr_parts = ARRAY_SIZE(h3xxx_partitions), | 109 | .nr_parts = ARRAY_SIZE(h3xxx_partitions), |
110 | }; | 110 | }; |
111 | 111 | ||
112 | static struct resource h3xxx_flash_resource = { | 112 | static struct resource h3xxx_flash_resource = |
113 | .start = SA1100_CS0_PHYS, | 113 | DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M); |
114 | .end = SA1100_CS0_PHYS + SZ_32M - 1, | ||
115 | .flags = IORESOURCE_MEM, | ||
116 | }; | ||
117 | 114 | ||
118 | 115 | ||
119 | /* | 116 | /* |
@@ -186,11 +183,7 @@ static struct sa1100_port_fns h3xxx_port_fns __initdata = { | |||
186 | */ | 183 | */ |
187 | 184 | ||
188 | static struct resource egpio_resources[] = { | 185 | static struct resource egpio_resources[] = { |
189 | [0] = { | 186 | [0] = DEFINE_RES_MEM(H3600_EGPIO_PHYS, 0x4), |
190 | .start = H3600_EGPIO_PHYS, | ||
191 | .end = H3600_EGPIO_PHYS + 0x4 - 1, | ||
192 | .flags = IORESOURCE_MEM, | ||
193 | }, | ||
194 | }; | 187 | }; |
195 | 188 | ||
196 | static struct htc_egpio_chip egpio_chips[] = { | 189 | static struct htc_egpio_chip egpio_chips[] = { |
diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c index c01bb36db940..37d381ad5464 100644 --- a/arch/arm/mach-sa1100/hackkit.c +++ b/arch/arm/mach-sa1100/hackkit.c | |||
@@ -179,11 +179,8 @@ static struct flash_platform_data hackkit_flash_data = { | |||
179 | .nr_parts = ARRAY_SIZE(hackkit_partitions), | 179 | .nr_parts = ARRAY_SIZE(hackkit_partitions), |
180 | }; | 180 | }; |
181 | 181 | ||
182 | static struct resource hackkit_flash_resource = { | 182 | static struct resource hackkit_flash_resource = |
183 | .start = SA1100_CS0_PHYS, | 183 | DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M); |
184 | .end = SA1100_CS0_PHYS + SZ_32M, | ||
185 | .flags = IORESOURCE_MEM, | ||
186 | }; | ||
187 | 184 | ||
188 | static void __init hackkit_init(void) | 185 | static void __init hackkit_init(void) |
189 | { | 186 | { |
diff --git a/arch/arm/mach-sa1100/include/mach/SA-1100.h b/arch/arm/mach-sa1100/include/mach/SA-1100.h index 3a4d4e067ed8..3f2d1b60188c 100644 --- a/arch/arm/mach-sa1100/include/mach/SA-1100.h +++ b/arch/arm/mach-sa1100/include/mach/SA-1100.h | |||
@@ -1590,224 +1590,9 @@ | |||
1590 | 1590 | ||
1591 | /* | 1591 | /* |
1592 | * Direct Memory Access (DMA) control registers | 1592 | * Direct Memory Access (DMA) control registers |
1593 | * | ||
1594 | * Registers | ||
1595 | * DDAR0 Direct Memory Access (DMA) Device Address Register | ||
1596 | * channel 0 (read/write). | ||
1597 | * DCSR0 Direct Memory Access (DMA) Control and Status | ||
1598 | * Register channel 0 (read/write). | ||
1599 | * DBSA0 Direct Memory Access (DMA) Buffer Start address | ||
1600 | * register A channel 0 (read/write). | ||
1601 | * DBTA0 Direct Memory Access (DMA) Buffer Transfer count | ||
1602 | * register A channel 0 (read/write). | ||
1603 | * DBSB0 Direct Memory Access (DMA) Buffer Start address | ||
1604 | * register B channel 0 (read/write). | ||
1605 | * DBTB0 Direct Memory Access (DMA) Buffer Transfer count | ||
1606 | * register B channel 0 (read/write). | ||
1607 | * | ||
1608 | * DDAR1 Direct Memory Access (DMA) Device Address Register | ||
1609 | * channel 1 (read/write). | ||
1610 | * DCSR1 Direct Memory Access (DMA) Control and Status | ||
1611 | * Register channel 1 (read/write). | ||
1612 | * DBSA1 Direct Memory Access (DMA) Buffer Start address | ||
1613 | * register A channel 1 (read/write). | ||
1614 | * DBTA1 Direct Memory Access (DMA) Buffer Transfer count | ||
1615 | * register A channel 1 (read/write). | ||
1616 | * DBSB1 Direct Memory Access (DMA) Buffer Start address | ||
1617 | * register B channel 1 (read/write). | ||
1618 | * DBTB1 Direct Memory Access (DMA) Buffer Transfer count | ||
1619 | * register B channel 1 (read/write). | ||
1620 | * | ||
1621 | * DDAR2 Direct Memory Access (DMA) Device Address Register | ||
1622 | * channel 2 (read/write). | ||
1623 | * DCSR2 Direct Memory Access (DMA) Control and Status | ||
1624 | * Register channel 2 (read/write). | ||
1625 | * DBSA2 Direct Memory Access (DMA) Buffer Start address | ||
1626 | * register A channel 2 (read/write). | ||
1627 | * DBTA2 Direct Memory Access (DMA) Buffer Transfer count | ||
1628 | * register A channel 2 (read/write). | ||
1629 | * DBSB2 Direct Memory Access (DMA) Buffer Start address | ||
1630 | * register B channel 2 (read/write). | ||
1631 | * DBTB2 Direct Memory Access (DMA) Buffer Transfer count | ||
1632 | * register B channel 2 (read/write). | ||
1633 | * | ||
1634 | * DDAR3 Direct Memory Access (DMA) Device Address Register | ||
1635 | * channel 3 (read/write). | ||
1636 | * DCSR3 Direct Memory Access (DMA) Control and Status | ||
1637 | * Register channel 3 (read/write). | ||
1638 | * DBSA3 Direct Memory Access (DMA) Buffer Start address | ||
1639 | * register A channel 3 (read/write). | ||
1640 | * DBTA3 Direct Memory Access (DMA) Buffer Transfer count | ||
1641 | * register A channel 3 (read/write). | ||
1642 | * DBSB3 Direct Memory Access (DMA) Buffer Start address | ||
1643 | * register B channel 3 (read/write). | ||
1644 | * DBTB3 Direct Memory Access (DMA) Buffer Transfer count | ||
1645 | * register B channel 3 (read/write). | ||
1646 | * | ||
1647 | * DDAR4 Direct Memory Access (DMA) Device Address Register | ||
1648 | * channel 4 (read/write). | ||
1649 | * DCSR4 Direct Memory Access (DMA) Control and Status | ||
1650 | * Register channel 4 (read/write). | ||
1651 | * DBSA4 Direct Memory Access (DMA) Buffer Start address | ||
1652 | * register A channel 4 (read/write). | ||
1653 | * DBTA4 Direct Memory Access (DMA) Buffer Transfer count | ||
1654 | * register A channel 4 (read/write). | ||
1655 | * DBSB4 Direct Memory Access (DMA) Buffer Start address | ||
1656 | * register B channel 4 (read/write). | ||
1657 | * DBTB4 Direct Memory Access (DMA) Buffer Transfer count | ||
1658 | * register B channel 4 (read/write). | ||
1659 | * | ||
1660 | * DDAR5 Direct Memory Access (DMA) Device Address Register | ||
1661 | * channel 5 (read/write). | ||
1662 | * DCSR5 Direct Memory Access (DMA) Control and Status | ||
1663 | * Register channel 5 (read/write). | ||
1664 | * DBSA5 Direct Memory Access (DMA) Buffer Start address | ||
1665 | * register A channel 5 (read/write). | ||
1666 | * DBTA5 Direct Memory Access (DMA) Buffer Transfer count | ||
1667 | * register A channel 5 (read/write). | ||
1668 | * DBSB5 Direct Memory Access (DMA) Buffer Start address | ||
1669 | * register B channel 5 (read/write). | ||
1670 | * DBTB5 Direct Memory Access (DMA) Buffer Transfer count | ||
1671 | * register B channel 5 (read/write). | ||
1672 | */ | 1593 | */ |
1673 | 1594 | #define DMA_SIZE (6 * 0x20) | |
1674 | #define DMASp 0x00000020 /* DMA control reg. Space [byte] */ | 1595 | #define DMA_PHYS 0xb0000000 |
1675 | |||
1676 | #define DDAR(Nb) __REG(0xB0000000 + (Nb)*DMASp) /* DMA Device Address Reg. channel [0..5] */ | ||
1677 | #define SetDCSR(Nb) __REG(0xB0000004 + (Nb)*DMASp) /* Set DMA Control & Status Reg. channel [0..5] (write) */ | ||
1678 | #define ClrDCSR(Nb) __REG(0xB0000008 + (Nb)*DMASp) /* Clear DMA Control & Status Reg. channel [0..5] (write) */ | ||
1679 | #define RdDCSR(Nb) __REG(0xB000000C + (Nb)*DMASp) /* Read DMA Control & Status Reg. channel [0..5] (read) */ | ||
1680 | #define DBSA(Nb) __REG(0xB0000010 + (Nb)*DMASp) /* DMA Buffer Start address reg. A channel [0..5] */ | ||
1681 | #define DBTA(Nb) __REG(0xB0000014 + (Nb)*DMASp) /* DMA Buffer Transfer count reg. A channel [0..5] */ | ||
1682 | #define DBSB(Nb) __REG(0xB0000018 + (Nb)*DMASp) /* DMA Buffer Start address reg. B channel [0..5] */ | ||
1683 | #define DBTB(Nb) __REG(0xB000001C + (Nb)*DMASp) /* DMA Buffer Transfer count reg. B channel [0..5] */ | ||
1684 | |||
1685 | #define DDAR_RW 0x00000001 /* device data Read/Write */ | ||
1686 | #define DDAR_DevWr (DDAR_RW*0) /* Device data Write */ | ||
1687 | /* (memory -> device) */ | ||
1688 | #define DDAR_DevRd (DDAR_RW*1) /* Device data Read */ | ||
1689 | /* (device -> memory) */ | ||
1690 | #define DDAR_E 0x00000002 /* big/little Endian device */ | ||
1691 | #define DDAR_LtlEnd (DDAR_E*0) /* Little Endian device */ | ||
1692 | #define DDAR_BigEnd (DDAR_E*1) /* Big Endian device */ | ||
1693 | #define DDAR_BS 0x00000004 /* device Burst Size */ | ||
1694 | #define DDAR_Brst4 (DDAR_BS*0) /* Burst-of-4 device */ | ||
1695 | #define DDAR_Brst8 (DDAR_BS*1) /* Burst-of-8 device */ | ||
1696 | #define DDAR_DW 0x00000008 /* device Data Width */ | ||
1697 | #define DDAR_8BitDev (DDAR_DW*0) /* 8-Bit Device */ | ||
1698 | #define DDAR_16BitDev (DDAR_DW*1) /* 16-Bit Device */ | ||
1699 | #define DDAR_DS Fld (4, 4) /* Device Select */ | ||
1700 | #define DDAR_Ser0UDCTr /* Ser. port 0 UDC Transmit */ \ | ||
1701 | (0x0 << FShft (DDAR_DS)) | ||
1702 | #define DDAR_Ser0UDCRc /* Ser. port 0 UDC Receive */ \ | ||
1703 | (0x1 << FShft (DDAR_DS)) | ||
1704 | #define DDAR_Ser1SDLCTr /* Ser. port 1 SDLC Transmit */ \ | ||
1705 | (0x2 << FShft (DDAR_DS)) | ||
1706 | #define DDAR_Ser1SDLCRc /* Ser. port 1 SDLC Receive */ \ | ||
1707 | (0x3 << FShft (DDAR_DS)) | ||
1708 | #define DDAR_Ser1UARTTr /* Ser. port 1 UART Transmit */ \ | ||
1709 | (0x4 << FShft (DDAR_DS)) | ||
1710 | #define DDAR_Ser1UARTRc /* Ser. port 1 UART Receive */ \ | ||
1711 | (0x5 << FShft (DDAR_DS)) | ||
1712 | #define DDAR_Ser2ICPTr /* Ser. port 2 ICP Transmit */ \ | ||
1713 | (0x6 << FShft (DDAR_DS)) | ||
1714 | #define DDAR_Ser2ICPRc /* Ser. port 2 ICP Receive */ \ | ||
1715 | (0x7 << FShft (DDAR_DS)) | ||
1716 | #define DDAR_Ser3UARTTr /* Ser. port 3 UART Transmit */ \ | ||
1717 | (0x8 << FShft (DDAR_DS)) | ||
1718 | #define DDAR_Ser3UARTRc /* Ser. port 3 UART Receive */ \ | ||
1719 | (0x9 << FShft (DDAR_DS)) | ||
1720 | #define DDAR_Ser4MCP0Tr /* Ser. port 4 MCP 0 Transmit */ \ | ||
1721 | /* (audio) */ \ | ||
1722 | (0xA << FShft (DDAR_DS)) | ||
1723 | #define DDAR_Ser4MCP0Rc /* Ser. port 4 MCP 0 Receive */ \ | ||
1724 | /* (audio) */ \ | ||
1725 | (0xB << FShft (DDAR_DS)) | ||
1726 | #define DDAR_Ser4MCP1Tr /* Ser. port 4 MCP 1 Transmit */ \ | ||
1727 | /* (telecom) */ \ | ||
1728 | (0xC << FShft (DDAR_DS)) | ||
1729 | #define DDAR_Ser4MCP1Rc /* Ser. port 4 MCP 1 Receive */ \ | ||
1730 | /* (telecom) */ \ | ||
1731 | (0xD << FShft (DDAR_DS)) | ||
1732 | #define DDAR_Ser4SSPTr /* Ser. port 4 SSP Transmit */ \ | ||
1733 | (0xE << FShft (DDAR_DS)) | ||
1734 | #define DDAR_Ser4SSPRc /* Ser. port 4 SSP Receive */ \ | ||
1735 | (0xF << FShft (DDAR_DS)) | ||
1736 | #define DDAR_DA Fld (24, 8) /* Device Address */ | ||
1737 | #define DDAR_DevAdd(Add) /* Device Address */ \ | ||
1738 | (((Add) & 0xF0000000) | \ | ||
1739 | (((Add) & 0X003FFFFC) << (FShft (DDAR_DA) - 2))) | ||
1740 | #define DDAR_Ser0UDCWr /* Ser. port 0 UDC Write */ \ | ||
1741 | (DDAR_DevWr + DDAR_Brst8 + DDAR_8BitDev + \ | ||
1742 | DDAR_Ser0UDCTr + DDAR_DevAdd (__PREG(Ser0UDCDR))) | ||
1743 | #define DDAR_Ser0UDCRd /* Ser. port 0 UDC Read */ \ | ||
1744 | (DDAR_DevRd + DDAR_Brst8 + DDAR_8BitDev + \ | ||
1745 | DDAR_Ser0UDCRc + DDAR_DevAdd (__PREG(Ser0UDCDR))) | ||
1746 | #define DDAR_Ser1UARTWr /* Ser. port 1 UART Write */ \ | ||
1747 | (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \ | ||
1748 | DDAR_Ser1UARTTr + DDAR_DevAdd (__PREG(Ser1UTDR))) | ||
1749 | #define DDAR_Ser1UARTRd /* Ser. port 1 UART Read */ \ | ||
1750 | (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \ | ||
1751 | DDAR_Ser1UARTRc + DDAR_DevAdd (__PREG(Ser1UTDR))) | ||
1752 | #define DDAR_Ser1SDLCWr /* Ser. port 1 SDLC Write */ \ | ||
1753 | (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \ | ||
1754 | DDAR_Ser1SDLCTr + DDAR_DevAdd (__PREG(Ser1SDDR))) | ||
1755 | #define DDAR_Ser1SDLCRd /* Ser. port 1 SDLC Read */ \ | ||
1756 | (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \ | ||
1757 | DDAR_Ser1SDLCRc + DDAR_DevAdd (__PREG(Ser1SDDR))) | ||
1758 | #define DDAR_Ser2UARTWr /* Ser. port 2 UART Write */ \ | ||
1759 | (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \ | ||
1760 | DDAR_Ser2ICPTr + DDAR_DevAdd (__PREG(Ser2UTDR))) | ||
1761 | #define DDAR_Ser2UARTRd /* Ser. port 2 UART Read */ \ | ||
1762 | (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \ | ||
1763 | DDAR_Ser2ICPRc + DDAR_DevAdd (__PREG(Ser2UTDR))) | ||
1764 | #define DDAR_Ser2HSSPWr /* Ser. port 2 HSSP Write */ \ | ||
1765 | (DDAR_DevWr + DDAR_Brst8 + DDAR_8BitDev + \ | ||
1766 | DDAR_Ser2ICPTr + DDAR_DevAdd (__PREG(Ser2HSDR))) | ||
1767 | #define DDAR_Ser2HSSPRd /* Ser. port 2 HSSP Read */ \ | ||
1768 | (DDAR_DevRd + DDAR_Brst8 + DDAR_8BitDev + \ | ||
1769 | DDAR_Ser2ICPRc + DDAR_DevAdd (__PREG(Ser2HSDR))) | ||
1770 | #define DDAR_Ser3UARTWr /* Ser. port 3 UART Write */ \ | ||
1771 | (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \ | ||
1772 | DDAR_Ser3UARTTr + DDAR_DevAdd (__PREG(Ser3UTDR))) | ||
1773 | #define DDAR_Ser3UARTRd /* Ser. port 3 UART Read */ \ | ||
1774 | (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \ | ||
1775 | DDAR_Ser3UARTRc + DDAR_DevAdd (__PREG(Ser3UTDR))) | ||
1776 | #define DDAR_Ser4MCP0Wr /* Ser. port 4 MCP 0 Write (audio) */ \ | ||
1777 | (DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \ | ||
1778 | DDAR_Ser4MCP0Tr + DDAR_DevAdd (__PREG(Ser4MCDR0))) | ||
1779 | #define DDAR_Ser4MCP0Rd /* Ser. port 4 MCP 0 Read (audio) */ \ | ||
1780 | (DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \ | ||
1781 | DDAR_Ser4MCP0Rc + DDAR_DevAdd (__PREG(Ser4MCDR0))) | ||
1782 | #define DDAR_Ser4MCP1Wr /* Ser. port 4 MCP 1 Write */ \ | ||
1783 | /* (telecom) */ \ | ||
1784 | (DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \ | ||
1785 | DDAR_Ser4MCP1Tr + DDAR_DevAdd (__PREG(Ser4MCDR1))) | ||
1786 | #define DDAR_Ser4MCP1Rd /* Ser. port 4 MCP 1 Read */ \ | ||
1787 | /* (telecom) */ \ | ||
1788 | (DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \ | ||
1789 | DDAR_Ser4MCP1Rc + DDAR_DevAdd (__PREG(Ser4MCDR1))) | ||
1790 | #define DDAR_Ser4SSPWr /* Ser. port 4 SSP Write (16 bits) */ \ | ||
1791 | (DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \ | ||
1792 | DDAR_Ser4SSPTr + DDAR_DevAdd (__PREG(Ser4SSDR))) | ||
1793 | #define DDAR_Ser4SSPRd /* Ser. port 4 SSP Read (16 bits) */ \ | ||
1794 | (DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \ | ||
1795 | DDAR_Ser4SSPRc + DDAR_DevAdd (__PREG(Ser4SSDR))) | ||
1796 | |||
1797 | #define DCSR_RUN 0x00000001 /* DMA running */ | ||
1798 | #define DCSR_IE 0x00000002 /* DMA Interrupt Enable */ | ||
1799 | #define DCSR_ERROR 0x00000004 /* DMA ERROR */ | ||
1800 | #define DCSR_DONEA 0x00000008 /* DONE DMA transfer buffer A */ | ||
1801 | #define DCSR_STRTA 0x00000010 /* STaRTed DMA transfer buffer A */ | ||
1802 | #define DCSR_DONEB 0x00000020 /* DONE DMA transfer buffer B */ | ||
1803 | #define DCSR_STRTB 0x00000040 /* STaRTed DMA transfer buffer B */ | ||
1804 | #define DCSR_BIU 0x00000080 /* DMA Buffer In Use */ | ||
1805 | #define DCSR_BufA (DCSR_BIU*0) /* DMA Buffer A in use */ | ||
1806 | #define DCSR_BufB (DCSR_BIU*1) /* DMA Buffer B in use */ | ||
1807 | |||
1808 | #define DBT_TC Fld (13, 0) /* Transfer Count */ | ||
1809 | #define DBTA_TCA DBT_TC /* Transfer Count buffer A */ | ||
1810 | #define DBTB_TCB DBT_TC /* Transfer Count buffer B */ | ||
1811 | 1596 | ||
1812 | 1597 | ||
1813 | /* | 1598 | /* |
diff --git a/arch/arm/mach-sa1100/include/mach/dma.h b/arch/arm/mach-sa1100/include/mach/dma.h deleted file mode 100644 index dda1b351310d..000000000000 --- a/arch/arm/mach-sa1100/include/mach/dma.h +++ /dev/null | |||
@@ -1,117 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-sa1100/include/mach/dma.h | ||
3 | * | ||
4 | * Generic SA1100 DMA support | ||
5 | * | ||
6 | * Copyright (C) 2000 Nicolas Pitre | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #ifndef __ASM_ARCH_DMA_H | ||
11 | #define __ASM_ARCH_DMA_H | ||
12 | |||
13 | #include "hardware.h" | ||
14 | |||
15 | |||
16 | /* | ||
17 | * The SA1100 has six internal DMA channels. | ||
18 | */ | ||
19 | #define SA1100_DMA_CHANNELS 6 | ||
20 | |||
21 | /* | ||
22 | * Maximum physical DMA buffer size | ||
23 | */ | ||
24 | #define MAX_DMA_SIZE 0x1fff | ||
25 | #define CUT_DMA_SIZE 0x1000 | ||
26 | |||
27 | /* | ||
28 | * All possible SA1100 devices a DMA channel can be attached to. | ||
29 | */ | ||
30 | typedef enum { | ||
31 | DMA_Ser0UDCWr = DDAR_Ser0UDCWr, /* Ser. port 0 UDC Write */ | ||
32 | DMA_Ser0UDCRd = DDAR_Ser0UDCRd, /* Ser. port 0 UDC Read */ | ||
33 | DMA_Ser1UARTWr = DDAR_Ser1UARTWr, /* Ser. port 1 UART Write */ | ||
34 | DMA_Ser1UARTRd = DDAR_Ser1UARTRd, /* Ser. port 1 UART Read */ | ||
35 | DMA_Ser1SDLCWr = DDAR_Ser1SDLCWr, /* Ser. port 1 SDLC Write */ | ||
36 | DMA_Ser1SDLCRd = DDAR_Ser1SDLCRd, /* Ser. port 1 SDLC Read */ | ||
37 | DMA_Ser2UARTWr = DDAR_Ser2UARTWr, /* Ser. port 2 UART Write */ | ||
38 | DMA_Ser2UARTRd = DDAR_Ser2UARTRd, /* Ser. port 2 UART Read */ | ||
39 | DMA_Ser2HSSPWr = DDAR_Ser2HSSPWr, /* Ser. port 2 HSSP Write */ | ||
40 | DMA_Ser2HSSPRd = DDAR_Ser2HSSPRd, /* Ser. port 2 HSSP Read */ | ||
41 | DMA_Ser3UARTWr = DDAR_Ser3UARTWr, /* Ser. port 3 UART Write */ | ||
42 | DMA_Ser3UARTRd = DDAR_Ser3UARTRd, /* Ser. port 3 UART Read */ | ||
43 | DMA_Ser4MCP0Wr = DDAR_Ser4MCP0Wr, /* Ser. port 4 MCP 0 Write (audio) */ | ||
44 | DMA_Ser4MCP0Rd = DDAR_Ser4MCP0Rd, /* Ser. port 4 MCP 0 Read (audio) */ | ||
45 | DMA_Ser4MCP1Wr = DDAR_Ser4MCP1Wr, /* Ser. port 4 MCP 1 Write */ | ||
46 | DMA_Ser4MCP1Rd = DDAR_Ser4MCP1Rd, /* Ser. port 4 MCP 1 Read */ | ||
47 | DMA_Ser4SSPWr = DDAR_Ser4SSPWr, /* Ser. port 4 SSP Write (16 bits) */ | ||
48 | DMA_Ser4SSPRd = DDAR_Ser4SSPRd /* Ser. port 4 SSP Read (16 bits) */ | ||
49 | } dma_device_t; | ||
50 | |||
51 | typedef struct { | ||
52 | volatile u_long DDAR; | ||
53 | volatile u_long SetDCSR; | ||
54 | volatile u_long ClrDCSR; | ||
55 | volatile u_long RdDCSR; | ||
56 | volatile dma_addr_t DBSA; | ||
57 | volatile u_long DBTA; | ||
58 | volatile dma_addr_t DBSB; | ||
59 | volatile u_long DBTB; | ||
60 | } dma_regs_t; | ||
61 | |||
62 | typedef void (*dma_callback_t)(void *data); | ||
63 | |||
64 | /* | ||
65 | * DMA function prototypes | ||
66 | */ | ||
67 | |||
68 | extern int sa1100_request_dma( dma_device_t device, const char *device_id, | ||
69 | dma_callback_t callback, void *data, | ||
70 | dma_regs_t **regs ); | ||
71 | extern void sa1100_free_dma( dma_regs_t *regs ); | ||
72 | extern int sa1100_start_dma( dma_regs_t *regs, dma_addr_t dma_ptr, u_int size ); | ||
73 | extern dma_addr_t sa1100_get_dma_pos(dma_regs_t *regs); | ||
74 | extern void sa1100_reset_dma(dma_regs_t *regs); | ||
75 | |||
76 | /** | ||
77 | * sa1100_stop_dma - stop DMA in progress | ||
78 | * @regs: identifier for the channel to use | ||
79 | * | ||
80 | * This stops DMA without clearing buffer pointers. Unlike | ||
81 | * sa1100_clear_dma() this allows subsequent use of sa1100_resume_dma() | ||
82 | * or sa1100_get_dma_pos(). | ||
83 | * | ||
84 | * The @regs identifier is provided by a successful call to | ||
85 | * sa1100_request_dma(). | ||
86 | **/ | ||
87 | |||
88 | #define sa1100_stop_dma(regs) ((regs)->ClrDCSR = DCSR_IE|DCSR_RUN) | ||
89 | |||
90 | /** | ||
91 | * sa1100_resume_dma - resume DMA on a stopped channel | ||
92 | * @regs: identifier for the channel to use | ||
93 | * | ||
94 | * This resumes DMA on a channel previously stopped with | ||
95 | * sa1100_stop_dma(). | ||
96 | * | ||
97 | * The @regs identifier is provided by a successful call to | ||
98 | * sa1100_request_dma(). | ||
99 | **/ | ||
100 | |||
101 | #define sa1100_resume_dma(regs) ((regs)->SetDCSR = DCSR_IE|DCSR_RUN) | ||
102 | |||
103 | /** | ||
104 | * sa1100_clear_dma - clear DMA pointers | ||
105 | * @regs: identifier for the channel to use | ||
106 | * | ||
107 | * This clear any DMA state so the DMA engine is ready to restart | ||
108 | * with new buffers through sa1100_start_dma(). Any buffers in flight | ||
109 | * are discarded. | ||
110 | * | ||
111 | * The @regs identifier is provided by a successful call to | ||
112 | * sa1100_request_dma(). | ||
113 | **/ | ||
114 | |||
115 | #define sa1100_clear_dma(regs) ((regs)->ClrDCSR = DCSR_IE|DCSR_RUN|DCSR_STRTA|DCSR_STRTB) | ||
116 | |||
117 | #endif /* _ASM_ARCH_DMA_H */ | ||
diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h index d18f21abef80..9e07634a4670 100644 --- a/arch/arm/mach-sa1100/include/mach/irqs.h +++ b/arch/arm/mach-sa1100/include/mach/irqs.h | |||
@@ -82,11 +82,3 @@ | |||
82 | #else | 82 | #else |
83 | #define NR_IRQS (IRQ_BOARD_START) | 83 | #define NR_IRQS (IRQ_BOARD_START) |
84 | #endif | 84 | #endif |
85 | |||
86 | /* | ||
87 | * Board specific IRQs. Define them here. | ||
88 | * Do not surround them with ifdefs. | ||
89 | */ | ||
90 | #define IRQ_NEPONSET_SMC9196 (IRQ_BOARD_START + 0) | ||
91 | #define IRQ_NEPONSET_USAR (IRQ_BOARD_START + 1) | ||
92 | #define IRQ_NEPONSET_SA1111 (IRQ_BOARD_START + 2) | ||
diff --git a/arch/arm/mach-sa1100/include/mach/neponset.h b/arch/arm/mach-sa1100/include/mach/neponset.h index ffe2bc45eed0..5516a52a329d 100644 --- a/arch/arm/mach-sa1100/include/mach/neponset.h +++ b/arch/arm/mach-sa1100/include/mach/neponset.h | |||
@@ -15,54 +15,6 @@ | |||
15 | /* | 15 | /* |
16 | * Neponset definitions: | 16 | * Neponset definitions: |
17 | */ | 17 | */ |
18 | |||
19 | #define NEPONSET_CPLD_BASE (0x10000000) | ||
20 | #define Nep_p2v( x ) ((x) - NEPONSET_CPLD_BASE + 0xf3000000) | ||
21 | #define Nep_v2p( x ) ((x) - 0xf3000000 + NEPONSET_CPLD_BASE) | ||
22 | |||
23 | #define _IRR 0x10000024 /* Interrupt Reason Register */ | ||
24 | #define _AUD_CTL 0x100000c0 /* Audio controls (RW) */ | ||
25 | #define _MDM_CTL_0 0x100000b0 /* Modem control 0 (RW) */ | ||
26 | #define _MDM_CTL_1 0x100000b4 /* Modem control 1 (RW) */ | ||
27 | #define _NCR_0 0x100000a0 /* Control Register (RW) */ | ||
28 | #define _KP_X_OUT 0x10000090 /* Keypad row write (RW) */ | ||
29 | #define _KP_Y_IN 0x10000080 /* Keypad column read (RO) */ | ||
30 | #define _SWPK 0x10000020 /* Switch pack (RO) */ | ||
31 | #define _WHOAMI 0x10000000 /* System ID Register (RO) */ | ||
32 | |||
33 | #define _LEDS 0x10000010 /* LEDs [31:0] (WO) */ | ||
34 | |||
35 | #define IRR (*((volatile u_char *) Nep_p2v(_IRR))) | ||
36 | #define AUD_CTL (*((volatile u_char *) Nep_p2v(_AUD_CTL))) | ||
37 | #define MDM_CTL_0 (*((volatile u_char *) Nep_p2v(_MDM_CTL_0))) | ||
38 | #define MDM_CTL_1 (*((volatile u_char *) Nep_p2v(_MDM_CTL_1))) | ||
39 | #define NCR_0 (*((volatile u_char *) Nep_p2v(_NCR_0))) | ||
40 | #define KP_X_OUT (*((volatile u_char *) Nep_p2v(_KP_X_OUT))) | ||
41 | #define KP_Y_IN (*((volatile u_char *) Nep_p2v(_KP_Y_IN))) | ||
42 | #define SWPK (*((volatile u_char *) Nep_p2v(_SWPK))) | ||
43 | #define WHOAMI (*((volatile u_char *) Nep_p2v(_WHOAMI))) | ||
44 | |||
45 | #define LEDS (*((volatile Word *) Nep_p2v(_LEDS))) | ||
46 | |||
47 | #define IRR_ETHERNET (1<<0) | ||
48 | #define IRR_USAR (1<<1) | ||
49 | #define IRR_SA1111 (1<<2) | ||
50 | |||
51 | #define AUD_SEL_1341 (1<<0) | ||
52 | #define AUD_MUTE_1341 (1<<1) | ||
53 | |||
54 | #define MDM_CTL0_RTS1 (1 << 0) | ||
55 | #define MDM_CTL0_DTR1 (1 << 1) | ||
56 | #define MDM_CTL0_RTS2 (1 << 2) | ||
57 | #define MDM_CTL0_DTR2 (1 << 3) | ||
58 | |||
59 | #define MDM_CTL1_CTS1 (1 << 0) | ||
60 | #define MDM_CTL1_DSR1 (1 << 1) | ||
61 | #define MDM_CTL1_DCD1 (1 << 2) | ||
62 | #define MDM_CTL1_CTS2 (1 << 3) | ||
63 | #define MDM_CTL1_DSR2 (1 << 4) | ||
64 | #define MDM_CTL1_DCD2 (1 << 5) | ||
65 | |||
66 | #define NCR_GP01_OFF (1<<0) | 18 | #define NCR_GP01_OFF (1<<0) |
67 | #define NCR_TP_PWR_EN (1<<1) | 19 | #define NCR_TP_PWR_EN (1<<1) |
68 | #define NCR_MS_PWR_EN (1<<2) | 20 | #define NCR_MS_PWR_EN (1<<2) |
@@ -71,4 +23,8 @@ | |||
71 | #define NCR_A0VPP (1<<5) | 23 | #define NCR_A0VPP (1<<5) |
72 | #define NCR_A1VPP (1<<6) | 24 | #define NCR_A1VPP (1<<6) |
73 | 25 | ||
26 | void neponset_ncr_frob(unsigned int, unsigned int); | ||
27 | #define neponset_ncr_set(v) neponset_ncr_frob(0, v) | ||
28 | #define neponset_ncr_clear(v) neponset_ncr_frob(v, 0) | ||
29 | |||
74 | #endif | 30 | #endif |
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c index dfbf824a69fa..5d12a305f53e 100644 --- a/arch/arm/mach-sa1100/irq.c +++ b/arch/arm/mach-sa1100/irq.c | |||
@@ -221,11 +221,8 @@ static struct irq_chip sa1100_normal_chip = { | |||
221 | .irq_set_wake = sa1100_set_wake, | 221 | .irq_set_wake = sa1100_set_wake, |
222 | }; | 222 | }; |
223 | 223 | ||
224 | static struct resource irq_resource = { | 224 | static struct resource irq_resource = |
225 | .name = "irqs", | 225 | DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs"); |
226 | .start = 0x90050000, | ||
227 | .end = 0x9005ffff, | ||
228 | }; | ||
229 | 226 | ||
230 | static struct sa1100irq_state { | 227 | static struct sa1100irq_state { |
231 | unsigned int saved; | 228 | unsigned int saved; |
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index ee121d6f0480..8be8130baf63 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | /* memory space (line 52 of HP's doc) */ | 47 | /* memory space (line 52 of HP's doc) */ |
48 | #define SA1111REGSTART 0x40000000 | 48 | #define SA1111REGSTART 0x40000000 |
49 | #define SA1111REGLEN 0x00001fff | 49 | #define SA1111REGLEN 0x00002000 |
50 | #define EPSONREGSTART 0x48000000 | 50 | #define EPSONREGSTART 0x48000000 |
51 | #define EPSONREGLEN 0x00100000 | 51 | #define EPSONREGLEN 0x00100000 |
52 | #define EPSONFBSTART 0x48200000 | 52 | #define EPSONFBSTART 0x48200000 |
@@ -174,16 +174,8 @@ static struct s1d13xxxfb_pdata s1d13xxxfb_data = { | |||
174 | }; | 174 | }; |
175 | 175 | ||
176 | static struct resource s1d13xxxfb_resources[] = { | 176 | static struct resource s1d13xxxfb_resources[] = { |
177 | [0] = { | 177 | [0] = DEFINE_RES_MEM(EPSONFBSTART, EPSONFBLEN), |
178 | .start = EPSONFBSTART, | 178 | [1] = DEFINE_RES_MEM(EPSONREGSTART, EPSONREGLEN), |
179 | .end = EPSONFBSTART + EPSONFBLEN, | ||
180 | .flags = IORESOURCE_MEM, | ||
181 | }, | ||
182 | [1] = { | ||
183 | .start = EPSONREGSTART, | ||
184 | .end = EPSONREGSTART + EPSONREGLEN, | ||
185 | .flags = IORESOURCE_MEM, | ||
186 | } | ||
187 | }; | 179 | }; |
188 | 180 | ||
189 | static struct platform_device s1d13xxxfb_device = { | 181 | static struct platform_device s1d13xxxfb_device = { |
@@ -197,20 +189,13 @@ static struct platform_device s1d13xxxfb_device = { | |||
197 | }; | 189 | }; |
198 | 190 | ||
199 | static struct resource sa1111_resources[] = { | 191 | static struct resource sa1111_resources[] = { |
200 | [0] = { | 192 | [0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN), |
201 | .start = SA1111REGSTART, | 193 | [1] = DEFINE_RES_IRQ(IRQ_GPIO1), |
202 | .end = SA1111REGSTART + SA1111REGLEN, | ||
203 | .flags = IORESOURCE_MEM, | ||
204 | }, | ||
205 | [1] = { | ||
206 | .start = IRQ_GPIO1, | ||
207 | .end = IRQ_GPIO1, | ||
208 | .flags = IORESOURCE_IRQ, | ||
209 | }, | ||
210 | }; | 194 | }; |
211 | 195 | ||
212 | static struct sa1111_platform_data sa1111_info = { | 196 | static struct sa1111_platform_data sa1111_info = { |
213 | .irq_base = IRQ_BOARD_END, | 197 | .irq_base = IRQ_BOARD_END, |
198 | .disable_devs = SA1111_DEVID_PS2_MSE, | ||
214 | }; | 199 | }; |
215 | 200 | ||
216 | static u64 sa1111_dmamask = 0xffffffffUL; | 201 | static u64 sa1111_dmamask = 0xffffffffUL; |
@@ -284,11 +269,6 @@ static struct map_desc jornada720_io_desc[] __initdata = { | |||
284 | .pfn = __phys_to_pfn(EPSONFBSTART), | 269 | .pfn = __phys_to_pfn(EPSONFBSTART), |
285 | .length = EPSONFBLEN, | 270 | .length = EPSONFBLEN, |
286 | .type = MT_DEVICE | 271 | .type = MT_DEVICE |
287 | }, { /* SA-1111 */ | ||
288 | .virtual = 0xf4000000, | ||
289 | .pfn = __phys_to_pfn(SA1111REGSTART), | ||
290 | .length = SA1111REGLEN, | ||
291 | .type = MT_DEVICE | ||
292 | } | 272 | } |
293 | }; | 273 | }; |
294 | 274 | ||
@@ -352,11 +332,8 @@ static struct flash_platform_data jornada720_flash_data = { | |||
352 | .nr_parts = ARRAY_SIZE(jornada720_partitions), | 332 | .nr_parts = ARRAY_SIZE(jornada720_partitions), |
353 | }; | 333 | }; |
354 | 334 | ||
355 | static struct resource jornada720_flash_resource = { | 335 | static struct resource jornada720_flash_resource = |
356 | .start = SA1100_CS0_PHYS, | 336 | DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M); |
357 | .end = SA1100_CS0_PHYS + SZ_32M - 1, | ||
358 | .flags = IORESOURCE_MEM, | ||
359 | }; | ||
360 | 337 | ||
361 | static void __init jornada720_mach_init(void) | 338 | static void __init jornada720_mach_init(void) |
362 | { | 339 | { |
diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c index 85f6ee672225..3923911000de 100644 --- a/arch/arm/mach-sa1100/nanoengine.c +++ b/arch/arm/mach-sa1100/nanoengine.c | |||
@@ -58,15 +58,8 @@ static struct flash_platform_data nanoengine_flash_data = { | |||
58 | }; | 58 | }; |
59 | 59 | ||
60 | static struct resource nanoengine_flash_resources[] = { | 60 | static struct resource nanoengine_flash_resources[] = { |
61 | { | 61 | DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M), |
62 | .start = SA1100_CS0_PHYS, | 62 | DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M), |
63 | .end = SA1100_CS0_PHYS + SZ_32M - 1, | ||
64 | .flags = IORESOURCE_MEM, | ||
65 | }, { | ||
66 | .start = SA1100_CS1_PHYS, | ||
67 | .end = SA1100_CS1_PHYS + SZ_32M - 1, | ||
68 | .flags = IORESOURCE_MEM, | ||
69 | } | ||
70 | }; | 63 | }; |
71 | 64 | ||
72 | static struct map_desc nanoengine_io_desc[] __initdata = { | 65 | static struct map_desc nanoengine_io_desc[] __initdata = { |
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index b4fa53a1427e..3297aa22cd77 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c | |||
@@ -1,89 +1,103 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-sa1100/neponset.c | 2 | * linux/arch/arm/mach-sa1100/neponset.c |
3 | * | ||
4 | */ | 3 | */ |
5 | #include <linux/kernel.h> | 4 | #include <linux/err.h> |
6 | #include <linux/init.h> | 5 | #include <linux/init.h> |
7 | #include <linux/tty.h> | ||
8 | #include <linux/ioport.h> | 6 | #include <linux/ioport.h> |
9 | #include <linux/serial_core.h> | 7 | #include <linux/irq.h> |
8 | #include <linux/kernel.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
11 | #include <linux/pm.h> | ||
12 | #include <linux/serial_core.h> | ||
13 | #include <linux/slab.h> | ||
11 | 14 | ||
12 | #include <mach/hardware.h> | ||
13 | #include <asm/mach-types.h> | 15 | #include <asm/mach-types.h> |
14 | #include <asm/irq.h> | ||
15 | #include <asm/mach/map.h> | 16 | #include <asm/mach/map.h> |
16 | #include <asm/mach/irq.h> | ||
17 | #include <asm/mach/serial_sa1100.h> | 17 | #include <asm/mach/serial_sa1100.h> |
18 | #include <mach/assabet.h> | ||
19 | #include <mach/neponset.h> | ||
20 | #include <asm/hardware/sa1111.h> | 18 | #include <asm/hardware/sa1111.h> |
21 | #include <asm/sizes.h> | 19 | #include <asm/sizes.h> |
22 | 20 | ||
23 | /* | 21 | #include <mach/hardware.h> |
24 | * Install handler for Neponset IRQ. Note that we have to loop here | 22 | #include <mach/assabet.h> |
25 | * since the ETHERNET and USAR IRQs are level based, and we need to | 23 | #include <mach/neponset.h> |
26 | * ensure that the IRQ signal is deasserted before returning. This | ||
27 | * is rather unfortunate. | ||
28 | */ | ||
29 | static void | ||
30 | neponset_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
31 | { | ||
32 | unsigned int irr; | ||
33 | |||
34 | while (1) { | ||
35 | /* | ||
36 | * Acknowledge the parent IRQ. | ||
37 | */ | ||
38 | desc->irq_data.chip->irq_ack(&desc->irq_data); | ||
39 | |||
40 | /* | ||
41 | * Read the interrupt reason register. Let's have all | ||
42 | * active IRQ bits high. Note: there is a typo in the | ||
43 | * Neponset user's guide for the SA1111 IRR level. | ||
44 | */ | ||
45 | irr = IRR ^ (IRR_ETHERNET | IRR_USAR); | ||
46 | |||
47 | if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0) | ||
48 | break; | ||
49 | |||
50 | /* | ||
51 | * Since there is no individual mask, we have to | ||
52 | * mask the parent IRQ. This is safe, since we'll | ||
53 | * recheck the register for any pending IRQs. | ||
54 | */ | ||
55 | if (irr & (IRR_ETHERNET | IRR_USAR)) { | ||
56 | desc->irq_data.chip->irq_mask(&desc->irq_data); | ||
57 | 24 | ||
58 | /* | 25 | #define NEP_IRQ_SMC91X 0 |
59 | * Ack the interrupt now to prevent re-entering | 26 | #define NEP_IRQ_USAR 1 |
60 | * this neponset handler. Again, this is safe | 27 | #define NEP_IRQ_SA1111 2 |
61 | * since we'll check the IRR register prior to | 28 | #define NEP_IRQ_NR 3 |
62 | * leaving. | 29 | |
63 | */ | 30 | #define WHOAMI 0x00 |
64 | desc->irq_data.chip->irq_ack(&desc->irq_data); | 31 | #define LEDS 0x10 |
32 | #define SWPK 0x20 | ||
33 | #define IRR 0x24 | ||
34 | #define KP_Y_IN 0x80 | ||
35 | #define KP_X_OUT 0x90 | ||
36 | #define NCR_0 0xa0 | ||
37 | #define MDM_CTL_0 0xb0 | ||
38 | #define MDM_CTL_1 0xb4 | ||
39 | #define AUD_CTL 0xc0 | ||
40 | |||
41 | #define IRR_ETHERNET (1 << 0) | ||
42 | #define IRR_USAR (1 << 1) | ||
43 | #define IRR_SA1111 (1 << 2) | ||
44 | |||
45 | #define MDM_CTL0_RTS1 (1 << 0) | ||
46 | #define MDM_CTL0_DTR1 (1 << 1) | ||
47 | #define MDM_CTL0_RTS2 (1 << 2) | ||
48 | #define MDM_CTL0_DTR2 (1 << 3) | ||
49 | |||
50 | #define MDM_CTL1_CTS1 (1 << 0) | ||
51 | #define MDM_CTL1_DSR1 (1 << 1) | ||
52 | #define MDM_CTL1_DCD1 (1 << 2) | ||
53 | #define MDM_CTL1_CTS2 (1 << 3) | ||
54 | #define MDM_CTL1_DSR2 (1 << 4) | ||
55 | #define MDM_CTL1_DCD2 (1 << 5) | ||
56 | |||
57 | #define AUD_SEL_1341 (1 << 0) | ||
58 | #define AUD_MUTE_1341 (1 << 1) | ||
65 | 59 | ||
66 | if (irr & IRR_ETHERNET) { | 60 | extern void sa1110_mb_disable(void); |
67 | generic_handle_irq(IRQ_NEPONSET_SMC9196); | ||
68 | } | ||
69 | 61 | ||
70 | if (irr & IRR_USAR) { | 62 | struct neponset_drvdata { |
71 | generic_handle_irq(IRQ_NEPONSET_USAR); | 63 | void __iomem *base; |
72 | } | 64 | struct platform_device *sa1111; |
65 | struct platform_device *smc91x; | ||
66 | unsigned irq_base; | ||
67 | #ifdef CONFIG_PM_SLEEP | ||
68 | u32 ncr0; | ||
69 | u32 mdm_ctl_0; | ||
70 | #endif | ||
71 | }; | ||
73 | 72 | ||
74 | desc->irq_data.chip->irq_unmask(&desc->irq_data); | 73 | static void __iomem *nep_base; |
75 | } | ||
76 | 74 | ||
77 | if (irr & IRR_SA1111) { | 75 | void neponset_ncr_frob(unsigned int mask, unsigned int val) |
78 | generic_handle_irq(IRQ_NEPONSET_SA1111); | 76 | { |
79 | } | 77 | void __iomem *base = nep_base; |
78 | |||
79 | if (base) { | ||
80 | unsigned long flags; | ||
81 | unsigned v; | ||
82 | |||
83 | local_irq_save(flags); | ||
84 | v = readb_relaxed(base + NCR_0); | ||
85 | writeb_relaxed((v & ~mask) | val, base + NCR_0); | ||
86 | local_irq_restore(flags); | ||
87 | } else { | ||
88 | WARN(1, "nep_base unset\n"); | ||
80 | } | 89 | } |
81 | } | 90 | } |
82 | 91 | ||
83 | static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) | 92 | static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) |
84 | { | 93 | { |
85 | u_int mdm_ctl0 = MDM_CTL_0; | 94 | void __iomem *base = nep_base; |
95 | u_int mdm_ctl0; | ||
96 | |||
97 | if (!base) | ||
98 | return; | ||
86 | 99 | ||
100 | mdm_ctl0 = readb_relaxed(base + MDM_CTL_0); | ||
87 | if (port->mapbase == _Ser1UTCR0) { | 101 | if (port->mapbase == _Ser1UTCR0) { |
88 | if (mctrl & TIOCM_RTS) | 102 | if (mctrl & TIOCM_RTS) |
89 | mdm_ctl0 &= ~MDM_CTL0_RTS2; | 103 | mdm_ctl0 &= ~MDM_CTL0_RTS2; |
@@ -106,14 +120,19 @@ static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) | |||
106 | mdm_ctl0 |= MDM_CTL0_DTR1; | 120 | mdm_ctl0 |= MDM_CTL0_DTR1; |
107 | } | 121 | } |
108 | 122 | ||
109 | MDM_CTL_0 = mdm_ctl0; | 123 | writeb_relaxed(mdm_ctl0, base + MDM_CTL_0); |
110 | } | 124 | } |
111 | 125 | ||
112 | static u_int neponset_get_mctrl(struct uart_port *port) | 126 | static u_int neponset_get_mctrl(struct uart_port *port) |
113 | { | 127 | { |
128 | void __iomem *base = nep_base; | ||
114 | u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; | 129 | u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; |
115 | u_int mdm_ctl1 = MDM_CTL_1; | 130 | u_int mdm_ctl1; |
116 | 131 | ||
132 | if (!base) | ||
133 | return ret; | ||
134 | |||
135 | mdm_ctl1 = readb_relaxed(base + MDM_CTL_1); | ||
117 | if (port->mapbase == _Ser1UTCR0) { | 136 | if (port->mapbase == _Ser1UTCR0) { |
118 | if (mdm_ctl1 & MDM_CTL1_DCD2) | 137 | if (mdm_ctl1 & MDM_CTL1_DCD2) |
119 | ret &= ~TIOCM_CD; | 138 | ret &= ~TIOCM_CD; |
@@ -138,209 +157,279 @@ static struct sa1100_port_fns neponset_port_fns __devinitdata = { | |||
138 | .get_mctrl = neponset_get_mctrl, | 157 | .get_mctrl = neponset_get_mctrl, |
139 | }; | 158 | }; |
140 | 159 | ||
141 | static int __devinit neponset_probe(struct platform_device *dev) | 160 | /* |
161 | * Install handler for Neponset IRQ. Note that we have to loop here | ||
162 | * since the ETHERNET and USAR IRQs are level based, and we need to | ||
163 | * ensure that the IRQ signal is deasserted before returning. This | ||
164 | * is rather unfortunate. | ||
165 | */ | ||
166 | static void neponset_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
142 | { | 167 | { |
143 | sa1100_register_uart_fns(&neponset_port_fns); | 168 | struct neponset_drvdata *d = irq_desc_get_handler_data(desc); |
169 | unsigned int irr; | ||
144 | 170 | ||
145 | /* | 171 | while (1) { |
146 | * Install handler for GPIO25. | 172 | /* |
147 | */ | 173 | * Acknowledge the parent IRQ. |
148 | irq_set_irq_type(IRQ_GPIO25, IRQ_TYPE_EDGE_RISING); | 174 | */ |
149 | irq_set_chained_handler(IRQ_GPIO25, neponset_irq_handler); | 175 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
150 | 176 | ||
151 | /* | 177 | /* |
152 | * We would set IRQ_GPIO25 to be a wake-up IRQ, but | 178 | * Read the interrupt reason register. Let's have all |
153 | * unfortunately something on the Neponset activates | 179 | * active IRQ bits high. Note: there is a typo in the |
154 | * this IRQ on sleep (ethernet?) | 180 | * Neponset user's guide for the SA1111 IRR level. |
155 | */ | 181 | */ |
156 | #if 0 | 182 | irr = readb_relaxed(d->base + IRR); |
157 | enable_irq_wake(IRQ_GPIO25); | 183 | irr ^= IRR_ETHERNET | IRR_USAR; |
158 | #endif | ||
159 | 184 | ||
160 | /* | 185 | if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0) |
161 | * Setup other Neponset IRQs. SA1111 will be done by the | 186 | break; |
162 | * generic SA1111 code. | ||
163 | */ | ||
164 | irq_set_handler(IRQ_NEPONSET_SMC9196, handle_simple_irq); | ||
165 | set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE); | ||
166 | irq_set_handler(IRQ_NEPONSET_USAR, handle_simple_irq); | ||
167 | set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE); | ||
168 | 187 | ||
169 | /* | 188 | /* |
170 | * Disable GPIO 0/1 drivers so the buttons work on the module. | 189 | * Since there is no individual mask, we have to |
171 | */ | 190 | * mask the parent IRQ. This is safe, since we'll |
172 | NCR_0 = NCR_GP01_OFF; | 191 | * recheck the register for any pending IRQs. |
192 | */ | ||
193 | if (irr & (IRR_ETHERNET | IRR_USAR)) { | ||
194 | desc->irq_data.chip->irq_mask(&desc->irq_data); | ||
173 | 195 | ||
174 | return 0; | 196 | /* |
175 | } | 197 | * Ack the interrupt now to prevent re-entering |
198 | * this neponset handler. Again, this is safe | ||
199 | * since we'll check the IRR register prior to | ||
200 | * leaving. | ||
201 | */ | ||
202 | desc->irq_data.chip->irq_ack(&desc->irq_data); | ||
176 | 203 | ||
177 | #ifdef CONFIG_PM | 204 | if (irr & IRR_ETHERNET) |
205 | generic_handle_irq(d->irq_base + NEP_IRQ_SMC91X); | ||
178 | 206 | ||
179 | /* | 207 | if (irr & IRR_USAR) |
180 | * LDM power management. | 208 | generic_handle_irq(d->irq_base + NEP_IRQ_USAR); |
181 | */ | ||
182 | static unsigned int neponset_saved_state; | ||
183 | 209 | ||
184 | static int neponset_suspend(struct platform_device *dev, pm_message_t state) | 210 | desc->irq_data.chip->irq_unmask(&desc->irq_data); |
185 | { | 211 | } |
186 | /* | ||
187 | * Save state. | ||
188 | */ | ||
189 | neponset_saved_state = NCR_0; | ||
190 | 212 | ||
191 | return 0; | 213 | if (irr & IRR_SA1111) |
214 | generic_handle_irq(d->irq_base + NEP_IRQ_SA1111); | ||
215 | } | ||
192 | } | 216 | } |
193 | 217 | ||
194 | static int neponset_resume(struct platform_device *dev) | 218 | /* Yes, we really do not have any kind of masking or unmasking */ |
219 | static void nochip_noop(struct irq_data *irq) | ||
195 | { | 220 | { |
196 | NCR_0 = neponset_saved_state; | ||
197 | |||
198 | return 0; | ||
199 | } | 221 | } |
200 | 222 | ||
201 | #else | 223 | static struct irq_chip nochip = { |
202 | #define neponset_suspend NULL | 224 | .name = "neponset", |
203 | #define neponset_resume NULL | 225 | .irq_ack = nochip_noop, |
204 | #endif | 226 | .irq_mask = nochip_noop, |
205 | 227 | .irq_unmask = nochip_noop, | |
206 | static struct platform_driver neponset_device_driver = { | ||
207 | .probe = neponset_probe, | ||
208 | .suspend = neponset_suspend, | ||
209 | .resume = neponset_resume, | ||
210 | .driver = { | ||
211 | .name = "neponset", | ||
212 | }, | ||
213 | }; | ||
214 | |||
215 | static struct resource neponset_resources[] = { | ||
216 | [0] = { | ||
217 | .start = 0x10000000, | ||
218 | .end = 0x17ffffff, | ||
219 | .flags = IORESOURCE_MEM, | ||
220 | }, | ||
221 | }; | ||
222 | |||
223 | static struct platform_device neponset_device = { | ||
224 | .name = "neponset", | ||
225 | .id = 0, | ||
226 | .num_resources = ARRAY_SIZE(neponset_resources), | ||
227 | .resource = neponset_resources, | ||
228 | }; | ||
229 | |||
230 | static struct resource sa1111_resources[] = { | ||
231 | [0] = { | ||
232 | .start = 0x40000000, | ||
233 | .end = 0x40001fff, | ||
234 | .flags = IORESOURCE_MEM, | ||
235 | }, | ||
236 | [1] = { | ||
237 | .start = IRQ_NEPONSET_SA1111, | ||
238 | .end = IRQ_NEPONSET_SA1111, | ||
239 | .flags = IORESOURCE_IRQ, | ||
240 | }, | ||
241 | }; | 228 | }; |
242 | 229 | ||
243 | static struct sa1111_platform_data sa1111_info = { | 230 | static struct sa1111_platform_data sa1111_info = { |
244 | .irq_base = IRQ_BOARD_END, | 231 | .irq_base = IRQ_BOARD_END, |
232 | .disable_devs = SA1111_DEVID_PS2_MSE, | ||
245 | }; | 233 | }; |
246 | 234 | ||
247 | static u64 sa1111_dmamask = 0xffffffffUL; | 235 | static int __devinit neponset_probe(struct platform_device *dev) |
236 | { | ||
237 | struct neponset_drvdata *d; | ||
238 | struct resource *nep_res, *sa1111_res, *smc91x_res; | ||
239 | struct resource sa1111_resources[] = { | ||
240 | DEFINE_RES_MEM(0x40000000, SZ_8K), | ||
241 | { .flags = IORESOURCE_IRQ }, | ||
242 | }; | ||
243 | struct platform_device_info sa1111_devinfo = { | ||
244 | .parent = &dev->dev, | ||
245 | .name = "sa1111", | ||
246 | .id = 0, | ||
247 | .res = sa1111_resources, | ||
248 | .num_res = ARRAY_SIZE(sa1111_resources), | ||
249 | .data = &sa1111_info, | ||
250 | .size_data = sizeof(sa1111_info), | ||
251 | .dma_mask = 0xffffffffUL, | ||
252 | }; | ||
253 | struct resource smc91x_resources[] = { | ||
254 | DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS, | ||
255 | 0x02000000, "smc91x-regs"), | ||
256 | DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS + 0x02000000, | ||
257 | 0x02000000, "smc91x-attrib"), | ||
258 | { .flags = IORESOURCE_IRQ }, | ||
259 | }; | ||
260 | struct platform_device_info smc91x_devinfo = { | ||
261 | .parent = &dev->dev, | ||
262 | .name = "smc91x", | ||
263 | .id = 0, | ||
264 | .res = smc91x_resources, | ||
265 | .num_res = ARRAY_SIZE(smc91x_resources), | ||
266 | }; | ||
267 | int ret, irq; | ||
268 | |||
269 | if (nep_base) | ||
270 | return -EBUSY; | ||
271 | |||
272 | irq = ret = platform_get_irq(dev, 0); | ||
273 | if (ret < 0) | ||
274 | goto err_alloc; | ||
275 | |||
276 | nep_res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
277 | smc91x_res = platform_get_resource(dev, IORESOURCE_MEM, 1); | ||
278 | sa1111_res = platform_get_resource(dev, IORESOURCE_MEM, 2); | ||
279 | if (!nep_res || !smc91x_res || !sa1111_res) { | ||
280 | ret = -ENXIO; | ||
281 | goto err_alloc; | ||
282 | } | ||
248 | 283 | ||
249 | static struct platform_device sa1111_device = { | 284 | d = kzalloc(sizeof(*d), GFP_KERNEL); |
250 | .name = "sa1111", | 285 | if (!d) { |
251 | .id = 0, | 286 | ret = -ENOMEM; |
252 | .dev = { | 287 | goto err_alloc; |
253 | .dma_mask = &sa1111_dmamask, | 288 | } |
254 | .coherent_dma_mask = 0xffffffff, | ||
255 | .platform_data = &sa1111_info, | ||
256 | }, | ||
257 | .num_resources = ARRAY_SIZE(sa1111_resources), | ||
258 | .resource = sa1111_resources, | ||
259 | }; | ||
260 | 289 | ||
261 | static struct resource smc91x_resources[] = { | 290 | d->base = ioremap(nep_res->start, SZ_4K); |
262 | [0] = { | 291 | if (!d->base) { |
263 | .name = "smc91x-regs", | 292 | ret = -ENOMEM; |
264 | .start = SA1100_CS3_PHYS, | 293 | goto err_ioremap; |
265 | .end = SA1100_CS3_PHYS + 0x01ffffff, | 294 | } |
266 | .flags = IORESOURCE_MEM, | ||
267 | }, | ||
268 | [1] = { | ||
269 | .start = IRQ_NEPONSET_SMC9196, | ||
270 | .end = IRQ_NEPONSET_SMC9196, | ||
271 | .flags = IORESOURCE_IRQ, | ||
272 | }, | ||
273 | [2] = { | ||
274 | .name = "smc91x-attrib", | ||
275 | .start = SA1100_CS3_PHYS + 0x02000000, | ||
276 | .end = SA1100_CS3_PHYS + 0x03ffffff, | ||
277 | .flags = IORESOURCE_MEM, | ||
278 | }, | ||
279 | }; | ||
280 | 295 | ||
281 | static struct platform_device smc91x_device = { | 296 | if (readb_relaxed(d->base + WHOAMI) != 0x11) { |
282 | .name = "smc91x", | 297 | dev_warn(&dev->dev, "Neponset board detected, but wrong ID: %02x\n", |
283 | .id = 0, | 298 | readb_relaxed(d->base + WHOAMI)); |
284 | .num_resources = ARRAY_SIZE(smc91x_resources), | 299 | ret = -ENODEV; |
285 | .resource = smc91x_resources, | 300 | goto err_id; |
286 | }; | 301 | } |
287 | 302 | ||
288 | static struct platform_device *devices[] __initdata = { | 303 | ret = irq_alloc_descs(-1, IRQ_BOARD_START, NEP_IRQ_NR, -1); |
289 | &neponset_device, | 304 | if (ret <= 0) { |
290 | &sa1111_device, | 305 | dev_err(&dev->dev, "unable to allocate %u irqs: %d\n", |
291 | &smc91x_device, | 306 | NEP_IRQ_NR, ret); |
292 | }; | 307 | if (ret == 0) |
308 | ret = -ENOMEM; | ||
309 | goto err_irq_alloc; | ||
310 | } | ||
293 | 311 | ||
294 | extern void sa1110_mb_disable(void); | 312 | d->irq_base = ret; |
295 | 313 | ||
296 | static int __init neponset_init(void) | 314 | irq_set_chip_and_handler(d->irq_base + NEP_IRQ_SMC91X, &nochip, |
297 | { | 315 | handle_simple_irq); |
298 | platform_driver_register(&neponset_device_driver); | 316 | set_irq_flags(d->irq_base + NEP_IRQ_SMC91X, IRQF_VALID | IRQF_PROBE); |
317 | irq_set_chip_and_handler(d->irq_base + NEP_IRQ_USAR, &nochip, | ||
318 | handle_simple_irq); | ||
319 | set_irq_flags(d->irq_base + NEP_IRQ_USAR, IRQF_VALID | IRQF_PROBE); | ||
320 | irq_set_chip(d->irq_base + NEP_IRQ_SA1111, &nochip); | ||
299 | 321 | ||
300 | /* | 322 | irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); |
301 | * The Neponset is only present on the Assabet machine type. | 323 | irq_set_handler_data(irq, d); |
302 | */ | 324 | irq_set_chained_handler(irq, neponset_irq_handler); |
303 | if (!machine_is_assabet()) | ||
304 | return -ENODEV; | ||
305 | 325 | ||
306 | /* | 326 | /* |
307 | * Ensure that the memory bus request/grant signals are setup, | 327 | * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately |
308 | * and the grant is held in its inactive state, whether or not | 328 | * something on the Neponset activates this IRQ on sleep (eth?) |
309 | * we actually have a Neponset attached. | ||
310 | */ | 329 | */ |
330 | #if 0 | ||
331 | enable_irq_wake(irq); | ||
332 | #endif | ||
333 | |||
334 | dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n", | ||
335 | d->irq_base, d->irq_base + NEP_IRQ_NR - 1); | ||
336 | nep_base = d->base; | ||
337 | |||
338 | sa1100_register_uart_fns(&neponset_port_fns); | ||
339 | |||
340 | /* Ensure that the memory bus request/grant signals are setup */ | ||
311 | sa1110_mb_disable(); | 341 | sa1110_mb_disable(); |
312 | 342 | ||
313 | if (!machine_has_neponset()) { | 343 | /* Disable GPIO 0/1 drivers so the buttons work on the Assabet */ |
314 | printk(KERN_DEBUG "Neponset expansion board not present\n"); | 344 | writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0); |
315 | return -ENODEV; | ||
316 | } | ||
317 | 345 | ||
318 | if (WHOAMI != 0x11) { | 346 | sa1111_resources[0].parent = sa1111_res; |
319 | printk(KERN_WARNING "Neponset board detected, but " | 347 | sa1111_resources[1].start = d->irq_base + NEP_IRQ_SA1111; |
320 | "wrong ID: %02x\n", WHOAMI); | 348 | sa1111_resources[1].end = d->irq_base + NEP_IRQ_SA1111; |
321 | return -ENODEV; | 349 | d->sa1111 = platform_device_register_full(&sa1111_devinfo); |
322 | } | 350 | |
351 | smc91x_resources[0].parent = smc91x_res; | ||
352 | smc91x_resources[1].parent = smc91x_res; | ||
353 | smc91x_resources[2].start = d->irq_base + NEP_IRQ_SMC91X; | ||
354 | smc91x_resources[2].end = d->irq_base + NEP_IRQ_SMC91X; | ||
355 | d->smc91x = platform_device_register_full(&smc91x_devinfo); | ||
356 | |||
357 | platform_set_drvdata(dev, d); | ||
323 | 358 | ||
324 | return platform_add_devices(devices, ARRAY_SIZE(devices)); | 359 | return 0; |
360 | |||
361 | err_irq_alloc: | ||
362 | err_id: | ||
363 | iounmap(d->base); | ||
364 | err_ioremap: | ||
365 | kfree(d); | ||
366 | err_alloc: | ||
367 | return ret; | ||
325 | } | 368 | } |
326 | 369 | ||
327 | subsys_initcall(neponset_init); | 370 | static int __devexit neponset_remove(struct platform_device *dev) |
371 | { | ||
372 | struct neponset_drvdata *d = platform_get_drvdata(dev); | ||
373 | int irq = platform_get_irq(dev, 0); | ||
374 | |||
375 | if (!IS_ERR(d->sa1111)) | ||
376 | platform_device_unregister(d->sa1111); | ||
377 | if (!IS_ERR(d->smc91x)) | ||
378 | platform_device_unregister(d->smc91x); | ||
379 | irq_set_chained_handler(irq, NULL); | ||
380 | irq_free_descs(d->irq_base, NEP_IRQ_NR); | ||
381 | nep_base = NULL; | ||
382 | iounmap(d->base); | ||
383 | kfree(d); | ||
328 | 384 | ||
329 | static struct map_desc neponset_io_desc[] __initdata = { | 385 | return 0; |
330 | { /* System Registers */ | 386 | } |
331 | .virtual = 0xf3000000, | 387 | |
332 | .pfn = __phys_to_pfn(0x10000000), | 388 | #ifdef CONFIG_PM_SLEEP |
333 | .length = SZ_1M, | 389 | static int neponset_suspend(struct device *dev) |
334 | .type = MT_DEVICE | 390 | { |
335 | }, { /* SA-1111 */ | 391 | struct neponset_drvdata *d = dev_get_drvdata(dev); |
336 | .virtual = 0xf4000000, | 392 | |
337 | .pfn = __phys_to_pfn(0x40000000), | 393 | d->ncr0 = readb_relaxed(d->base + NCR_0); |
338 | .length = SZ_1M, | 394 | d->mdm_ctl_0 = readb_relaxed(d->base + MDM_CTL_0); |
339 | .type = MT_DEVICE | 395 | |
340 | } | 396 | return 0; |
397 | } | ||
398 | |||
399 | static int neponset_resume(struct device *dev) | ||
400 | { | ||
401 | struct neponset_drvdata *d = dev_get_drvdata(dev); | ||
402 | |||
403 | writeb_relaxed(d->ncr0, d->base + NCR_0); | ||
404 | writeb_relaxed(d->mdm_ctl_0, d->base + MDM_CTL_0); | ||
405 | |||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | static const struct dev_pm_ops neponset_pm_ops = { | ||
410 | .suspend_noirq = neponset_suspend, | ||
411 | .resume_noirq = neponset_resume, | ||
412 | .freeze_noirq = neponset_suspend, | ||
413 | .restore_noirq = neponset_resume, | ||
414 | }; | ||
415 | #define PM_OPS &neponset_pm_ops | ||
416 | #else | ||
417 | #define PM_OPS NULL | ||
418 | #endif | ||
419 | |||
420 | static struct platform_driver neponset_device_driver = { | ||
421 | .probe = neponset_probe, | ||
422 | .remove = __devexit_p(neponset_remove), | ||
423 | .driver = { | ||
424 | .name = "neponset", | ||
425 | .owner = THIS_MODULE, | ||
426 | .pm = PM_OPS, | ||
427 | }, | ||
341 | }; | 428 | }; |
342 | 429 | ||
343 | void __init neponset_map_io(void) | 430 | static int __init neponset_init(void) |
344 | { | 431 | { |
345 | iotable_init(neponset_io_desc, ARRAY_SIZE(neponset_io_desc)); | 432 | return platform_driver_register(&neponset_device_driver); |
346 | } | 433 | } |
434 | |||
435 | subsys_initcall(neponset_init); | ||
diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c index 0d01ca788922..41bb018b3103 100644 --- a/arch/arm/mach-sa1100/pci-nanoengine.c +++ b/arch/arm/mach-sa1100/pci-nanoengine.c | |||
@@ -135,12 +135,8 @@ struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys | |||
135 | &sys->resources); | 135 | &sys->resources); |
136 | } | 136 | } |
137 | 137 | ||
138 | static struct resource pci_io_ports = { | 138 | static struct resource pci_io_ports = |
139 | .name = "PCI IO", | 139 | DEFINE_RES_IO_NAMED(0x400, 0x400, "PCI IO"); |
140 | .start = 0x400, | ||
141 | .end = 0x7FF, | ||
142 | .flags = IORESOURCE_IO, | ||
143 | }; | ||
144 | 140 | ||
145 | static struct resource pci_non_prefetchable_memory = { | 141 | static struct resource pci_non_prefetchable_memory = { |
146 | .name = "PCI non-prefetchable", | 142 | .name = "PCI non-prefetchable", |
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c index 9307df053533..ca5d33b6041a 100644 --- a/arch/arm/mach-sa1100/pleb.c +++ b/arch/arm/mach-sa1100/pleb.c | |||
@@ -37,17 +37,9 @@ | |||
37 | #define IRQ_GPIO_ETH0_IRQ IRQ_GPIO21 | 37 | #define IRQ_GPIO_ETH0_IRQ IRQ_GPIO21 |
38 | 38 | ||
39 | static struct resource smc91x_resources[] = { | 39 | static struct resource smc91x_resources[] = { |
40 | [0] = { | 40 | [0] = DEFINE_RES_MEM(PLEB_ETH0_P, 0x04000000), |
41 | .start = PLEB_ETH0_P, | ||
42 | .end = PLEB_ETH0_P | 0x03ffffff, | ||
43 | .flags = IORESOURCE_MEM, | ||
44 | }, | ||
45 | #if 0 /* Autoprobe instead, to get rising/falling edge characteristic right */ | 41 | #if 0 /* Autoprobe instead, to get rising/falling edge characteristic right */ |
46 | [1] = { | 42 | [1] = DEFINE_RES_IRQ(IRQ_GPIO_ETH0_IRQ), |
47 | .start = IRQ_GPIO_ETH0_IRQ, | ||
48 | .end = IRQ_GPIO_ETH0_IRQ, | ||
49 | .flags = IORESOURCE_IRQ, | ||
50 | }, | ||
51 | #endif | 43 | #endif |
52 | }; | 44 | }; |
53 | 45 | ||
@@ -70,16 +62,8 @@ static struct platform_device *devices[] __initdata = { | |||
70 | * the two SA1100 lowest chip select outputs. | 62 | * the two SA1100 lowest chip select outputs. |
71 | */ | 63 | */ |
72 | static struct resource pleb_flash_resources[] = { | 64 | static struct resource pleb_flash_resources[] = { |
73 | [0] = { | 65 | [0] = DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_8M), |
74 | .start = SA1100_CS0_PHYS, | 66 | [1] = DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_8M), |
75 | .end = SA1100_CS0_PHYS + SZ_8M - 1, | ||
76 | .flags = IORESOURCE_MEM, | ||
77 | }, | ||
78 | [1] = { | ||
79 | .start = SA1100_CS1_PHYS, | ||
80 | .end = SA1100_CS1_PHYS + SZ_8M - 1, | ||
81 | .flags = IORESOURCE_MEM, | ||
82 | } | ||
83 | }; | 67 | }; |
84 | 68 | ||
85 | 69 | ||
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c index c695b730bd69..77b2b9b522ac 100644 --- a/arch/arm/mach-sa1100/shannon.c +++ b/arch/arm/mach-sa1100/shannon.c | |||
@@ -48,11 +48,8 @@ static struct flash_platform_data shannon_flash_data = { | |||
48 | .nr_parts = ARRAY_SIZE(shannon_partitions), | 48 | .nr_parts = ARRAY_SIZE(shannon_partitions), |
49 | }; | 49 | }; |
50 | 50 | ||
51 | static struct resource shannon_flash_resource = { | 51 | static struct resource shannon_flash_resource = |
52 | .start = SA1100_CS0_PHYS, | 52 | DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_4M); |
53 | .end = SA1100_CS0_PHYS + SZ_4M - 1, | ||
54 | .flags = IORESOURCE_MEM, | ||
55 | }; | ||
56 | 53 | ||
57 | static struct mcp_plat_data shannon_mcp_data = { | 54 | static struct mcp_plat_data shannon_mcp_data = { |
58 | .mccr0 = MCCR0_ADM, | 55 | .mccr0 = MCCR0_ADM, |
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index e17c04d6e324..cdb9d197c092 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c | |||
@@ -176,15 +176,8 @@ static struct flash_platform_data simpad_flash_data = { | |||
176 | 176 | ||
177 | 177 | ||
178 | static struct resource simpad_flash_resources [] = { | 178 | static struct resource simpad_flash_resources [] = { |
179 | { | 179 | DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_16M), |
180 | .start = SA1100_CS0_PHYS, | 180 | DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_16M), |
181 | .end = SA1100_CS0_PHYS + SZ_16M -1, | ||
182 | .flags = IORESOURCE_MEM, | ||
183 | }, { | ||
184 | .start = SA1100_CS1_PHYS, | ||
185 | .end = SA1100_CS1_PHYS + SZ_16M -1, | ||
186 | .flags = IORESOURCE_MEM, | ||
187 | } | ||
188 | }; | 181 | }; |
189 | 182 | ||
190 | static struct mcp_plat_data simpad_mcp_data = { | 183 | static struct mcp_plat_data simpad_mcp_data = { |
diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S index e8223315b442..30cc6721665b 100644 --- a/arch/arm/mach-sa1100/sleep.S +++ b/arch/arm/mach-sa1100/sleep.S | |||
@@ -26,27 +26,36 @@ | |||
26 | * | 26 | * |
27 | * Causes sa11x0 to enter sleep state | 27 | * Causes sa11x0 to enter sleep state |
28 | * | 28 | * |
29 | * Must be aligned to a cacheline. | ||
29 | */ | 30 | */ |
30 | 31 | .balign 32 | |
31 | ENTRY(sa1100_finish_suspend) | 32 | ENTRY(sa1100_finish_suspend) |
32 | @ disable clock switching | 33 | @ disable clock switching |
33 | mcr p15, 0, r1, c15, c2, 2 | 34 | mcr p15, 0, r1, c15, c2, 2 |
34 | 35 | ||
35 | @ Adjust memory timing before lowering CPU clock | 36 | ldr r6, =MDREFR |
36 | @ Clock speed adjustment without changing memory timing makes | 37 | ldr r4, [r6] |
37 | @ CPU hang in some cases | 38 | orr r4, r4, #MDREFR_K1DB2 |
38 | ldr r0, =MDREFR | 39 | ldr r5, =PPCR |
39 | ldr r1, [r0] | 40 | |
40 | orr r1, r1, #MDREFR_K1DB2 | 41 | @ Pre-load __udelay into the I-cache |
41 | str r1, [r0] | 42 | mov r0, #1 |
43 | bl __udelay | ||
44 | mov r0, r0 | ||
45 | |||
46 | @ The following must all exist in a single cache line to | ||
47 | @ avoid accessing memory until this sequence is complete, | ||
48 | @ otherwise we occasionally hang. | ||
49 | |||
50 | @ Adjust memory timing before lowering CPU clock | ||
51 | str r4, [r6] | ||
42 | 52 | ||
43 | @ delay 90us and set CPU PLL to lowest speed | 53 | @ delay 90us and set CPU PLL to lowest speed |
44 | @ fixes resume problem on high speed SA1110 | 54 | @ fixes resume problem on high speed SA1110 |
45 | mov r0, #90 | 55 | mov r0, #90 |
46 | bl __udelay | 56 | bl __udelay |
47 | ldr r0, =PPCR | ||
48 | mov r1, #0 | 57 | mov r1, #0 |
49 | str r1, [r0] | 58 | str r1, [r5] |
50 | mov r0, #90 | 59 | mov r0, #90 |
51 | bl __udelay | 60 | bl __udelay |
52 | 61 | ||
@@ -85,12 +94,10 @@ ENTRY(sa1100_finish_suspend) | |||
85 | bic r5, r5, #FMsk(MSC_RT) | 94 | bic r5, r5, #FMsk(MSC_RT) |
86 | bic r5, r5, #FMsk(MSC_RT)<<16 | 95 | bic r5, r5, #FMsk(MSC_RT)<<16 |
87 | 96 | ||
88 | ldr r6, =MDREFR | ||
89 | |||
90 | ldr r7, [r6] | 97 | ldr r7, [r6] |
91 | bic r7, r7, #0x0000FF00 | 98 | bic r7, r7, #0x0000FF00 |
92 | bic r7, r7, #0x000000F0 | 99 | bic r7, r7, #0x000000F0 |
93 | orr r8, r7, #MDREFR_SLFRSH | 100 | orr r8, r7, #MDREFR_SLFRSH |
94 | 101 | ||
95 | ldr r9, =MDCNFG | 102 | ldr r9, =MDCNFG |
96 | ldr r10, [r9] | 103 | ldr r10, [r9] |
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index f1a274994bb1..4a6c46dea8a0 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
@@ -252,6 +252,15 @@ config EP93XX_DMA | |||
252 | help | 252 | help |
253 | Enable support for the Cirrus Logic EP93xx M2P/M2M DMA controller. | 253 | Enable support for the Cirrus Logic EP93xx M2P/M2M DMA controller. |
254 | 254 | ||
255 | config DMA_SA11X0 | ||
256 | tristate "SA-11x0 DMA support" | ||
257 | depends on ARCH_SA1100 | ||
258 | select DMA_ENGINE | ||
259 | help | ||
260 | Support the DMA engine found on Intel StrongARM SA-1100 and | ||
261 | SA-1110 SoCs. This DMA engine can only be used with on-chip | ||
262 | devices. | ||
263 | |||
255 | config DMA_ENGINE | 264 | config DMA_ENGINE |
256 | bool | 265 | bool |
257 | 266 | ||
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 009a222e8283..86b795baba98 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile | |||
@@ -27,3 +27,4 @@ obj-$(CONFIG_PL330_DMA) += pl330.o | |||
27 | obj-$(CONFIG_PCH_DMA) += pch_dma.o | 27 | obj-$(CONFIG_PCH_DMA) += pch_dma.o |
28 | obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o | 28 | obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o |
29 | obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o | 29 | obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o |
30 | obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o | ||
diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c new file mode 100644 index 000000000000..16a6b48883cf --- /dev/null +++ b/drivers/dma/sa11x0-dma.c | |||
@@ -0,0 +1,1109 @@ | |||
1 | /* | ||
2 | * SA11x0 DMAengine support | ||
3 | * | ||
4 | * Copyright (C) 2012 Russell King | ||
5 | * Derived in part from arch/arm/mach-sa1100/dma.c, | ||
6 | * Copyright (C) 2000, 2001 by Nicolas Pitre | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | #include <linux/sched.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/dmaengine.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/sa11x0-dma.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | |||
24 | #define NR_PHY_CHAN 6 | ||
25 | #define DMA_ALIGN 3 | ||
26 | #define DMA_MAX_SIZE 0x1fff | ||
27 | #define DMA_CHUNK_SIZE 0x1000 | ||
28 | |||
29 | #define DMA_DDAR 0x00 | ||
30 | #define DMA_DCSR_S 0x04 | ||
31 | #define DMA_DCSR_C 0x08 | ||
32 | #define DMA_DCSR_R 0x0c | ||
33 | #define DMA_DBSA 0x10 | ||
34 | #define DMA_DBTA 0x14 | ||
35 | #define DMA_DBSB 0x18 | ||
36 | #define DMA_DBTB 0x1c | ||
37 | #define DMA_SIZE 0x20 | ||
38 | |||
39 | #define DCSR_RUN (1 << 0) | ||
40 | #define DCSR_IE (1 << 1) | ||
41 | #define DCSR_ERROR (1 << 2) | ||
42 | #define DCSR_DONEA (1 << 3) | ||
43 | #define DCSR_STRTA (1 << 4) | ||
44 | #define DCSR_DONEB (1 << 5) | ||
45 | #define DCSR_STRTB (1 << 6) | ||
46 | #define DCSR_BIU (1 << 7) | ||
47 | |||
48 | #define DDAR_RW (1 << 0) /* 0 = W, 1 = R */ | ||
49 | #define DDAR_E (1 << 1) /* 0 = LE, 1 = BE */ | ||
50 | #define DDAR_BS (1 << 2) /* 0 = BS4, 1 = BS8 */ | ||
51 | #define DDAR_DW (1 << 3) /* 0 = 8b, 1 = 16b */ | ||
52 | #define DDAR_Ser0UDCTr (0x0 << 4) | ||
53 | #define DDAR_Ser0UDCRc (0x1 << 4) | ||
54 | #define DDAR_Ser1SDLCTr (0x2 << 4) | ||
55 | #define DDAR_Ser1SDLCRc (0x3 << 4) | ||
56 | #define DDAR_Ser1UARTTr (0x4 << 4) | ||
57 | #define DDAR_Ser1UARTRc (0x5 << 4) | ||
58 | #define DDAR_Ser2ICPTr (0x6 << 4) | ||
59 | #define DDAR_Ser2ICPRc (0x7 << 4) | ||
60 | #define DDAR_Ser3UARTTr (0x8 << 4) | ||
61 | #define DDAR_Ser3UARTRc (0x9 << 4) | ||
62 | #define DDAR_Ser4MCP0Tr (0xa << 4) | ||
63 | #define DDAR_Ser4MCP0Rc (0xb << 4) | ||
64 | #define DDAR_Ser4MCP1Tr (0xc << 4) | ||
65 | #define DDAR_Ser4MCP1Rc (0xd << 4) | ||
66 | #define DDAR_Ser4SSPTr (0xe << 4) | ||
67 | #define DDAR_Ser4SSPRc (0xf << 4) | ||
68 | |||
69 | struct sa11x0_dma_sg { | ||
70 | u32 addr; | ||
71 | u32 len; | ||
72 | }; | ||
73 | |||
74 | struct sa11x0_dma_desc { | ||
75 | struct dma_async_tx_descriptor tx; | ||
76 | u32 ddar; | ||
77 | size_t size; | ||
78 | |||
79 | /* maybe protected by c->lock */ | ||
80 | struct list_head node; | ||
81 | unsigned sglen; | ||
82 | struct sa11x0_dma_sg sg[0]; | ||
83 | }; | ||
84 | |||
85 | struct sa11x0_dma_phy; | ||
86 | |||
87 | struct sa11x0_dma_chan { | ||
88 | struct dma_chan chan; | ||
89 | spinlock_t lock; | ||
90 | dma_cookie_t lc; | ||
91 | |||
92 | /* protected by c->lock */ | ||
93 | struct sa11x0_dma_phy *phy; | ||
94 | enum dma_status status; | ||
95 | struct list_head desc_submitted; | ||
96 | struct list_head desc_issued; | ||
97 | |||
98 | /* protected by d->lock */ | ||
99 | struct list_head node; | ||
100 | |||
101 | u32 ddar; | ||
102 | const char *name; | ||
103 | }; | ||
104 | |||
105 | struct sa11x0_dma_phy { | ||
106 | void __iomem *base; | ||
107 | struct sa11x0_dma_dev *dev; | ||
108 | unsigned num; | ||
109 | |||
110 | struct sa11x0_dma_chan *vchan; | ||
111 | |||
112 | /* Protected by c->lock */ | ||
113 | unsigned sg_load; | ||
114 | struct sa11x0_dma_desc *txd_load; | ||
115 | unsigned sg_done; | ||
116 | struct sa11x0_dma_desc *txd_done; | ||
117 | #ifdef CONFIG_PM_SLEEP | ||
118 | u32 dbs[2]; | ||
119 | u32 dbt[2]; | ||
120 | u32 dcsr; | ||
121 | #endif | ||
122 | }; | ||
123 | |||
124 | struct sa11x0_dma_dev { | ||
125 | struct dma_device slave; | ||
126 | void __iomem *base; | ||
127 | spinlock_t lock; | ||
128 | struct tasklet_struct task; | ||
129 | struct list_head chan_pending; | ||
130 | struct list_head desc_complete; | ||
131 | struct sa11x0_dma_phy phy[NR_PHY_CHAN]; | ||
132 | }; | ||
133 | |||
134 | static struct sa11x0_dma_chan *to_sa11x0_dma_chan(struct dma_chan *chan) | ||
135 | { | ||
136 | return container_of(chan, struct sa11x0_dma_chan, chan); | ||
137 | } | ||
138 | |||
139 | static struct sa11x0_dma_dev *to_sa11x0_dma(struct dma_device *dmadev) | ||
140 | { | ||
141 | return container_of(dmadev, struct sa11x0_dma_dev, slave); | ||
142 | } | ||
143 | |||
144 | static struct sa11x0_dma_desc *to_sa11x0_dma_tx(struct dma_async_tx_descriptor *tx) | ||
145 | { | ||
146 | return container_of(tx, struct sa11x0_dma_desc, tx); | ||
147 | } | ||
148 | |||
149 | static struct sa11x0_dma_desc *sa11x0_dma_next_desc(struct sa11x0_dma_chan *c) | ||
150 | { | ||
151 | if (list_empty(&c->desc_issued)) | ||
152 | return NULL; | ||
153 | |||
154 | return list_first_entry(&c->desc_issued, struct sa11x0_dma_desc, node); | ||
155 | } | ||
156 | |||
157 | static void sa11x0_dma_start_desc(struct sa11x0_dma_phy *p, struct sa11x0_dma_desc *txd) | ||
158 | { | ||
159 | list_del(&txd->node); | ||
160 | p->txd_load = txd; | ||
161 | p->sg_load = 0; | ||
162 | |||
163 | dev_vdbg(p->dev->slave.dev, "pchan %u: txd %p[%x]: starting: DDAR:%x\n", | ||
164 | p->num, txd, txd->tx.cookie, txd->ddar); | ||
165 | } | ||
166 | |||
167 | static void noinline sa11x0_dma_start_sg(struct sa11x0_dma_phy *p, | ||
168 | struct sa11x0_dma_chan *c) | ||
169 | { | ||
170 | struct sa11x0_dma_desc *txd = p->txd_load; | ||
171 | struct sa11x0_dma_sg *sg; | ||
172 | void __iomem *base = p->base; | ||
173 | unsigned dbsx, dbtx; | ||
174 | u32 dcsr; | ||
175 | |||
176 | if (!txd) | ||
177 | return; | ||
178 | |||
179 | dcsr = readl_relaxed(base + DMA_DCSR_R); | ||
180 | |||
181 | /* Don't try to load the next transfer if both buffers are started */ | ||
182 | if ((dcsr & (DCSR_STRTA | DCSR_STRTB)) == (DCSR_STRTA | DCSR_STRTB)) | ||
183 | return; | ||
184 | |||
185 | if (p->sg_load == txd->sglen) { | ||
186 | struct sa11x0_dma_desc *txn = sa11x0_dma_next_desc(c); | ||
187 | |||
188 | /* | ||
189 | * We have reached the end of the current descriptor. | ||
190 | * Peek at the next descriptor, and if compatible with | ||
191 | * the current, start processing it. | ||
192 | */ | ||
193 | if (txn && txn->ddar == txd->ddar) { | ||
194 | txd = txn; | ||
195 | sa11x0_dma_start_desc(p, txn); | ||
196 | } else { | ||
197 | p->txd_load = NULL; | ||
198 | return; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | sg = &txd->sg[p->sg_load++]; | ||
203 | |||
204 | /* Select buffer to load according to channel status */ | ||
205 | if (((dcsr & (DCSR_BIU | DCSR_STRTB)) == (DCSR_BIU | DCSR_STRTB)) || | ||
206 | ((dcsr & (DCSR_BIU | DCSR_STRTA)) == 0)) { | ||
207 | dbsx = DMA_DBSA; | ||
208 | dbtx = DMA_DBTA; | ||
209 | dcsr = DCSR_STRTA | DCSR_IE | DCSR_RUN; | ||
210 | } else { | ||
211 | dbsx = DMA_DBSB; | ||
212 | dbtx = DMA_DBTB; | ||
213 | dcsr = DCSR_STRTB | DCSR_IE | DCSR_RUN; | ||
214 | } | ||
215 | |||
216 | writel_relaxed(sg->addr, base + dbsx); | ||
217 | writel_relaxed(sg->len, base + dbtx); | ||
218 | writel(dcsr, base + DMA_DCSR_S); | ||
219 | |||
220 | dev_dbg(p->dev->slave.dev, "pchan %u: load: DCSR:%02x DBS%c:%08x DBT%c:%08x\n", | ||
221 | p->num, dcsr, | ||
222 | 'A' + (dbsx == DMA_DBSB), sg->addr, | ||
223 | 'A' + (dbtx == DMA_DBTB), sg->len); | ||
224 | } | ||
225 | |||
226 | static void noinline sa11x0_dma_complete(struct sa11x0_dma_phy *p, | ||
227 | struct sa11x0_dma_chan *c) | ||
228 | { | ||
229 | struct sa11x0_dma_desc *txd = p->txd_done; | ||
230 | |||
231 | if (++p->sg_done == txd->sglen) { | ||
232 | struct sa11x0_dma_dev *d = p->dev; | ||
233 | |||
234 | dev_vdbg(d->slave.dev, "pchan %u: txd %p[%x]: completed\n", | ||
235 | p->num, p->txd_done, p->txd_done->tx.cookie); | ||
236 | |||
237 | c->lc = txd->tx.cookie; | ||
238 | |||
239 | spin_lock(&d->lock); | ||
240 | list_add_tail(&txd->node, &d->desc_complete); | ||
241 | spin_unlock(&d->lock); | ||
242 | |||
243 | p->sg_done = 0; | ||
244 | p->txd_done = p->txd_load; | ||
245 | |||
246 | tasklet_schedule(&d->task); | ||
247 | } | ||
248 | |||
249 | sa11x0_dma_start_sg(p, c); | ||
250 | } | ||
251 | |||
252 | static irqreturn_t sa11x0_dma_irq(int irq, void *dev_id) | ||
253 | { | ||
254 | struct sa11x0_dma_phy *p = dev_id; | ||
255 | struct sa11x0_dma_dev *d = p->dev; | ||
256 | struct sa11x0_dma_chan *c; | ||
257 | u32 dcsr; | ||
258 | |||
259 | dcsr = readl_relaxed(p->base + DMA_DCSR_R); | ||
260 | if (!(dcsr & (DCSR_ERROR | DCSR_DONEA | DCSR_DONEB))) | ||
261 | return IRQ_NONE; | ||
262 | |||
263 | /* Clear reported status bits */ | ||
264 | writel_relaxed(dcsr & (DCSR_ERROR | DCSR_DONEA | DCSR_DONEB), | ||
265 | p->base + DMA_DCSR_C); | ||
266 | |||
267 | dev_dbg(d->slave.dev, "pchan %u: irq: DCSR:%02x\n", p->num, dcsr); | ||
268 | |||
269 | if (dcsr & DCSR_ERROR) { | ||
270 | dev_err(d->slave.dev, "pchan %u: error. DCSR:%02x DDAR:%08x DBSA:%08x DBTA:%08x DBSB:%08x DBTB:%08x\n", | ||
271 | p->num, dcsr, | ||
272 | readl_relaxed(p->base + DMA_DDAR), | ||
273 | readl_relaxed(p->base + DMA_DBSA), | ||
274 | readl_relaxed(p->base + DMA_DBTA), | ||
275 | readl_relaxed(p->base + DMA_DBSB), | ||
276 | readl_relaxed(p->base + DMA_DBTB)); | ||
277 | } | ||
278 | |||
279 | c = p->vchan; | ||
280 | if (c) { | ||
281 | unsigned long flags; | ||
282 | |||
283 | spin_lock_irqsave(&c->lock, flags); | ||
284 | /* | ||
285 | * Now that we're holding the lock, check that the vchan | ||
286 | * really is associated with this pchan before touching the | ||
287 | * hardware. This should always succeed, because we won't | ||
288 | * change p->vchan or c->phy while the channel is actively | ||
289 | * transferring. | ||
290 | */ | ||
291 | if (c->phy == p) { | ||
292 | if (dcsr & DCSR_DONEA) | ||
293 | sa11x0_dma_complete(p, c); | ||
294 | if (dcsr & DCSR_DONEB) | ||
295 | sa11x0_dma_complete(p, c); | ||
296 | } | ||
297 | spin_unlock_irqrestore(&c->lock, flags); | ||
298 | } | ||
299 | |||
300 | return IRQ_HANDLED; | ||
301 | } | ||
302 | |||
303 | static void sa11x0_dma_start_txd(struct sa11x0_dma_chan *c) | ||
304 | { | ||
305 | struct sa11x0_dma_desc *txd = sa11x0_dma_next_desc(c); | ||
306 | |||
307 | /* If the issued list is empty, we have no further txds to process */ | ||
308 | if (txd) { | ||
309 | struct sa11x0_dma_phy *p = c->phy; | ||
310 | |||
311 | sa11x0_dma_start_desc(p, txd); | ||
312 | p->txd_done = txd; | ||
313 | p->sg_done = 0; | ||
314 | |||
315 | /* The channel should not have any transfers started */ | ||
316 | WARN_ON(readl_relaxed(p->base + DMA_DCSR_R) & | ||
317 | (DCSR_STRTA | DCSR_STRTB)); | ||
318 | |||
319 | /* Clear the run and start bits before changing DDAR */ | ||
320 | writel_relaxed(DCSR_RUN | DCSR_STRTA | DCSR_STRTB, | ||
321 | p->base + DMA_DCSR_C); | ||
322 | writel_relaxed(txd->ddar, p->base + DMA_DDAR); | ||
323 | |||
324 | /* Try to start both buffers */ | ||
325 | sa11x0_dma_start_sg(p, c); | ||
326 | sa11x0_dma_start_sg(p, c); | ||
327 | } | ||
328 | } | ||
329 | |||
330 | static void sa11x0_dma_tasklet(unsigned long arg) | ||
331 | { | ||
332 | struct sa11x0_dma_dev *d = (struct sa11x0_dma_dev *)arg; | ||
333 | struct sa11x0_dma_phy *p; | ||
334 | struct sa11x0_dma_chan *c; | ||
335 | struct sa11x0_dma_desc *txd, *txn; | ||
336 | LIST_HEAD(head); | ||
337 | unsigned pch, pch_alloc = 0; | ||
338 | |||
339 | dev_dbg(d->slave.dev, "tasklet enter\n"); | ||
340 | |||
341 | /* Get the completed tx descriptors */ | ||
342 | spin_lock_irq(&d->lock); | ||
343 | list_splice_init(&d->desc_complete, &head); | ||
344 | spin_unlock_irq(&d->lock); | ||
345 | |||
346 | list_for_each_entry(txd, &head, node) { | ||
347 | c = to_sa11x0_dma_chan(txd->tx.chan); | ||
348 | |||
349 | dev_dbg(d->slave.dev, "vchan %p: txd %p[%x] completed\n", | ||
350 | c, txd, txd->tx.cookie); | ||
351 | |||
352 | spin_lock_irq(&c->lock); | ||
353 | p = c->phy; | ||
354 | if (p) { | ||
355 | if (!p->txd_done) | ||
356 | sa11x0_dma_start_txd(c); | ||
357 | if (!p->txd_done) { | ||
358 | /* No current txd associated with this channel */ | ||
359 | dev_dbg(d->slave.dev, "pchan %u: free\n", p->num); | ||
360 | |||
361 | /* Mark this channel free */ | ||
362 | c->phy = NULL; | ||
363 | p->vchan = NULL; | ||
364 | } | ||
365 | } | ||
366 | spin_unlock_irq(&c->lock); | ||
367 | } | ||
368 | |||
369 | spin_lock_irq(&d->lock); | ||
370 | for (pch = 0; pch < NR_PHY_CHAN; pch++) { | ||
371 | p = &d->phy[pch]; | ||
372 | |||
373 | if (p->vchan == NULL && !list_empty(&d->chan_pending)) { | ||
374 | c = list_first_entry(&d->chan_pending, | ||
375 | struct sa11x0_dma_chan, node); | ||
376 | list_del_init(&c->node); | ||
377 | |||
378 | pch_alloc |= 1 << pch; | ||
379 | |||
380 | /* Mark this channel allocated */ | ||
381 | p->vchan = c; | ||
382 | |||
383 | dev_dbg(d->slave.dev, "pchan %u: alloc vchan %p\n", pch, c); | ||
384 | } | ||
385 | } | ||
386 | spin_unlock_irq(&d->lock); | ||
387 | |||
388 | for (pch = 0; pch < NR_PHY_CHAN; pch++) { | ||
389 | if (pch_alloc & (1 << pch)) { | ||
390 | p = &d->phy[pch]; | ||
391 | c = p->vchan; | ||
392 | |||
393 | spin_lock_irq(&c->lock); | ||
394 | c->phy = p; | ||
395 | |||
396 | sa11x0_dma_start_txd(c); | ||
397 | spin_unlock_irq(&c->lock); | ||
398 | } | ||
399 | } | ||
400 | |||
401 | /* Now free the completed tx descriptor, and call their callbacks */ | ||
402 | list_for_each_entry_safe(txd, txn, &head, node) { | ||
403 | dma_async_tx_callback callback = txd->tx.callback; | ||
404 | void *callback_param = txd->tx.callback_param; | ||
405 | |||
406 | dev_dbg(d->slave.dev, "txd %p[%x]: callback and free\n", | ||
407 | txd, txd->tx.cookie); | ||
408 | |||
409 | kfree(txd); | ||
410 | |||
411 | if (callback) | ||
412 | callback(callback_param); | ||
413 | } | ||
414 | |||
415 | dev_dbg(d->slave.dev, "tasklet exit\n"); | ||
416 | } | ||
417 | |||
418 | |||
419 | static void sa11x0_dma_desc_free(struct sa11x0_dma_dev *d, struct list_head *head) | ||
420 | { | ||
421 | struct sa11x0_dma_desc *txd, *txn; | ||
422 | |||
423 | list_for_each_entry_safe(txd, txn, head, node) { | ||
424 | dev_dbg(d->slave.dev, "txd %p: freeing\n", txd); | ||
425 | kfree(txd); | ||
426 | } | ||
427 | } | ||
428 | |||
429 | static int sa11x0_dma_alloc_chan_resources(struct dma_chan *chan) | ||
430 | { | ||
431 | return 0; | ||
432 | } | ||
433 | |||
434 | static void sa11x0_dma_free_chan_resources(struct dma_chan *chan) | ||
435 | { | ||
436 | struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); | ||
437 | struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device); | ||
438 | unsigned long flags; | ||
439 | LIST_HEAD(head); | ||
440 | |||
441 | spin_lock_irqsave(&c->lock, flags); | ||
442 | spin_lock(&d->lock); | ||
443 | list_del_init(&c->node); | ||
444 | spin_unlock(&d->lock); | ||
445 | |||
446 | list_splice_tail_init(&c->desc_submitted, &head); | ||
447 | list_splice_tail_init(&c->desc_issued, &head); | ||
448 | spin_unlock_irqrestore(&c->lock, flags); | ||
449 | |||
450 | sa11x0_dma_desc_free(d, &head); | ||
451 | } | ||
452 | |||
453 | static dma_addr_t sa11x0_dma_pos(struct sa11x0_dma_phy *p) | ||
454 | { | ||
455 | unsigned reg; | ||
456 | u32 dcsr; | ||
457 | |||
458 | dcsr = readl_relaxed(p->base + DMA_DCSR_R); | ||
459 | |||
460 | if ((dcsr & (DCSR_BIU | DCSR_STRTA)) == DCSR_STRTA || | ||
461 | (dcsr & (DCSR_BIU | DCSR_STRTB)) == DCSR_BIU) | ||
462 | reg = DMA_DBSA; | ||
463 | else | ||
464 | reg = DMA_DBSB; | ||
465 | |||
466 | return readl_relaxed(p->base + reg); | ||
467 | } | ||
468 | |||
469 | static enum dma_status sa11x0_dma_tx_status(struct dma_chan *chan, | ||
470 | dma_cookie_t cookie, struct dma_tx_state *state) | ||
471 | { | ||
472 | struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); | ||
473 | struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device); | ||
474 | struct sa11x0_dma_phy *p; | ||
475 | struct sa11x0_dma_desc *txd; | ||
476 | dma_cookie_t last_used, last_complete; | ||
477 | unsigned long flags; | ||
478 | enum dma_status ret; | ||
479 | size_t bytes = 0; | ||
480 | |||
481 | last_used = c->chan.cookie; | ||
482 | last_complete = c->lc; | ||
483 | |||
484 | ret = dma_async_is_complete(cookie, last_complete, last_used); | ||
485 | if (ret == DMA_SUCCESS) { | ||
486 | dma_set_tx_state(state, last_complete, last_used, 0); | ||
487 | return ret; | ||
488 | } | ||
489 | |||
490 | spin_lock_irqsave(&c->lock, flags); | ||
491 | p = c->phy; | ||
492 | ret = c->status; | ||
493 | if (p) { | ||
494 | dma_addr_t addr = sa11x0_dma_pos(p); | ||
495 | |||
496 | dev_vdbg(d->slave.dev, "tx_status: addr:%x\n", addr); | ||
497 | |||
498 | txd = p->txd_done; | ||
499 | if (txd) { | ||
500 | unsigned i; | ||
501 | |||
502 | for (i = 0; i < txd->sglen; i++) { | ||
503 | dev_vdbg(d->slave.dev, "tx_status: [%u] %x+%x\n", | ||
504 | i, txd->sg[i].addr, txd->sg[i].len); | ||
505 | if (addr >= txd->sg[i].addr && | ||
506 | addr < txd->sg[i].addr + txd->sg[i].len) { | ||
507 | unsigned len; | ||
508 | |||
509 | len = txd->sg[i].len - | ||
510 | (addr - txd->sg[i].addr); | ||
511 | dev_vdbg(d->slave.dev, "tx_status: [%u] +%x\n", | ||
512 | i, len); | ||
513 | bytes += len; | ||
514 | i++; | ||
515 | break; | ||
516 | } | ||
517 | } | ||
518 | for (; i < txd->sglen; i++) { | ||
519 | dev_vdbg(d->slave.dev, "tx_status: [%u] %x+%x ++\n", | ||
520 | i, txd->sg[i].addr, txd->sg[i].len); | ||
521 | bytes += txd->sg[i].len; | ||
522 | } | ||
523 | } | ||
524 | if (txd != p->txd_load && p->txd_load) | ||
525 | bytes += p->txd_load->size; | ||
526 | } | ||
527 | list_for_each_entry(txd, &c->desc_issued, node) { | ||
528 | bytes += txd->size; | ||
529 | } | ||
530 | spin_unlock_irqrestore(&c->lock, flags); | ||
531 | |||
532 | dma_set_tx_state(state, last_complete, last_used, bytes); | ||
533 | |||
534 | dev_vdbg(d->slave.dev, "tx_status: bytes 0x%zx\n", bytes); | ||
535 | |||
536 | return ret; | ||
537 | } | ||
538 | |||
539 | /* | ||
540 | * Move pending txds to the issued list, and re-init pending list. | ||
541 | * If not already pending, add this channel to the list of pending | ||
542 | * channels and trigger the tasklet to run. | ||
543 | */ | ||
544 | static void sa11x0_dma_issue_pending(struct dma_chan *chan) | ||
545 | { | ||
546 | struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); | ||
547 | struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device); | ||
548 | unsigned long flags; | ||
549 | |||
550 | spin_lock_irqsave(&c->lock, flags); | ||
551 | list_splice_tail_init(&c->desc_submitted, &c->desc_issued); | ||
552 | if (!list_empty(&c->desc_issued)) { | ||
553 | spin_lock(&d->lock); | ||
554 | if (!c->phy && list_empty(&c->node)) { | ||
555 | list_add_tail(&c->node, &d->chan_pending); | ||
556 | tasklet_schedule(&d->task); | ||
557 | dev_dbg(d->slave.dev, "vchan %p: issued\n", c); | ||
558 | } | ||
559 | spin_unlock(&d->lock); | ||
560 | } else | ||
561 | dev_dbg(d->slave.dev, "vchan %p: nothing to issue\n", c); | ||
562 | spin_unlock_irqrestore(&c->lock, flags); | ||
563 | } | ||
564 | |||
565 | static dma_cookie_t sa11x0_dma_tx_submit(struct dma_async_tx_descriptor *tx) | ||
566 | { | ||
567 | struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(tx->chan); | ||
568 | struct sa11x0_dma_desc *txd = to_sa11x0_dma_tx(tx); | ||
569 | unsigned long flags; | ||
570 | |||
571 | spin_lock_irqsave(&c->lock, flags); | ||
572 | c->chan.cookie += 1; | ||
573 | if (c->chan.cookie < 0) | ||
574 | c->chan.cookie = 1; | ||
575 | txd->tx.cookie = c->chan.cookie; | ||
576 | |||
577 | list_add_tail(&txd->node, &c->desc_submitted); | ||
578 | spin_unlock_irqrestore(&c->lock, flags); | ||
579 | |||
580 | dev_dbg(tx->chan->device->dev, "vchan %p: txd %p[%x]: submitted\n", | ||
581 | c, txd, txd->tx.cookie); | ||
582 | |||
583 | return txd->tx.cookie; | ||
584 | } | ||
585 | |||
586 | static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg( | ||
587 | struct dma_chan *chan, struct scatterlist *sg, unsigned int sglen, | ||
588 | enum dma_transfer_direction dir, unsigned long flags) | ||
589 | { | ||
590 | struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); | ||
591 | struct sa11x0_dma_desc *txd; | ||
592 | struct scatterlist *sgent; | ||
593 | unsigned i, j = sglen; | ||
594 | size_t size = 0; | ||
595 | |||
596 | /* SA11x0 channels can only operate in their native direction */ | ||
597 | if (dir != (c->ddar & DDAR_RW ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV)) { | ||
598 | dev_err(chan->device->dev, "vchan %p: bad DMA direction: DDAR:%08x dir:%u\n", | ||
599 | c, c->ddar, dir); | ||
600 | return NULL; | ||
601 | } | ||
602 | |||
603 | /* Do not allow zero-sized txds */ | ||
604 | if (sglen == 0) | ||
605 | return NULL; | ||
606 | |||
607 | for_each_sg(sg, sgent, sglen, i) { | ||
608 | dma_addr_t addr = sg_dma_address(sgent); | ||
609 | unsigned int len = sg_dma_len(sgent); | ||
610 | |||
611 | if (len > DMA_MAX_SIZE) | ||
612 | j += DIV_ROUND_UP(len, DMA_MAX_SIZE & ~DMA_ALIGN) - 1; | ||
613 | if (addr & DMA_ALIGN) { | ||
614 | dev_dbg(chan->device->dev, "vchan %p: bad buffer alignment: %08x\n", | ||
615 | c, addr); | ||
616 | return NULL; | ||
617 | } | ||
618 | } | ||
619 | |||
620 | txd = kzalloc(sizeof(*txd) + j * sizeof(txd->sg[0]), GFP_ATOMIC); | ||
621 | if (!txd) { | ||
622 | dev_dbg(chan->device->dev, "vchan %p: kzalloc failed\n", c); | ||
623 | return NULL; | ||
624 | } | ||
625 | |||
626 | j = 0; | ||
627 | for_each_sg(sg, sgent, sglen, i) { | ||
628 | dma_addr_t addr = sg_dma_address(sgent); | ||
629 | unsigned len = sg_dma_len(sgent); | ||
630 | |||
631 | size += len; | ||
632 | |||
633 | do { | ||
634 | unsigned tlen = len; | ||
635 | |||
636 | /* | ||
637 | * Check whether the transfer will fit. If not, try | ||
638 | * to split the transfer up such that we end up with | ||
639 | * equal chunks - but make sure that we preserve the | ||
640 | * alignment. This avoids small segments. | ||
641 | */ | ||
642 | if (tlen > DMA_MAX_SIZE) { | ||
643 | unsigned mult = DIV_ROUND_UP(tlen, | ||
644 | DMA_MAX_SIZE & ~DMA_ALIGN); | ||
645 | |||
646 | tlen = (tlen / mult) & ~DMA_ALIGN; | ||
647 | } | ||
648 | |||
649 | txd->sg[j].addr = addr; | ||
650 | txd->sg[j].len = tlen; | ||
651 | |||
652 | addr += tlen; | ||
653 | len -= tlen; | ||
654 | j++; | ||
655 | } while (len); | ||
656 | } | ||
657 | |||
658 | dma_async_tx_descriptor_init(&txd->tx, &c->chan); | ||
659 | txd->tx.flags = flags; | ||
660 | txd->tx.tx_submit = sa11x0_dma_tx_submit; | ||
661 | txd->ddar = c->ddar; | ||
662 | txd->size = size; | ||
663 | txd->sglen = j; | ||
664 | |||
665 | dev_dbg(chan->device->dev, "vchan %p: txd %p: size %u nr %u\n", | ||
666 | c, txd, txd->size, txd->sglen); | ||
667 | |||
668 | return &txd->tx; | ||
669 | } | ||
670 | |||
671 | static int sa11x0_dma_slave_config(struct sa11x0_dma_chan *c, struct dma_slave_config *cfg) | ||
672 | { | ||
673 | u32 ddar = c->ddar & ((0xf << 4) | DDAR_RW); | ||
674 | dma_addr_t addr; | ||
675 | enum dma_slave_buswidth width; | ||
676 | u32 maxburst; | ||
677 | |||
678 | if (ddar & DDAR_RW) { | ||
679 | addr = cfg->src_addr; | ||
680 | width = cfg->src_addr_width; | ||
681 | maxburst = cfg->src_maxburst; | ||
682 | } else { | ||
683 | addr = cfg->dst_addr; | ||
684 | width = cfg->dst_addr_width; | ||
685 | maxburst = cfg->dst_maxburst; | ||
686 | } | ||
687 | |||
688 | if ((width != DMA_SLAVE_BUSWIDTH_1_BYTE && | ||
689 | width != DMA_SLAVE_BUSWIDTH_2_BYTES) || | ||
690 | (maxburst != 4 && maxburst != 8)) | ||
691 | return -EINVAL; | ||
692 | |||
693 | if (width == DMA_SLAVE_BUSWIDTH_2_BYTES) | ||
694 | ddar |= DDAR_DW; | ||
695 | if (maxburst == 8) | ||
696 | ddar |= DDAR_BS; | ||
697 | |||
698 | dev_dbg(c->chan.device->dev, "vchan %p: dma_slave_config addr %x width %u burst %u\n", | ||
699 | c, addr, width, maxburst); | ||
700 | |||
701 | c->ddar = ddar | (addr & 0xf0000000) | (addr & 0x003ffffc) << 6; | ||
702 | |||
703 | return 0; | ||
704 | } | ||
705 | |||
706 | static int sa11x0_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | ||
707 | unsigned long arg) | ||
708 | { | ||
709 | struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); | ||
710 | struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device); | ||
711 | struct sa11x0_dma_phy *p; | ||
712 | LIST_HEAD(head); | ||
713 | unsigned long flags; | ||
714 | int ret; | ||
715 | |||
716 | switch (cmd) { | ||
717 | case DMA_SLAVE_CONFIG: | ||
718 | return sa11x0_dma_slave_config(c, (struct dma_slave_config *)arg); | ||
719 | |||
720 | case DMA_TERMINATE_ALL: | ||
721 | dev_dbg(d->slave.dev, "vchan %p: terminate all\n", c); | ||
722 | /* Clear the tx descriptor lists */ | ||
723 | spin_lock_irqsave(&c->lock, flags); | ||
724 | list_splice_tail_init(&c->desc_submitted, &head); | ||
725 | list_splice_tail_init(&c->desc_issued, &head); | ||
726 | |||
727 | p = c->phy; | ||
728 | if (p) { | ||
729 | struct sa11x0_dma_desc *txd, *txn; | ||
730 | |||
731 | dev_dbg(d->slave.dev, "pchan %u: terminating\n", p->num); | ||
732 | /* vchan is assigned to a pchan - stop the channel */ | ||
733 | writel(DCSR_RUN | DCSR_IE | | ||
734 | DCSR_STRTA | DCSR_DONEA | | ||
735 | DCSR_STRTB | DCSR_DONEB, | ||
736 | p->base + DMA_DCSR_C); | ||
737 | |||
738 | list_for_each_entry_safe(txd, txn, &d->desc_complete, node) | ||
739 | if (txd->tx.chan == &c->chan) | ||
740 | list_move(&txd->node, &head); | ||
741 | |||
742 | if (p->txd_load) { | ||
743 | if (p->txd_load != p->txd_done) | ||
744 | list_add_tail(&p->txd_load->node, &head); | ||
745 | p->txd_load = NULL; | ||
746 | } | ||
747 | if (p->txd_done) { | ||
748 | list_add_tail(&p->txd_done->node, &head); | ||
749 | p->txd_done = NULL; | ||
750 | } | ||
751 | c->phy = NULL; | ||
752 | spin_lock(&d->lock); | ||
753 | p->vchan = NULL; | ||
754 | spin_unlock(&d->lock); | ||
755 | tasklet_schedule(&d->task); | ||
756 | } | ||
757 | spin_unlock_irqrestore(&c->lock, flags); | ||
758 | sa11x0_dma_desc_free(d, &head); | ||
759 | ret = 0; | ||
760 | break; | ||
761 | |||
762 | case DMA_PAUSE: | ||
763 | dev_dbg(d->slave.dev, "vchan %p: pause\n", c); | ||
764 | spin_lock_irqsave(&c->lock, flags); | ||
765 | if (c->status == DMA_IN_PROGRESS) { | ||
766 | c->status = DMA_PAUSED; | ||
767 | |||
768 | p = c->phy; | ||
769 | if (p) { | ||
770 | writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_C); | ||
771 | } else { | ||
772 | spin_lock(&d->lock); | ||
773 | list_del_init(&c->node); | ||
774 | spin_unlock(&d->lock); | ||
775 | } | ||
776 | } | ||
777 | spin_unlock_irqrestore(&c->lock, flags); | ||
778 | ret = 0; | ||
779 | break; | ||
780 | |||
781 | case DMA_RESUME: | ||
782 | dev_dbg(d->slave.dev, "vchan %p: resume\n", c); | ||
783 | spin_lock_irqsave(&c->lock, flags); | ||
784 | if (c->status == DMA_PAUSED) { | ||
785 | c->status = DMA_IN_PROGRESS; | ||
786 | |||
787 | p = c->phy; | ||
788 | if (p) { | ||
789 | writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_S); | ||
790 | } else if (!list_empty(&c->desc_issued)) { | ||
791 | spin_lock(&d->lock); | ||
792 | list_add_tail(&c->node, &d->chan_pending); | ||
793 | spin_unlock(&d->lock); | ||
794 | } | ||
795 | } | ||
796 | spin_unlock_irqrestore(&c->lock, flags); | ||
797 | ret = 0; | ||
798 | break; | ||
799 | |||
800 | default: | ||
801 | ret = -ENXIO; | ||
802 | break; | ||
803 | } | ||
804 | |||
805 | return ret; | ||
806 | } | ||
807 | |||
808 | struct sa11x0_dma_channel_desc { | ||
809 | u32 ddar; | ||
810 | const char *name; | ||
811 | }; | ||
812 | |||
813 | #define CD(d1, d2) { .ddar = DDAR_##d1 | d2, .name = #d1 } | ||
814 | static const struct sa11x0_dma_channel_desc chan_desc[] = { | ||
815 | CD(Ser0UDCTr, 0), | ||
816 | CD(Ser0UDCRc, DDAR_RW), | ||
817 | CD(Ser1SDLCTr, 0), | ||
818 | CD(Ser1SDLCRc, DDAR_RW), | ||
819 | CD(Ser1UARTTr, 0), | ||
820 | CD(Ser1UARTRc, DDAR_RW), | ||
821 | CD(Ser2ICPTr, 0), | ||
822 | CD(Ser2ICPRc, DDAR_RW), | ||
823 | CD(Ser3UARTTr, 0), | ||
824 | CD(Ser3UARTRc, DDAR_RW), | ||
825 | CD(Ser4MCP0Tr, 0), | ||
826 | CD(Ser4MCP0Rc, DDAR_RW), | ||
827 | CD(Ser4MCP1Tr, 0), | ||
828 | CD(Ser4MCP1Rc, DDAR_RW), | ||
829 | CD(Ser4SSPTr, 0), | ||
830 | CD(Ser4SSPRc, DDAR_RW), | ||
831 | }; | ||
832 | |||
833 | static int __devinit sa11x0_dma_init_dmadev(struct dma_device *dmadev, | ||
834 | struct device *dev) | ||
835 | { | ||
836 | unsigned i; | ||
837 | |||
838 | dmadev->chancnt = ARRAY_SIZE(chan_desc); | ||
839 | INIT_LIST_HEAD(&dmadev->channels); | ||
840 | dmadev->dev = dev; | ||
841 | dmadev->device_alloc_chan_resources = sa11x0_dma_alloc_chan_resources; | ||
842 | dmadev->device_free_chan_resources = sa11x0_dma_free_chan_resources; | ||
843 | dmadev->device_control = sa11x0_dma_control; | ||
844 | dmadev->device_tx_status = sa11x0_dma_tx_status; | ||
845 | dmadev->device_issue_pending = sa11x0_dma_issue_pending; | ||
846 | |||
847 | for (i = 0; i < dmadev->chancnt; i++) { | ||
848 | struct sa11x0_dma_chan *c; | ||
849 | |||
850 | c = kzalloc(sizeof(*c), GFP_KERNEL); | ||
851 | if (!c) { | ||
852 | dev_err(dev, "no memory for channel %u\n", i); | ||
853 | return -ENOMEM; | ||
854 | } | ||
855 | |||
856 | c->chan.device = dmadev; | ||
857 | c->status = DMA_IN_PROGRESS; | ||
858 | c->ddar = chan_desc[i].ddar; | ||
859 | c->name = chan_desc[i].name; | ||
860 | spin_lock_init(&c->lock); | ||
861 | INIT_LIST_HEAD(&c->desc_submitted); | ||
862 | INIT_LIST_HEAD(&c->desc_issued); | ||
863 | INIT_LIST_HEAD(&c->node); | ||
864 | list_add_tail(&c->chan.device_node, &dmadev->channels); | ||
865 | } | ||
866 | |||
867 | return dma_async_device_register(dmadev); | ||
868 | } | ||
869 | |||
870 | static int sa11x0_dma_request_irq(struct platform_device *pdev, int nr, | ||
871 | void *data) | ||
872 | { | ||
873 | int irq = platform_get_irq(pdev, nr); | ||
874 | |||
875 | if (irq <= 0) | ||
876 | return -ENXIO; | ||
877 | |||
878 | return request_irq(irq, sa11x0_dma_irq, 0, dev_name(&pdev->dev), data); | ||
879 | } | ||
880 | |||
881 | static void sa11x0_dma_free_irq(struct platform_device *pdev, int nr, | ||
882 | void *data) | ||
883 | { | ||
884 | int irq = platform_get_irq(pdev, nr); | ||
885 | if (irq > 0) | ||
886 | free_irq(irq, data); | ||
887 | } | ||
888 | |||
889 | static void sa11x0_dma_free_channels(struct dma_device *dmadev) | ||
890 | { | ||
891 | struct sa11x0_dma_chan *c, *cn; | ||
892 | |||
893 | list_for_each_entry_safe(c, cn, &dmadev->channels, chan.device_node) { | ||
894 | list_del(&c->chan.device_node); | ||
895 | kfree(c); | ||
896 | } | ||
897 | } | ||
898 | |||
899 | static int __devinit sa11x0_dma_probe(struct platform_device *pdev) | ||
900 | { | ||
901 | struct sa11x0_dma_dev *d; | ||
902 | struct resource *res; | ||
903 | unsigned i; | ||
904 | int ret; | ||
905 | |||
906 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
907 | if (!res) | ||
908 | return -ENXIO; | ||
909 | |||
910 | d = kzalloc(sizeof(*d), GFP_KERNEL); | ||
911 | if (!d) { | ||
912 | ret = -ENOMEM; | ||
913 | goto err_alloc; | ||
914 | } | ||
915 | |||
916 | spin_lock_init(&d->lock); | ||
917 | INIT_LIST_HEAD(&d->chan_pending); | ||
918 | INIT_LIST_HEAD(&d->desc_complete); | ||
919 | |||
920 | d->base = ioremap(res->start, resource_size(res)); | ||
921 | if (!d->base) { | ||
922 | ret = -ENOMEM; | ||
923 | goto err_ioremap; | ||
924 | } | ||
925 | |||
926 | tasklet_init(&d->task, sa11x0_dma_tasklet, (unsigned long)d); | ||
927 | |||
928 | for (i = 0; i < NR_PHY_CHAN; i++) { | ||
929 | struct sa11x0_dma_phy *p = &d->phy[i]; | ||
930 | |||
931 | p->dev = d; | ||
932 | p->num = i; | ||
933 | p->base = d->base + i * DMA_SIZE; | ||
934 | writel_relaxed(DCSR_RUN | DCSR_IE | DCSR_ERROR | | ||
935 | DCSR_DONEA | DCSR_STRTA | DCSR_DONEB | DCSR_STRTB, | ||
936 | p->base + DMA_DCSR_C); | ||
937 | writel_relaxed(0, p->base + DMA_DDAR); | ||
938 | |||
939 | ret = sa11x0_dma_request_irq(pdev, i, p); | ||
940 | if (ret) { | ||
941 | while (i) { | ||
942 | i--; | ||
943 | sa11x0_dma_free_irq(pdev, i, &d->phy[i]); | ||
944 | } | ||
945 | goto err_irq; | ||
946 | } | ||
947 | } | ||
948 | |||
949 | dma_cap_set(DMA_SLAVE, d->slave.cap_mask); | ||
950 | d->slave.device_prep_slave_sg = sa11x0_dma_prep_slave_sg; | ||
951 | ret = sa11x0_dma_init_dmadev(&d->slave, &pdev->dev); | ||
952 | if (ret) { | ||
953 | dev_warn(d->slave.dev, "failed to register slave async device: %d\n", | ||
954 | ret); | ||
955 | goto err_slave_reg; | ||
956 | } | ||
957 | |||
958 | platform_set_drvdata(pdev, d); | ||
959 | return 0; | ||
960 | |||
961 | err_slave_reg: | ||
962 | sa11x0_dma_free_channels(&d->slave); | ||
963 | for (i = 0; i < NR_PHY_CHAN; i++) | ||
964 | sa11x0_dma_free_irq(pdev, i, &d->phy[i]); | ||
965 | err_irq: | ||
966 | tasklet_kill(&d->task); | ||
967 | iounmap(d->base); | ||
968 | err_ioremap: | ||
969 | kfree(d); | ||
970 | err_alloc: | ||
971 | return ret; | ||
972 | } | ||
973 | |||
974 | static int __devexit sa11x0_dma_remove(struct platform_device *pdev) | ||
975 | { | ||
976 | struct sa11x0_dma_dev *d = platform_get_drvdata(pdev); | ||
977 | unsigned pch; | ||
978 | |||
979 | dma_async_device_unregister(&d->slave); | ||
980 | |||
981 | sa11x0_dma_free_channels(&d->slave); | ||
982 | for (pch = 0; pch < NR_PHY_CHAN; pch++) | ||
983 | sa11x0_dma_free_irq(pdev, pch, &d->phy[pch]); | ||
984 | tasklet_kill(&d->task); | ||
985 | iounmap(d->base); | ||
986 | kfree(d); | ||
987 | |||
988 | return 0; | ||
989 | } | ||
990 | |||
991 | #ifdef CONFIG_PM_SLEEP | ||
992 | static int sa11x0_dma_suspend(struct device *dev) | ||
993 | { | ||
994 | struct sa11x0_dma_dev *d = dev_get_drvdata(dev); | ||
995 | unsigned pch; | ||
996 | |||
997 | for (pch = 0; pch < NR_PHY_CHAN; pch++) { | ||
998 | struct sa11x0_dma_phy *p = &d->phy[pch]; | ||
999 | u32 dcsr, saved_dcsr; | ||
1000 | |||
1001 | dcsr = saved_dcsr = readl_relaxed(p->base + DMA_DCSR_R); | ||
1002 | if (dcsr & DCSR_RUN) { | ||
1003 | writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_C); | ||
1004 | dcsr = readl_relaxed(p->base + DMA_DCSR_R); | ||
1005 | } | ||
1006 | |||
1007 | saved_dcsr &= DCSR_RUN | DCSR_IE; | ||
1008 | if (dcsr & DCSR_BIU) { | ||
1009 | p->dbs[0] = readl_relaxed(p->base + DMA_DBSB); | ||
1010 | p->dbt[0] = readl_relaxed(p->base + DMA_DBTB); | ||
1011 | p->dbs[1] = readl_relaxed(p->base + DMA_DBSA); | ||
1012 | p->dbt[1] = readl_relaxed(p->base + DMA_DBTA); | ||
1013 | saved_dcsr |= (dcsr & DCSR_STRTA ? DCSR_STRTB : 0) | | ||
1014 | (dcsr & DCSR_STRTB ? DCSR_STRTA : 0); | ||
1015 | } else { | ||
1016 | p->dbs[0] = readl_relaxed(p->base + DMA_DBSA); | ||
1017 | p->dbt[0] = readl_relaxed(p->base + DMA_DBTA); | ||
1018 | p->dbs[1] = readl_relaxed(p->base + DMA_DBSB); | ||
1019 | p->dbt[1] = readl_relaxed(p->base + DMA_DBTB); | ||
1020 | saved_dcsr |= dcsr & (DCSR_STRTA | DCSR_STRTB); | ||
1021 | } | ||
1022 | p->dcsr = saved_dcsr; | ||
1023 | |||
1024 | writel(DCSR_STRTA | DCSR_STRTB, p->base + DMA_DCSR_C); | ||
1025 | } | ||
1026 | |||
1027 | return 0; | ||
1028 | } | ||
1029 | |||
1030 | static int sa11x0_dma_resume(struct device *dev) | ||
1031 | { | ||
1032 | struct sa11x0_dma_dev *d = dev_get_drvdata(dev); | ||
1033 | unsigned pch; | ||
1034 | |||
1035 | for (pch = 0; pch < NR_PHY_CHAN; pch++) { | ||
1036 | struct sa11x0_dma_phy *p = &d->phy[pch]; | ||
1037 | struct sa11x0_dma_desc *txd = NULL; | ||
1038 | u32 dcsr = readl_relaxed(p->base + DMA_DCSR_R); | ||
1039 | |||
1040 | WARN_ON(dcsr & (DCSR_BIU | DCSR_STRTA | DCSR_STRTB | DCSR_RUN)); | ||
1041 | |||
1042 | if (p->txd_done) | ||
1043 | txd = p->txd_done; | ||
1044 | else if (p->txd_load) | ||
1045 | txd = p->txd_load; | ||
1046 | |||
1047 | if (!txd) | ||
1048 | continue; | ||
1049 | |||
1050 | writel_relaxed(txd->ddar, p->base + DMA_DDAR); | ||
1051 | |||
1052 | writel_relaxed(p->dbs[0], p->base + DMA_DBSA); | ||
1053 | writel_relaxed(p->dbt[0], p->base + DMA_DBTA); | ||
1054 | writel_relaxed(p->dbs[1], p->base + DMA_DBSB); | ||
1055 | writel_relaxed(p->dbt[1], p->base + DMA_DBTB); | ||
1056 | writel_relaxed(p->dcsr, p->base + DMA_DCSR_S); | ||
1057 | } | ||
1058 | |||
1059 | return 0; | ||
1060 | } | ||
1061 | #endif | ||
1062 | |||
1063 | static const struct dev_pm_ops sa11x0_dma_pm_ops = { | ||
1064 | .suspend_noirq = sa11x0_dma_suspend, | ||
1065 | .resume_noirq = sa11x0_dma_resume, | ||
1066 | .freeze_noirq = sa11x0_dma_suspend, | ||
1067 | .thaw_noirq = sa11x0_dma_resume, | ||
1068 | .poweroff_noirq = sa11x0_dma_suspend, | ||
1069 | .restore_noirq = sa11x0_dma_resume, | ||
1070 | }; | ||
1071 | |||
1072 | static struct platform_driver sa11x0_dma_driver = { | ||
1073 | .driver = { | ||
1074 | .name = "sa11x0-dma", | ||
1075 | .owner = THIS_MODULE, | ||
1076 | .pm = &sa11x0_dma_pm_ops, | ||
1077 | }, | ||
1078 | .probe = sa11x0_dma_probe, | ||
1079 | .remove = __devexit_p(sa11x0_dma_remove), | ||
1080 | }; | ||
1081 | |||
1082 | bool sa11x0_dma_filter_fn(struct dma_chan *chan, void *param) | ||
1083 | { | ||
1084 | if (chan->device->dev->driver == &sa11x0_dma_driver.driver) { | ||
1085 | struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); | ||
1086 | const char *p = param; | ||
1087 | |||
1088 | return !strcmp(c->name, p); | ||
1089 | } | ||
1090 | return false; | ||
1091 | } | ||
1092 | EXPORT_SYMBOL(sa11x0_dma_filter_fn); | ||
1093 | |||
1094 | static int __init sa11x0_dma_init(void) | ||
1095 | { | ||
1096 | return platform_driver_register(&sa11x0_dma_driver); | ||
1097 | } | ||
1098 | subsys_initcall(sa11x0_dma_init); | ||
1099 | |||
1100 | static void __exit sa11x0_dma_exit(void) | ||
1101 | { | ||
1102 | platform_driver_unregister(&sa11x0_dma_driver); | ||
1103 | } | ||
1104 | module_exit(sa11x0_dma_exit); | ||
1105 | |||
1106 | MODULE_AUTHOR("Russell King"); | ||
1107 | MODULE_DESCRIPTION("SA-11x0 DMA driver"); | ||
1108 | MODULE_LICENSE("GPL v2"); | ||
1109 | MODULE_ALIAS("platform:sa11x0-dma"); | ||
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c index 44fc8b4bcd81..5ebabe3fc845 100644 --- a/drivers/input/serio/sa1111ps2.c +++ b/drivers/input/serio/sa1111ps2.c | |||
@@ -24,6 +24,26 @@ | |||
24 | 24 | ||
25 | #include <asm/hardware/sa1111.h> | 25 | #include <asm/hardware/sa1111.h> |
26 | 26 | ||
27 | #define PS2CR 0x0000 | ||
28 | #define PS2STAT 0x0004 | ||
29 | #define PS2DATA 0x0008 | ||
30 | #define PS2CLKDIV 0x000c | ||
31 | #define PS2PRECNT 0x0010 | ||
32 | |||
33 | #define PS2CR_ENA 0x08 | ||
34 | #define PS2CR_FKD 0x02 | ||
35 | #define PS2CR_FKC 0x01 | ||
36 | |||
37 | #define PS2STAT_STP 0x0100 | ||
38 | #define PS2STAT_TXE 0x0080 | ||
39 | #define PS2STAT_TXB 0x0040 | ||
40 | #define PS2STAT_RXF 0x0020 | ||
41 | #define PS2STAT_RXB 0x0010 | ||
42 | #define PS2STAT_ENA 0x0008 | ||
43 | #define PS2STAT_RXP 0x0004 | ||
44 | #define PS2STAT_KBD 0x0002 | ||
45 | #define PS2STAT_KBC 0x0001 | ||
46 | |||
27 | struct ps2if { | 47 | struct ps2if { |
28 | struct serio *io; | 48 | struct serio *io; |
29 | struct sa1111_dev *dev; | 49 | struct sa1111_dev *dev; |
@@ -45,22 +65,22 @@ static irqreturn_t ps2_rxint(int irq, void *dev_id) | |||
45 | struct ps2if *ps2if = dev_id; | 65 | struct ps2if *ps2if = dev_id; |
46 | unsigned int scancode, flag, status; | 66 | unsigned int scancode, flag, status; |
47 | 67 | ||
48 | status = sa1111_readl(ps2if->base + SA1111_PS2STAT); | 68 | status = sa1111_readl(ps2if->base + PS2STAT); |
49 | while (status & PS2STAT_RXF) { | 69 | while (status & PS2STAT_RXF) { |
50 | if (status & PS2STAT_STP) | 70 | if (status & PS2STAT_STP) |
51 | sa1111_writel(PS2STAT_STP, ps2if->base + SA1111_PS2STAT); | 71 | sa1111_writel(PS2STAT_STP, ps2if->base + PS2STAT); |
52 | 72 | ||
53 | flag = (status & PS2STAT_STP ? SERIO_FRAME : 0) | | 73 | flag = (status & PS2STAT_STP ? SERIO_FRAME : 0) | |
54 | (status & PS2STAT_RXP ? 0 : SERIO_PARITY); | 74 | (status & PS2STAT_RXP ? 0 : SERIO_PARITY); |
55 | 75 | ||
56 | scancode = sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff; | 76 | scancode = sa1111_readl(ps2if->base + PS2DATA) & 0xff; |
57 | 77 | ||
58 | if (hweight8(scancode) & 1) | 78 | if (hweight8(scancode) & 1) |
59 | flag ^= SERIO_PARITY; | 79 | flag ^= SERIO_PARITY; |
60 | 80 | ||
61 | serio_interrupt(ps2if->io, scancode, flag); | 81 | serio_interrupt(ps2if->io, scancode, flag); |
62 | 82 | ||
63 | status = sa1111_readl(ps2if->base + SA1111_PS2STAT); | 83 | status = sa1111_readl(ps2if->base + PS2STAT); |
64 | } | 84 | } |
65 | 85 | ||
66 | return IRQ_HANDLED; | 86 | return IRQ_HANDLED; |
@@ -75,12 +95,12 @@ static irqreturn_t ps2_txint(int irq, void *dev_id) | |||
75 | unsigned int status; | 95 | unsigned int status; |
76 | 96 | ||
77 | spin_lock(&ps2if->lock); | 97 | spin_lock(&ps2if->lock); |
78 | status = sa1111_readl(ps2if->base + SA1111_PS2STAT); | 98 | status = sa1111_readl(ps2if->base + PS2STAT); |
79 | if (ps2if->head == ps2if->tail) { | 99 | if (ps2if->head == ps2if->tail) { |
80 | disable_irq_nosync(irq); | 100 | disable_irq_nosync(irq); |
81 | /* done */ | 101 | /* done */ |
82 | } else if (status & PS2STAT_TXE) { | 102 | } else if (status & PS2STAT_TXE) { |
83 | sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + SA1111_PS2DATA); | 103 | sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + PS2DATA); |
84 | ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1); | 104 | ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1); |
85 | } | 105 | } |
86 | spin_unlock(&ps2if->lock); | 106 | spin_unlock(&ps2if->lock); |
@@ -103,8 +123,8 @@ static int ps2_write(struct serio *io, unsigned char val) | |||
103 | /* | 123 | /* |
104 | * If the TX register is empty, we can go straight out. | 124 | * If the TX register is empty, we can go straight out. |
105 | */ | 125 | */ |
106 | if (sa1111_readl(ps2if->base + SA1111_PS2STAT) & PS2STAT_TXE) { | 126 | if (sa1111_readl(ps2if->base + PS2STAT) & PS2STAT_TXE) { |
107 | sa1111_writel(val, ps2if->base + SA1111_PS2DATA); | 127 | sa1111_writel(val, ps2if->base + PS2DATA); |
108 | } else { | 128 | } else { |
109 | if (ps2if->head == ps2if->tail) | 129 | if (ps2if->head == ps2if->tail) |
110 | enable_irq(ps2if->dev->irq[1]); | 130 | enable_irq(ps2if->dev->irq[1]); |
@@ -124,13 +144,16 @@ static int ps2_open(struct serio *io) | |||
124 | struct ps2if *ps2if = io->port_data; | 144 | struct ps2if *ps2if = io->port_data; |
125 | int ret; | 145 | int ret; |
126 | 146 | ||
127 | sa1111_enable_device(ps2if->dev); | 147 | ret = sa1111_enable_device(ps2if->dev); |
148 | if (ret) | ||
149 | return ret; | ||
128 | 150 | ||
129 | ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0, | 151 | ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0, |
130 | SA1111_DRIVER_NAME(ps2if->dev), ps2if); | 152 | SA1111_DRIVER_NAME(ps2if->dev), ps2if); |
131 | if (ret) { | 153 | if (ret) { |
132 | printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", | 154 | printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", |
133 | ps2if->dev->irq[0], ret); | 155 | ps2if->dev->irq[0], ret); |
156 | sa1111_disable_device(ps2if->dev); | ||
134 | return ret; | 157 | return ret; |
135 | } | 158 | } |
136 | 159 | ||
@@ -140,6 +163,7 @@ static int ps2_open(struct serio *io) | |||
140 | printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", | 163 | printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", |
141 | ps2if->dev->irq[1], ret); | 164 | ps2if->dev->irq[1], ret); |
142 | free_irq(ps2if->dev->irq[0], ps2if); | 165 | free_irq(ps2if->dev->irq[0], ps2if); |
166 | sa1111_disable_device(ps2if->dev); | ||
143 | return ret; | 167 | return ret; |
144 | } | 168 | } |
145 | 169 | ||
@@ -147,7 +171,7 @@ static int ps2_open(struct serio *io) | |||
147 | 171 | ||
148 | enable_irq_wake(ps2if->dev->irq[0]); | 172 | enable_irq_wake(ps2if->dev->irq[0]); |
149 | 173 | ||
150 | sa1111_writel(PS2CR_ENA, ps2if->base + SA1111_PS2CR); | 174 | sa1111_writel(PS2CR_ENA, ps2if->base + PS2CR); |
151 | return 0; | 175 | return 0; |
152 | } | 176 | } |
153 | 177 | ||
@@ -155,7 +179,7 @@ static void ps2_close(struct serio *io) | |||
155 | { | 179 | { |
156 | struct ps2if *ps2if = io->port_data; | 180 | struct ps2if *ps2if = io->port_data; |
157 | 181 | ||
158 | sa1111_writel(0, ps2if->base + SA1111_PS2CR); | 182 | sa1111_writel(0, ps2if->base + PS2CR); |
159 | 183 | ||
160 | disable_irq_wake(ps2if->dev->irq[0]); | 184 | disable_irq_wake(ps2if->dev->irq[0]); |
161 | 185 | ||
@@ -175,7 +199,7 @@ static void __devinit ps2_clear_input(struct ps2if *ps2if) | |||
175 | int maxread = 100; | 199 | int maxread = 100; |
176 | 200 | ||
177 | while (maxread--) { | 201 | while (maxread--) { |
178 | if ((sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff) == 0xff) | 202 | if ((sa1111_readl(ps2if->base + PS2DATA) & 0xff) == 0xff) |
179 | break; | 203 | break; |
180 | } | 204 | } |
181 | } | 205 | } |
@@ -185,11 +209,11 @@ static unsigned int __devinit ps2_test_one(struct ps2if *ps2if, | |||
185 | { | 209 | { |
186 | unsigned int val; | 210 | unsigned int val; |
187 | 211 | ||
188 | sa1111_writel(PS2CR_ENA | mask, ps2if->base + SA1111_PS2CR); | 212 | sa1111_writel(PS2CR_ENA | mask, ps2if->base + PS2CR); |
189 | 213 | ||
190 | udelay(2); | 214 | udelay(2); |
191 | 215 | ||
192 | val = sa1111_readl(ps2if->base + SA1111_PS2STAT); | 216 | val = sa1111_readl(ps2if->base + PS2STAT); |
193 | return val & (PS2STAT_KBC | PS2STAT_KBD); | 217 | return val & (PS2STAT_KBC | PS2STAT_KBD); |
194 | } | 218 | } |
195 | 219 | ||
@@ -220,7 +244,7 @@ static int __devinit ps2_test(struct ps2if *ps2if) | |||
220 | ret = -ENODEV; | 244 | ret = -ENODEV; |
221 | } | 245 | } |
222 | 246 | ||
223 | sa1111_writel(0, ps2if->base + SA1111_PS2CR); | 247 | sa1111_writel(0, ps2if->base + PS2CR); |
224 | 248 | ||
225 | return ret; | 249 | return ret; |
226 | } | 250 | } |
@@ -274,8 +298,8 @@ static int __devinit ps2_probe(struct sa1111_dev *dev) | |||
274 | sa1111_enable_device(ps2if->dev); | 298 | sa1111_enable_device(ps2if->dev); |
275 | 299 | ||
276 | /* Incoming clock is 8MHz */ | 300 | /* Incoming clock is 8MHz */ |
277 | sa1111_writel(0, ps2if->base + SA1111_PS2CLKDIV); | 301 | sa1111_writel(0, ps2if->base + PS2CLKDIV); |
278 | sa1111_writel(127, ps2if->base + SA1111_PS2PRECNT); | 302 | sa1111_writel(127, ps2if->base + PS2PRECNT); |
279 | 303 | ||
280 | /* | 304 | /* |
281 | * Flush any pending input. | 305 | * Flush any pending input. |
@@ -330,6 +354,7 @@ static int __devexit ps2_remove(struct sa1111_dev *dev) | |||
330 | static struct sa1111_driver ps2_driver = { | 354 | static struct sa1111_driver ps2_driver = { |
331 | .drv = { | 355 | .drv = { |
332 | .name = "sa1111-ps2", | 356 | .name = "sa1111-ps2", |
357 | .owner = THIS_MODULE, | ||
333 | }, | 358 | }, |
334 | .devid = SA1111_DEVID_PS2, | 359 | .devid = SA1111_DEVID_PS2, |
335 | .probe = ps2_probe, | 360 | .probe = ps2_probe, |
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 502821997707..cbc3b7867910 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c | |||
@@ -23,106 +23,6 @@ | |||
23 | #include <asm/sizes.h> | 23 | #include <asm/sizes.h> |
24 | #include <asm/mach/flash.h> | 24 | #include <asm/mach/flash.h> |
25 | 25 | ||
26 | #if 0 | ||
27 | /* | ||
28 | * This is here for documentation purposes only - until these people | ||
29 | * submit their machine types. It will be gone January 2005. | ||
30 | */ | ||
31 | static struct mtd_partition consus_partitions[] = { | ||
32 | { | ||
33 | .name = "Consus boot firmware", | ||
34 | .offset = 0, | ||
35 | .size = 0x00040000, | ||
36 | .mask_flags = MTD_WRITABLE, /* force read-only */ | ||
37 | }, { | ||
38 | .name = "Consus kernel", | ||
39 | .offset = 0x00040000, | ||
40 | .size = 0x00100000, | ||
41 | .mask_flags = 0, | ||
42 | }, { | ||
43 | .name = "Consus disk", | ||
44 | .offset = 0x00140000, | ||
45 | /* The rest (up to 16M) for jffs. We could put 0 and | ||
46 | make it find the size automatically, but right now | ||
47 | i have 32 megs. jffs will use all 32 megs if given | ||
48 | the chance, and this leads to horrible problems | ||
49 | when you try to re-flash the image because blob | ||
50 | won't erase the whole partition. */ | ||
51 | .size = 0x01000000 - 0x00140000, | ||
52 | .mask_flags = 0, | ||
53 | }, { | ||
54 | /* this disk is a secondary disk, which can be used as | ||
55 | needed, for simplicity, make it the size of the other | ||
56 | consus partition, although realistically it could be | ||
57 | the remainder of the disk (depending on the file | ||
58 | system used) */ | ||
59 | .name = "Consus disk2", | ||
60 | .offset = 0x01000000, | ||
61 | .size = 0x01000000 - 0x00140000, | ||
62 | .mask_flags = 0, | ||
63 | } | ||
64 | }; | ||
65 | |||
66 | /* Frodo has 2 x 16M 28F128J3A flash chips in bank 0: */ | ||
67 | static struct mtd_partition frodo_partitions[] = | ||
68 | { | ||
69 | { | ||
70 | .name = "bootloader", | ||
71 | .size = 0x00040000, | ||
72 | .offset = 0x00000000, | ||
73 | .mask_flags = MTD_WRITEABLE | ||
74 | }, { | ||
75 | .name = "bootloader params", | ||
76 | .size = 0x00040000, | ||
77 | .offset = MTDPART_OFS_APPEND, | ||
78 | .mask_flags = MTD_WRITEABLE | ||
79 | }, { | ||
80 | .name = "kernel", | ||
81 | .size = 0x00100000, | ||
82 | .offset = MTDPART_OFS_APPEND, | ||
83 | .mask_flags = MTD_WRITEABLE | ||
84 | }, { | ||
85 | .name = "ramdisk", | ||
86 | .size = 0x00400000, | ||
87 | .offset = MTDPART_OFS_APPEND, | ||
88 | .mask_flags = MTD_WRITEABLE | ||
89 | }, { | ||
90 | .name = "file system", | ||
91 | .size = MTDPART_SIZ_FULL, | ||
92 | .offset = MTDPART_OFS_APPEND | ||
93 | } | ||
94 | }; | ||
95 | |||
96 | static struct mtd_partition jornada56x_partitions[] = { | ||
97 | { | ||
98 | .name = "bootldr", | ||
99 | .size = 0x00040000, | ||
100 | .offset = 0, | ||
101 | .mask_flags = MTD_WRITEABLE, | ||
102 | }, { | ||
103 | .name = "rootfs", | ||
104 | .size = MTDPART_SIZ_FULL, | ||
105 | .offset = MTDPART_OFS_APPEND, | ||
106 | } | ||
107 | }; | ||
108 | |||
109 | static void jornada56x_set_vpp(int vpp) | ||
110 | { | ||
111 | if (vpp) | ||
112 | GPSR = GPIO_GPIO26; | ||
113 | else | ||
114 | GPCR = GPIO_GPIO26; | ||
115 | GPDR |= GPIO_GPIO26; | ||
116 | } | ||
117 | |||
118 | /* | ||
119 | * Machine Phys Size set_vpp | ||
120 | * Consus : SA1100_CS0_PHYS SZ_32M | ||
121 | * Frodo : SA1100_CS0_PHYS SZ_32M | ||
122 | * Jornada56x: SA1100_CS0_PHYS SZ_32M jornada56x_set_vpp | ||
123 | */ | ||
124 | #endif | ||
125 | |||
126 | struct sa_subdev_info { | 26 | struct sa_subdev_info { |
127 | char name[16]; | 27 | char name[16]; |
128 | struct map_info map; | 28 | struct map_info map; |
@@ -373,21 +273,9 @@ static int __exit sa1100_mtd_remove(struct platform_device *pdev) | |||
373 | return 0; | 273 | return 0; |
374 | } | 274 | } |
375 | 275 | ||
376 | #ifdef CONFIG_PM | ||
377 | static void sa1100_mtd_shutdown(struct platform_device *dev) | ||
378 | { | ||
379 | struct sa_info *info = platform_get_drvdata(dev); | ||
380 | if (info && mtd_suspend(info->mtd) == 0) | ||
381 | mtd_resume(info->mtd); | ||
382 | } | ||
383 | #else | ||
384 | #define sa1100_mtd_shutdown NULL | ||
385 | #endif | ||
386 | |||
387 | static struct platform_driver sa1100_mtd_driver = { | 276 | static struct platform_driver sa1100_mtd_driver = { |
388 | .probe = sa1100_mtd_probe, | 277 | .probe = sa1100_mtd_probe, |
389 | .remove = __exit_p(sa1100_mtd_remove), | 278 | .remove = __exit_p(sa1100_mtd_remove), |
390 | .shutdown = sa1100_mtd_shutdown, | ||
391 | .driver = { | 279 | .driver = { |
392 | .name = "sa1100-mtd", | 280 | .name = "sa1100-mtd", |
393 | .owner = THIS_MODULE, | 281 | .owner = THIS_MODULE, |
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 64ad3ed74495..0dba0501b712 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c | |||
@@ -2281,7 +2281,7 @@ static int __devinit smc_drv_probe(struct platform_device *pdev) | |||
2281 | if (ret) | 2281 | if (ret) |
2282 | goto out_release_io; | 2282 | goto out_release_io; |
2283 | #if defined(CONFIG_SA1100_ASSABET) | 2283 | #if defined(CONFIG_SA1100_ASSABET) |
2284 | NCR_0 |= NCR_ENET_OSC_EN; | 2284 | neponset_ncr_set(NCR_ENET_OSC_EN); |
2285 | #endif | 2285 | #endif |
2286 | platform_set_drvdata(pdev, ndev); | 2286 | platform_set_drvdata(pdev, ndev); |
2287 | ret = smc_enable_device(pdev); | 2287 | ret = smc_enable_device(pdev); |
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index e535137eb2d0..468047866c8c 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig | |||
@@ -356,7 +356,7 @@ config VLSI_FIR | |||
356 | 356 | ||
357 | config SA1100_FIR | 357 | config SA1100_FIR |
358 | tristate "SA1100 Internal IR" | 358 | tristate "SA1100 Internal IR" |
359 | depends on ARCH_SA1100 && IRDA | 359 | depends on ARCH_SA1100 && IRDA && DMA_SA11X0 |
360 | 360 | ||
361 | config VIA_FIR | 361 | config VIA_FIR |
362 | tristate "VIA VT8231/VT1211 SIR/MIR/FIR" | 362 | tristate "VIA VT8231/VT1211 SIR/MIR/FIR" |
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index da2705061a60..a0d1913a58d3 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c | |||
@@ -15,7 +15,7 @@ | |||
15 | * This driver takes one kernel command line parameter, sa1100ir=, with | 15 | * This driver takes one kernel command line parameter, sa1100ir=, with |
16 | * the following options: | 16 | * the following options: |
17 | * max_rate:baudrate - set the maximum baud rate | 17 | * max_rate:baudrate - set the maximum baud rate |
18 | * power_leve:level - set the transmitter power level | 18 | * power_level:level - set the transmitter power level |
19 | * tx_lpm:0|1 - set transmit low power mode | 19 | * tx_lpm:0|1 - set transmit low power mode |
20 | */ | 20 | */ |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
@@ -30,13 +30,13 @@ | |||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
33 | #include <linux/dmaengine.h> | ||
34 | #include <linux/sa11x0-dma.h> | ||
33 | 35 | ||
34 | #include <net/irda/irda.h> | 36 | #include <net/irda/irda.h> |
35 | #include <net/irda/wrapper.h> | 37 | #include <net/irda/wrapper.h> |
36 | #include <net/irda/irda_device.h> | 38 | #include <net/irda/irda_device.h> |
37 | 39 | ||
38 | #include <asm/irq.h> | ||
39 | #include <mach/dma.h> | ||
40 | #include <mach/hardware.h> | 40 | #include <mach/hardware.h> |
41 | #include <asm/mach/irda.h> | 41 | #include <asm/mach/irda.h> |
42 | 42 | ||
@@ -44,8 +44,15 @@ static int power_level = 3; | |||
44 | static int tx_lpm; | 44 | static int tx_lpm; |
45 | static int max_rate = 4000000; | 45 | static int max_rate = 4000000; |
46 | 46 | ||
47 | struct sa1100_buf { | ||
48 | struct device *dev; | ||
49 | struct sk_buff *skb; | ||
50 | struct scatterlist sg; | ||
51 | struct dma_chan *chan; | ||
52 | dma_cookie_t cookie; | ||
53 | }; | ||
54 | |||
47 | struct sa1100_irda { | 55 | struct sa1100_irda { |
48 | unsigned char hscr0; | ||
49 | unsigned char utcr4; | 56 | unsigned char utcr4; |
50 | unsigned char power; | 57 | unsigned char power; |
51 | unsigned char open; | 58 | unsigned char open; |
@@ -53,12 +60,8 @@ struct sa1100_irda { | |||
53 | int speed; | 60 | int speed; |
54 | int newspeed; | 61 | int newspeed; |
55 | 62 | ||
56 | struct sk_buff *txskb; | 63 | struct sa1100_buf dma_rx; |
57 | struct sk_buff *rxskb; | 64 | struct sa1100_buf dma_tx; |
58 | dma_addr_t txbuf_dma; | ||
59 | dma_addr_t rxbuf_dma; | ||
60 | dma_regs_t *txdma; | ||
61 | dma_regs_t *rxdma; | ||
62 | 65 | ||
63 | struct device *dev; | 66 | struct device *dev; |
64 | struct irda_platform_data *pdata; | 67 | struct irda_platform_data *pdata; |
@@ -67,23 +70,103 @@ struct sa1100_irda { | |||
67 | 70 | ||
68 | iobuff_t tx_buff; | 71 | iobuff_t tx_buff; |
69 | iobuff_t rx_buff; | 72 | iobuff_t rx_buff; |
73 | |||
74 | int (*tx_start)(struct sk_buff *, struct net_device *, struct sa1100_irda *); | ||
75 | irqreturn_t (*irq)(struct net_device *, struct sa1100_irda *); | ||
70 | }; | 76 | }; |
71 | 77 | ||
78 | static int sa1100_irda_set_speed(struct sa1100_irda *, int); | ||
79 | |||
72 | #define IS_FIR(si) ((si)->speed >= 4000000) | 80 | #define IS_FIR(si) ((si)->speed >= 4000000) |
73 | 81 | ||
74 | #define HPSIR_MAX_RXLEN 2047 | 82 | #define HPSIR_MAX_RXLEN 2047 |
75 | 83 | ||
84 | static struct dma_slave_config sa1100_irda_sir_tx = { | ||
85 | .direction = DMA_TO_DEVICE, | ||
86 | .dst_addr = __PREG(Ser2UTDR), | ||
87 | .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, | ||
88 | .dst_maxburst = 4, | ||
89 | }; | ||
90 | |||
91 | static struct dma_slave_config sa1100_irda_fir_rx = { | ||
92 | .direction = DMA_FROM_DEVICE, | ||
93 | .src_addr = __PREG(Ser2HSDR), | ||
94 | .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, | ||
95 | .src_maxburst = 8, | ||
96 | }; | ||
97 | |||
98 | static struct dma_slave_config sa1100_irda_fir_tx = { | ||
99 | .direction = DMA_TO_DEVICE, | ||
100 | .dst_addr = __PREG(Ser2HSDR), | ||
101 | .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, | ||
102 | .dst_maxburst = 8, | ||
103 | }; | ||
104 | |||
105 | static unsigned sa1100_irda_dma_xferred(struct sa1100_buf *buf) | ||
106 | { | ||
107 | struct dma_chan *chan = buf->chan; | ||
108 | struct dma_tx_state state; | ||
109 | enum dma_status status; | ||
110 | |||
111 | status = chan->device->device_tx_status(chan, buf->cookie, &state); | ||
112 | if (status != DMA_PAUSED) | ||
113 | return 0; | ||
114 | |||
115 | return sg_dma_len(&buf->sg) - state.residue; | ||
116 | } | ||
117 | |||
118 | static int sa1100_irda_dma_request(struct device *dev, struct sa1100_buf *buf, | ||
119 | const char *name, struct dma_slave_config *cfg) | ||
120 | { | ||
121 | dma_cap_mask_t m; | ||
122 | int ret; | ||
123 | |||
124 | dma_cap_zero(m); | ||
125 | dma_cap_set(DMA_SLAVE, m); | ||
126 | |||
127 | buf->chan = dma_request_channel(m, sa11x0_dma_filter_fn, (void *)name); | ||
128 | if (!buf->chan) { | ||
129 | dev_err(dev, "unable to request DMA channel for %s\n", | ||
130 | name); | ||
131 | return -ENOENT; | ||
132 | } | ||
133 | |||
134 | ret = dmaengine_slave_config(buf->chan, cfg); | ||
135 | if (ret) | ||
136 | dev_warn(dev, "DMA slave_config for %s returned %d\n", | ||
137 | name, ret); | ||
138 | |||
139 | buf->dev = buf->chan->device->dev; | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static void sa1100_irda_dma_start(struct sa1100_buf *buf, | ||
145 | enum dma_transfer_direction dir, dma_async_tx_callback cb, void *cb_p) | ||
146 | { | ||
147 | struct dma_async_tx_descriptor *desc; | ||
148 | struct dma_chan *chan = buf->chan; | ||
149 | |||
150 | desc = chan->device->device_prep_slave_sg(chan, &buf->sg, 1, dir, | ||
151 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
152 | if (desc) { | ||
153 | desc->callback = cb; | ||
154 | desc->callback_param = cb_p; | ||
155 | buf->cookie = dmaengine_submit(desc); | ||
156 | dma_async_issue_pending(chan); | ||
157 | } | ||
158 | } | ||
159 | |||
76 | /* | 160 | /* |
77 | * Allocate and map the receive buffer, unless it is already allocated. | 161 | * Allocate and map the receive buffer, unless it is already allocated. |
78 | */ | 162 | */ |
79 | static int sa1100_irda_rx_alloc(struct sa1100_irda *si) | 163 | static int sa1100_irda_rx_alloc(struct sa1100_irda *si) |
80 | { | 164 | { |
81 | if (si->rxskb) | 165 | if (si->dma_rx.skb) |
82 | return 0; | 166 | return 0; |
83 | 167 | ||
84 | si->rxskb = alloc_skb(HPSIR_MAX_RXLEN + 1, GFP_ATOMIC); | 168 | si->dma_rx.skb = alloc_skb(HPSIR_MAX_RXLEN + 1, GFP_ATOMIC); |
85 | 169 | if (!si->dma_rx.skb) { | |
86 | if (!si->rxskb) { | ||
87 | printk(KERN_ERR "sa1100_ir: out of memory for RX SKB\n"); | 170 | printk(KERN_ERR "sa1100_ir: out of memory for RX SKB\n"); |
88 | return -ENOMEM; | 171 | return -ENOMEM; |
89 | } | 172 | } |
@@ -92,11 +175,14 @@ static int sa1100_irda_rx_alloc(struct sa1100_irda *si) | |||
92 | * Align any IP headers that may be contained | 175 | * Align any IP headers that may be contained |
93 | * within the frame. | 176 | * within the frame. |
94 | */ | 177 | */ |
95 | skb_reserve(si->rxskb, 1); | 178 | skb_reserve(si->dma_rx.skb, 1); |
179 | |||
180 | sg_set_buf(&si->dma_rx.sg, si->dma_rx.skb->data, HPSIR_MAX_RXLEN); | ||
181 | if (dma_map_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, DMA_FROM_DEVICE) == 0) { | ||
182 | dev_kfree_skb_any(si->dma_rx.skb); | ||
183 | return -ENOMEM; | ||
184 | } | ||
96 | 185 | ||
97 | si->rxbuf_dma = dma_map_single(si->dev, si->rxskb->data, | ||
98 | HPSIR_MAX_RXLEN, | ||
99 | DMA_FROM_DEVICE); | ||
100 | return 0; | 186 | return 0; |
101 | } | 187 | } |
102 | 188 | ||
@@ -106,7 +192,7 @@ static int sa1100_irda_rx_alloc(struct sa1100_irda *si) | |||
106 | */ | 192 | */ |
107 | static void sa1100_irda_rx_dma_start(struct sa1100_irda *si) | 193 | static void sa1100_irda_rx_dma_start(struct sa1100_irda *si) |
108 | { | 194 | { |
109 | if (!si->rxskb) { | 195 | if (!si->dma_rx.skb) { |
110 | printk(KERN_ERR "sa1100_ir: rx buffer went missing\n"); | 196 | printk(KERN_ERR "sa1100_ir: rx buffer went missing\n"); |
111 | return; | 197 | return; |
112 | } | 198 | } |
@@ -114,254 +200,87 @@ static void sa1100_irda_rx_dma_start(struct sa1100_irda *si) | |||
114 | /* | 200 | /* |
115 | * First empty receive FIFO | 201 | * First empty receive FIFO |
116 | */ | 202 | */ |
117 | Ser2HSCR0 = si->hscr0 | HSCR0_HSSP; | 203 | Ser2HSCR0 = HSCR0_HSSP; |
118 | 204 | ||
119 | /* | 205 | /* |
120 | * Enable the DMA, receiver and receive interrupt. | 206 | * Enable the DMA, receiver and receive interrupt. |
121 | */ | 207 | */ |
122 | sa1100_clear_dma(si->rxdma); | 208 | dmaengine_terminate_all(si->dma_rx.chan); |
123 | sa1100_start_dma(si->rxdma, si->rxbuf_dma, HPSIR_MAX_RXLEN); | 209 | sa1100_irda_dma_start(&si->dma_rx, DMA_DEV_TO_MEM, NULL, NULL); |
124 | Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_RXE; | 210 | |
211 | Ser2HSCR0 = HSCR0_HSSP | HSCR0_RXE; | ||
125 | } | 212 | } |
126 | 213 | ||
127 | /* | 214 | static void sa1100_irda_check_speed(struct sa1100_irda *si) |
128 | * Set the IrDA communications speed. | ||
129 | */ | ||
130 | static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed) | ||
131 | { | 215 | { |
132 | unsigned long flags; | 216 | if (si->newspeed) { |
133 | int brd, ret = -EINVAL; | 217 | sa1100_irda_set_speed(si, si->newspeed); |
134 | 218 | si->newspeed = 0; | |
135 | switch (speed) { | ||
136 | case 9600: case 19200: case 38400: | ||
137 | case 57600: case 115200: | ||
138 | brd = 3686400 / (16 * speed) - 1; | ||
139 | |||
140 | /* | ||
141 | * Stop the receive DMA. | ||
142 | */ | ||
143 | if (IS_FIR(si)) | ||
144 | sa1100_stop_dma(si->rxdma); | ||
145 | |||
146 | local_irq_save(flags); | ||
147 | |||
148 | Ser2UTCR3 = 0; | ||
149 | Ser2HSCR0 = HSCR0_UART; | ||
150 | |||
151 | Ser2UTCR1 = brd >> 8; | ||
152 | Ser2UTCR2 = brd; | ||
153 | |||
154 | /* | ||
155 | * Clear status register | ||
156 | */ | ||
157 | Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; | ||
158 | Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE; | ||
159 | |||
160 | if (si->pdata->set_speed) | ||
161 | si->pdata->set_speed(si->dev, speed); | ||
162 | |||
163 | si->speed = speed; | ||
164 | |||
165 | local_irq_restore(flags); | ||
166 | ret = 0; | ||
167 | break; | ||
168 | |||
169 | case 4000000: | ||
170 | local_irq_save(flags); | ||
171 | |||
172 | si->hscr0 = 0; | ||
173 | |||
174 | Ser2HSSR0 = 0xff; | ||
175 | Ser2HSCR0 = si->hscr0 | HSCR0_HSSP; | ||
176 | Ser2UTCR3 = 0; | ||
177 | |||
178 | si->speed = speed; | ||
179 | |||
180 | if (si->pdata->set_speed) | ||
181 | si->pdata->set_speed(si->dev, speed); | ||
182 | |||
183 | sa1100_irda_rx_alloc(si); | ||
184 | sa1100_irda_rx_dma_start(si); | ||
185 | |||
186 | local_irq_restore(flags); | ||
187 | |||
188 | break; | ||
189 | |||
190 | default: | ||
191 | break; | ||
192 | } | 219 | } |
193 | |||
194 | return ret; | ||
195 | } | 220 | } |
196 | 221 | ||
197 | /* | 222 | /* |
198 | * Control the power state of the IrDA transmitter. | 223 | * HP-SIR format support. |
199 | * State: | ||
200 | * 0 - off | ||
201 | * 1 - short range, lowest power | ||
202 | * 2 - medium range, medium power | ||
203 | * 3 - maximum range, high power | ||
204 | * | ||
205 | * Currently, only assabet is known to support this. | ||
206 | */ | 224 | */ |
207 | static int | 225 | static void sa1100_irda_sirtxdma_irq(void *id) |
208 | __sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state) | ||
209 | { | 226 | { |
210 | int ret = 0; | 227 | struct net_device *dev = id; |
211 | if (si->pdata->set_power) | 228 | struct sa1100_irda *si = netdev_priv(dev); |
212 | ret = si->pdata->set_power(si->dev, state); | ||
213 | return ret; | ||
214 | } | ||
215 | |||
216 | static inline int | ||
217 | sa1100_set_power(struct sa1100_irda *si, unsigned int state) | ||
218 | { | ||
219 | int ret; | ||
220 | |||
221 | ret = __sa1100_irda_set_power(si, state); | ||
222 | if (ret == 0) | ||
223 | si->power = state; | ||
224 | 229 | ||
225 | return ret; | 230 | dma_unmap_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, DMA_TO_DEVICE); |
226 | } | 231 | dev_kfree_skb(si->dma_tx.skb); |
232 | si->dma_tx.skb = NULL; | ||
227 | 233 | ||
228 | static int sa1100_irda_startup(struct sa1100_irda *si) | 234 | dev->stats.tx_packets++; |
229 | { | 235 | dev->stats.tx_bytes += sg_dma_len(&si->dma_tx.sg); |
230 | int ret; | ||
231 | 236 | ||
232 | /* | 237 | /* We need to ensure that the transmitter has finished. */ |
233 | * Ensure that the ports for this device are setup correctly. | 238 | do |
234 | */ | 239 | rmb(); |
235 | if (si->pdata->startup) { | 240 | while (Ser2UTSR1 & UTSR1_TBY); |
236 | ret = si->pdata->startup(si->dev); | ||
237 | if (ret) | ||
238 | return ret; | ||
239 | } | ||
240 | |||
241 | /* | ||
242 | * Configure PPC for IRDA - we want to drive TXD2 low. | ||
243 | * We also want to drive this pin low during sleep. | ||
244 | */ | ||
245 | PPSR &= ~PPC_TXD2; | ||
246 | PSDR &= ~PPC_TXD2; | ||
247 | PPDR |= PPC_TXD2; | ||
248 | |||
249 | /* | ||
250 | * Enable HP-SIR modulation, and ensure that the port is disabled. | ||
251 | */ | ||
252 | Ser2UTCR3 = 0; | ||
253 | Ser2HSCR0 = HSCR0_UART; | ||
254 | Ser2UTCR4 = si->utcr4; | ||
255 | Ser2UTCR0 = UTCR0_8BitData; | ||
256 | Ser2HSCR2 = HSCR2_TrDataH | HSCR2_RcDataL; | ||
257 | 241 | ||
258 | /* | 242 | /* |
259 | * Clear status register | 243 | * Ok, we've finished transmitting. Now enable the receiver. |
244 | * Sometimes we get a receive IRQ immediately after a transmit... | ||
260 | */ | 245 | */ |
261 | Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; | 246 | Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; |
247 | Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE; | ||
262 | 248 | ||
263 | ret = sa1100_irda_set_speed(si, si->speed = 9600); | 249 | sa1100_irda_check_speed(si); |
264 | if (ret) { | ||
265 | Ser2UTCR3 = 0; | ||
266 | Ser2HSCR0 = 0; | ||
267 | |||
268 | if (si->pdata->shutdown) | ||
269 | si->pdata->shutdown(si->dev); | ||
270 | } | ||
271 | |||
272 | return ret; | ||
273 | } | ||
274 | |||
275 | static void sa1100_irda_shutdown(struct sa1100_irda *si) | ||
276 | { | ||
277 | /* | ||
278 | * Stop all DMA activity. | ||
279 | */ | ||
280 | sa1100_stop_dma(si->rxdma); | ||
281 | sa1100_stop_dma(si->txdma); | ||
282 | |||
283 | /* Disable the port. */ | ||
284 | Ser2UTCR3 = 0; | ||
285 | Ser2HSCR0 = 0; | ||
286 | 250 | ||
287 | if (si->pdata->shutdown) | 251 | /* I'm hungry! */ |
288 | si->pdata->shutdown(si->dev); | 252 | netif_wake_queue(dev); |
289 | } | 253 | } |
290 | 254 | ||
291 | #ifdef CONFIG_PM | 255 | static int sa1100_irda_sir_tx_start(struct sk_buff *skb, struct net_device *dev, |
292 | /* | 256 | struct sa1100_irda *si) |
293 | * Suspend the IrDA interface. | ||
294 | */ | ||
295 | static int sa1100_irda_suspend(struct platform_device *pdev, pm_message_t state) | ||
296 | { | 257 | { |
297 | struct net_device *dev = platform_get_drvdata(pdev); | 258 | si->tx_buff.data = si->tx_buff.head; |
298 | struct sa1100_irda *si; | 259 | si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, |
299 | 260 | si->tx_buff.truesize); | |
300 | if (!dev) | 261 | |
301 | return 0; | 262 | si->dma_tx.skb = skb; |
302 | 263 | sg_set_buf(&si->dma_tx.sg, si->tx_buff.data, si->tx_buff.len); | |
303 | si = netdev_priv(dev); | 264 | if (dma_map_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, DMA_TO_DEVICE) == 0) { |
304 | if (si->open) { | 265 | si->dma_tx.skb = NULL; |
305 | /* | 266 | netif_wake_queue(dev); |
306 | * Stop the transmit queue | 267 | dev->stats.tx_dropped++; |
307 | */ | 268 | return NETDEV_TX_OK; |
308 | netif_device_detach(dev); | ||
309 | disable_irq(dev->irq); | ||
310 | sa1100_irda_shutdown(si); | ||
311 | __sa1100_irda_set_power(si, 0); | ||
312 | } | 269 | } |
313 | 270 | ||
314 | return 0; | 271 | sa1100_irda_dma_start(&si->dma_tx, DMA_MEM_TO_DEV, sa1100_irda_sirtxdma_irq, dev); |
315 | } | ||
316 | |||
317 | /* | ||
318 | * Resume the IrDA interface. | ||
319 | */ | ||
320 | static int sa1100_irda_resume(struct platform_device *pdev) | ||
321 | { | ||
322 | struct net_device *dev = platform_get_drvdata(pdev); | ||
323 | struct sa1100_irda *si; | ||
324 | |||
325 | if (!dev) | ||
326 | return 0; | ||
327 | 272 | ||
328 | si = netdev_priv(dev); | 273 | /* |
329 | if (si->open) { | 274 | * The mean turn-around time is enforced by XBOF padding, |
330 | /* | 275 | * so we don't have to do anything special here. |
331 | * If we missed a speed change, initialise at the new speed | 276 | */ |
332 | * directly. It is debatable whether this is actually | 277 | Ser2UTCR3 = UTCR3_TXE; |
333 | * required, but in the interests of continuing from where | ||
334 | * we left off it is desirable. The converse argument is | ||
335 | * that we should re-negotiate at 9600 baud again. | ||
336 | */ | ||
337 | if (si->newspeed) { | ||
338 | si->speed = si->newspeed; | ||
339 | si->newspeed = 0; | ||
340 | } | ||
341 | |||
342 | sa1100_irda_startup(si); | ||
343 | __sa1100_irda_set_power(si, si->power); | ||
344 | enable_irq(dev->irq); | ||
345 | |||
346 | /* | ||
347 | * This automatically wakes up the queue | ||
348 | */ | ||
349 | netif_device_attach(dev); | ||
350 | } | ||
351 | 278 | ||
352 | return 0; | 279 | return NETDEV_TX_OK; |
353 | } | 280 | } |
354 | #else | ||
355 | #define sa1100_irda_suspend NULL | ||
356 | #define sa1100_irda_resume NULL | ||
357 | #endif | ||
358 | 281 | ||
359 | /* | 282 | static irqreturn_t sa1100_irda_sir_irq(struct net_device *dev, struct sa1100_irda *si) |
360 | * HP-SIR format interrupt service routines. | ||
361 | */ | ||
362 | static void sa1100_irda_hpsir_irq(struct net_device *dev) | ||
363 | { | 283 | { |
364 | struct sa1100_irda *si = netdev_priv(dev); | ||
365 | int status; | 284 | int status; |
366 | 285 | ||
367 | status = Ser2UTSR0; | 286 | status = Ser2UTSR0; |
@@ -414,51 +333,96 @@ static void sa1100_irda_hpsir_irq(struct net_device *dev) | |||
414 | 333 | ||
415 | } | 334 | } |
416 | 335 | ||
417 | if (status & UTSR0_TFS && si->tx_buff.len) { | 336 | return IRQ_HANDLED; |
418 | /* | 337 | } |
419 | * Transmitter FIFO is not full | ||
420 | */ | ||
421 | do { | ||
422 | Ser2UTDR = *si->tx_buff.data++; | ||
423 | si->tx_buff.len -= 1; | ||
424 | } while (Ser2UTSR1 & UTSR1_TNF && si->tx_buff.len); | ||
425 | 338 | ||
426 | if (si->tx_buff.len == 0) { | 339 | /* |
427 | dev->stats.tx_packets++; | 340 | * FIR format support. |
428 | dev->stats.tx_bytes += si->tx_buff.data - | 341 | */ |
429 | si->tx_buff.head; | 342 | static void sa1100_irda_firtxdma_irq(void *id) |
343 | { | ||
344 | struct net_device *dev = id; | ||
345 | struct sa1100_irda *si = netdev_priv(dev); | ||
346 | struct sk_buff *skb; | ||
430 | 347 | ||
431 | /* | 348 | /* |
432 | * We need to ensure that the transmitter has | 349 | * Wait for the transmission to complete. Unfortunately, |
433 | * finished. | 350 | * the hardware doesn't give us an interrupt to indicate |
434 | */ | 351 | * "end of frame". |
435 | do | 352 | */ |
436 | rmb(); | 353 | do |
437 | while (Ser2UTSR1 & UTSR1_TBY); | 354 | rmb(); |
355 | while (!(Ser2HSSR0 & HSSR0_TUR) || Ser2HSSR1 & HSSR1_TBY); | ||
438 | 356 | ||
439 | /* | 357 | /* |
440 | * Ok, we've finished transmitting. Now enable | 358 | * Clear the transmit underrun bit. |
441 | * the receiver. Sometimes we get a receive IRQ | 359 | */ |
442 | * immediately after a transmit... | 360 | Ser2HSSR0 = HSSR0_TUR; |
443 | */ | ||
444 | Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; | ||
445 | Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE; | ||
446 | 361 | ||
447 | if (si->newspeed) { | 362 | /* |
448 | sa1100_irda_set_speed(si, si->newspeed); | 363 | * Do we need to change speed? Note that we're lazy |
449 | si->newspeed = 0; | 364 | * here - we don't free the old dma_rx.skb. We don't need |
450 | } | 365 | * to allocate a buffer either. |
366 | */ | ||
367 | sa1100_irda_check_speed(si); | ||
451 | 368 | ||
452 | /* I'm hungry! */ | 369 | /* |
453 | netif_wake_queue(dev); | 370 | * Start reception. This disables the transmitter for |
454 | } | 371 | * us. This will be using the existing RX buffer. |
372 | */ | ||
373 | sa1100_irda_rx_dma_start(si); | ||
374 | |||
375 | /* Account and free the packet. */ | ||
376 | skb = si->dma_tx.skb; | ||
377 | if (skb) { | ||
378 | dma_unmap_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, | ||
379 | DMA_TO_DEVICE); | ||
380 | dev->stats.tx_packets ++; | ||
381 | dev->stats.tx_bytes += skb->len; | ||
382 | dev_kfree_skb_irq(skb); | ||
383 | si->dma_tx.skb = NULL; | ||
455 | } | 384 | } |
385 | |||
386 | /* | ||
387 | * Make sure that the TX queue is available for sending | ||
388 | * (for retries). TX has priority over RX at all times. | ||
389 | */ | ||
390 | netif_wake_queue(dev); | ||
391 | } | ||
392 | |||
393 | static int sa1100_irda_fir_tx_start(struct sk_buff *skb, struct net_device *dev, | ||
394 | struct sa1100_irda *si) | ||
395 | { | ||
396 | int mtt = irda_get_mtt(skb); | ||
397 | |||
398 | si->dma_tx.skb = skb; | ||
399 | sg_set_buf(&si->dma_tx.sg, skb->data, skb->len); | ||
400 | if (dma_map_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, DMA_TO_DEVICE) == 0) { | ||
401 | si->dma_tx.skb = NULL; | ||
402 | netif_wake_queue(dev); | ||
403 | dev->stats.tx_dropped++; | ||
404 | dev_kfree_skb(skb); | ||
405 | return NETDEV_TX_OK; | ||
406 | } | ||
407 | |||
408 | sa1100_irda_dma_start(&si->dma_tx, DMA_MEM_TO_DEV, sa1100_irda_firtxdma_irq, dev); | ||
409 | |||
410 | /* | ||
411 | * If we have a mean turn-around time, impose the specified | ||
412 | * specified delay. We could shorten this by timing from | ||
413 | * the point we received the packet. | ||
414 | */ | ||
415 | if (mtt) | ||
416 | udelay(mtt); | ||
417 | |||
418 | Ser2HSCR0 = HSCR0_HSSP | HSCR0_TXE; | ||
419 | |||
420 | return NETDEV_TX_OK; | ||
456 | } | 421 | } |
457 | 422 | ||
458 | static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev) | 423 | static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev) |
459 | { | 424 | { |
460 | struct sk_buff *skb = si->rxskb; | 425 | struct sk_buff *skb = si->dma_rx.skb; |
461 | dma_addr_t dma_addr; | ||
462 | unsigned int len, stat, data; | 426 | unsigned int len, stat, data; |
463 | 427 | ||
464 | if (!skb) { | 428 | if (!skb) { |
@@ -469,11 +433,10 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev | |||
469 | /* | 433 | /* |
470 | * Get the current data position. | 434 | * Get the current data position. |
471 | */ | 435 | */ |
472 | dma_addr = sa1100_get_dma_pos(si->rxdma); | 436 | len = sa1100_irda_dma_xferred(&si->dma_rx); |
473 | len = dma_addr - si->rxbuf_dma; | ||
474 | if (len > HPSIR_MAX_RXLEN) | 437 | if (len > HPSIR_MAX_RXLEN) |
475 | len = HPSIR_MAX_RXLEN; | 438 | len = HPSIR_MAX_RXLEN; |
476 | dma_unmap_single(si->dev, si->rxbuf_dma, len, DMA_FROM_DEVICE); | 439 | dma_unmap_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, DMA_FROM_DEVICE); |
477 | 440 | ||
478 | do { | 441 | do { |
479 | /* | 442 | /* |
@@ -501,7 +464,7 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev | |||
501 | } while (Ser2HSSR0 & HSSR0_EIF); | 464 | } while (Ser2HSSR0 & HSSR0_EIF); |
502 | 465 | ||
503 | if (stat & HSSR1_EOF) { | 466 | if (stat & HSSR1_EOF) { |
504 | si->rxskb = NULL; | 467 | si->dma_rx.skb = NULL; |
505 | 468 | ||
506 | skb_put(skb, len); | 469 | skb_put(skb, len); |
507 | skb->dev = dev; | 470 | skb->dev = dev; |
@@ -518,28 +481,23 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev | |||
518 | netif_rx(skb); | 481 | netif_rx(skb); |
519 | } else { | 482 | } else { |
520 | /* | 483 | /* |
521 | * Remap the buffer. | 484 | * Remap the buffer - it was previously mapped, and we |
485 | * hope that this succeeds. | ||
522 | */ | 486 | */ |
523 | si->rxbuf_dma = dma_map_single(si->dev, si->rxskb->data, | 487 | dma_map_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, DMA_FROM_DEVICE); |
524 | HPSIR_MAX_RXLEN, | ||
525 | DMA_FROM_DEVICE); | ||
526 | } | 488 | } |
527 | } | 489 | } |
528 | 490 | ||
529 | /* | 491 | /* |
530 | * FIR format interrupt service routine. We only have to | 492 | * We only have to handle RX events here; transmit events go via the TX |
531 | * handle RX events; transmit events go via the TX DMA handler. | 493 | * DMA handler. We disable RX, process, and the restart RX. |
532 | * | ||
533 | * No matter what, we disable RX, process, and the restart RX. | ||
534 | */ | 494 | */ |
535 | static void sa1100_irda_fir_irq(struct net_device *dev) | 495 | static irqreturn_t sa1100_irda_fir_irq(struct net_device *dev, struct sa1100_irda *si) |
536 | { | 496 | { |
537 | struct sa1100_irda *si = netdev_priv(dev); | ||
538 | |||
539 | /* | 497 | /* |
540 | * Stop RX DMA | 498 | * Stop RX DMA |
541 | */ | 499 | */ |
542 | sa1100_stop_dma(si->rxdma); | 500 | dmaengine_pause(si->dma_rx.chan); |
543 | 501 | ||
544 | /* | 502 | /* |
545 | * Framing error - we throw away the packet completely. | 503 | * Framing error - we throw away the packet completely. |
@@ -555,7 +513,7 @@ static void sa1100_irda_fir_irq(struct net_device *dev) | |||
555 | /* | 513 | /* |
556 | * Clear out the DMA... | 514 | * Clear out the DMA... |
557 | */ | 515 | */ |
558 | Ser2HSCR0 = si->hscr0 | HSCR0_HSSP; | 516 | Ser2HSCR0 = HSCR0_HSSP; |
559 | 517 | ||
560 | /* | 518 | /* |
561 | * Clear selected status bits now, so we | 519 | * Clear selected status bits now, so we |
@@ -577,74 +535,124 @@ static void sa1100_irda_fir_irq(struct net_device *dev) | |||
577 | * No matter what happens, we must restart reception. | 535 | * No matter what happens, we must restart reception. |
578 | */ | 536 | */ |
579 | sa1100_irda_rx_dma_start(si); | 537 | sa1100_irda_rx_dma_start(si); |
580 | } | ||
581 | 538 | ||
582 | static irqreturn_t sa1100_irda_irq(int irq, void *dev_id) | ||
583 | { | ||
584 | struct net_device *dev = dev_id; | ||
585 | if (IS_FIR(((struct sa1100_irda *)netdev_priv(dev)))) | ||
586 | sa1100_irda_fir_irq(dev); | ||
587 | else | ||
588 | sa1100_irda_hpsir_irq(dev); | ||
589 | return IRQ_HANDLED; | 539 | return IRQ_HANDLED; |
590 | } | 540 | } |
591 | 541 | ||
592 | /* | 542 | /* |
593 | * TX DMA completion handler. | 543 | * Set the IrDA communications speed. |
594 | */ | 544 | */ |
595 | static void sa1100_irda_txdma_irq(void *id) | 545 | static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed) |
596 | { | 546 | { |
597 | struct net_device *dev = id; | 547 | unsigned long flags; |
598 | struct sa1100_irda *si = netdev_priv(dev); | 548 | int brd, ret = -EINVAL; |
599 | struct sk_buff *skb = si->txskb; | ||
600 | 549 | ||
601 | si->txskb = NULL; | 550 | switch (speed) { |
551 | case 9600: case 19200: case 38400: | ||
552 | case 57600: case 115200: | ||
553 | brd = 3686400 / (16 * speed) - 1; | ||
602 | 554 | ||
603 | /* | 555 | /* Stop the receive DMA, and configure transmit. */ |
604 | * Wait for the transmission to complete. Unfortunately, | 556 | if (IS_FIR(si)) { |
605 | * the hardware doesn't give us an interrupt to indicate | 557 | dmaengine_terminate_all(si->dma_rx.chan); |
606 | * "end of frame". | 558 | dmaengine_slave_config(si->dma_tx.chan, |
607 | */ | 559 | &sa1100_irda_sir_tx); |
608 | do | 560 | } |
609 | rmb(); | ||
610 | while (!(Ser2HSSR0 & HSSR0_TUR) || Ser2HSSR1 & HSSR1_TBY); | ||
611 | 561 | ||
612 | /* | 562 | local_irq_save(flags); |
613 | * Clear the transmit underrun bit. | ||
614 | */ | ||
615 | Ser2HSSR0 = HSSR0_TUR; | ||
616 | 563 | ||
617 | /* | 564 | Ser2UTCR3 = 0; |
618 | * Do we need to change speed? Note that we're lazy | 565 | Ser2HSCR0 = HSCR0_UART; |
619 | * here - we don't free the old rxskb. We don't need | ||
620 | * to allocate a buffer either. | ||
621 | */ | ||
622 | if (si->newspeed) { | ||
623 | sa1100_irda_set_speed(si, si->newspeed); | ||
624 | si->newspeed = 0; | ||
625 | } | ||
626 | 566 | ||
627 | /* | 567 | Ser2UTCR1 = brd >> 8; |
628 | * Start reception. This disables the transmitter for | 568 | Ser2UTCR2 = brd; |
629 | * us. This will be using the existing RX buffer. | ||
630 | */ | ||
631 | sa1100_irda_rx_dma_start(si); | ||
632 | 569 | ||
633 | /* | 570 | /* |
634 | * Account and free the packet. | 571 | * Clear status register |
635 | */ | 572 | */ |
636 | if (skb) { | 573 | Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; |
637 | dma_unmap_single(si->dev, si->txbuf_dma, skb->len, DMA_TO_DEVICE); | 574 | Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE; |
638 | dev->stats.tx_packets ++; | 575 | |
639 | dev->stats.tx_bytes += skb->len; | 576 | if (si->pdata->set_speed) |
640 | dev_kfree_skb_irq(skb); | 577 | si->pdata->set_speed(si->dev, speed); |
578 | |||
579 | si->speed = speed; | ||
580 | si->tx_start = sa1100_irda_sir_tx_start; | ||
581 | si->irq = sa1100_irda_sir_irq; | ||
582 | |||
583 | local_irq_restore(flags); | ||
584 | ret = 0; | ||
585 | break; | ||
586 | |||
587 | case 4000000: | ||
588 | if (!IS_FIR(si)) | ||
589 | dmaengine_slave_config(si->dma_tx.chan, | ||
590 | &sa1100_irda_fir_tx); | ||
591 | |||
592 | local_irq_save(flags); | ||
593 | |||
594 | Ser2HSSR0 = 0xff; | ||
595 | Ser2HSCR0 = HSCR0_HSSP; | ||
596 | Ser2UTCR3 = 0; | ||
597 | |||
598 | si->speed = speed; | ||
599 | si->tx_start = sa1100_irda_fir_tx_start; | ||
600 | si->irq = sa1100_irda_fir_irq; | ||
601 | |||
602 | if (si->pdata->set_speed) | ||
603 | si->pdata->set_speed(si->dev, speed); | ||
604 | |||
605 | sa1100_irda_rx_alloc(si); | ||
606 | sa1100_irda_rx_dma_start(si); | ||
607 | |||
608 | local_irq_restore(flags); | ||
609 | |||
610 | break; | ||
611 | |||
612 | default: | ||
613 | break; | ||
641 | } | 614 | } |
642 | 615 | ||
643 | /* | 616 | return ret; |
644 | * Make sure that the TX queue is available for sending | 617 | } |
645 | * (for retries). TX has priority over RX at all times. | 618 | |
646 | */ | 619 | /* |
647 | netif_wake_queue(dev); | 620 | * Control the power state of the IrDA transmitter. |
621 | * State: | ||
622 | * 0 - off | ||
623 | * 1 - short range, lowest power | ||
624 | * 2 - medium range, medium power | ||
625 | * 3 - maximum range, high power | ||
626 | * | ||
627 | * Currently, only assabet is known to support this. | ||
628 | */ | ||
629 | static int | ||
630 | __sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state) | ||
631 | { | ||
632 | int ret = 0; | ||
633 | if (si->pdata->set_power) | ||
634 | ret = si->pdata->set_power(si->dev, state); | ||
635 | return ret; | ||
636 | } | ||
637 | |||
638 | static inline int | ||
639 | sa1100_set_power(struct sa1100_irda *si, unsigned int state) | ||
640 | { | ||
641 | int ret; | ||
642 | |||
643 | ret = __sa1100_irda_set_power(si, state); | ||
644 | if (ret == 0) | ||
645 | si->power = state; | ||
646 | |||
647 | return ret; | ||
648 | } | ||
649 | |||
650 | static irqreturn_t sa1100_irda_irq(int irq, void *dev_id) | ||
651 | { | ||
652 | struct net_device *dev = dev_id; | ||
653 | struct sa1100_irda *si = netdev_priv(dev); | ||
654 | |||
655 | return si->irq(dev, si); | ||
648 | } | 656 | } |
649 | 657 | ||
650 | static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) | 658 | static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) |
@@ -660,62 +668,19 @@ static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) | |||
660 | if (speed != si->speed && speed != -1) | 668 | if (speed != si->speed && speed != -1) |
661 | si->newspeed = speed; | 669 | si->newspeed = speed; |
662 | 670 | ||
663 | /* | 671 | /* If this is an empty frame, we can bypass a lot. */ |
664 | * If this is an empty frame, we can bypass a lot. | ||
665 | */ | ||
666 | if (skb->len == 0) { | 672 | if (skb->len == 0) { |
667 | if (si->newspeed) { | 673 | sa1100_irda_check_speed(si); |
668 | si->newspeed = 0; | ||
669 | sa1100_irda_set_speed(si, speed); | ||
670 | } | ||
671 | dev_kfree_skb(skb); | 674 | dev_kfree_skb(skb); |
672 | return NETDEV_TX_OK; | 675 | return NETDEV_TX_OK; |
673 | } | 676 | } |
674 | 677 | ||
675 | if (!IS_FIR(si)) { | 678 | netif_stop_queue(dev); |
676 | netif_stop_queue(dev); | ||
677 | |||
678 | si->tx_buff.data = si->tx_buff.head; | ||
679 | si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, | ||
680 | si->tx_buff.truesize); | ||
681 | |||
682 | /* | ||
683 | * Set the transmit interrupt enable. This will fire | ||
684 | * off an interrupt immediately. Note that we disable | ||
685 | * the receiver so we won't get spurious characteres | ||
686 | * received. | ||
687 | */ | ||
688 | Ser2UTCR3 = UTCR3_TIE | UTCR3_TXE; | ||
689 | |||
690 | dev_kfree_skb(skb); | ||
691 | } else { | ||
692 | int mtt = irda_get_mtt(skb); | ||
693 | |||
694 | /* | ||
695 | * We must not be transmitting... | ||
696 | */ | ||
697 | BUG_ON(si->txskb); | ||
698 | |||
699 | netif_stop_queue(dev); | ||
700 | |||
701 | si->txskb = skb; | ||
702 | si->txbuf_dma = dma_map_single(si->dev, skb->data, | ||
703 | skb->len, DMA_TO_DEVICE); | ||
704 | |||
705 | sa1100_start_dma(si->txdma, si->txbuf_dma, skb->len); | ||
706 | |||
707 | /* | ||
708 | * If we have a mean turn-around time, impose the specified | ||
709 | * specified delay. We could shorten this by timing from | ||
710 | * the point we received the packet. | ||
711 | */ | ||
712 | if (mtt) | ||
713 | udelay(mtt); | ||
714 | 679 | ||
715 | Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_TXE; | 680 | /* We must not already have a skb to transmit... */ |
716 | } | 681 | BUG_ON(si->dma_tx.skb); |
717 | 682 | ||
718 | return NETDEV_TX_OK; | 683 | return si->tx_start(skb, dev, si); |
719 | } | 684 | } |
720 | 685 | ||
721 | static int | 686 | static int |
@@ -762,6 +727,69 @@ sa1100_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) | |||
762 | return ret; | 727 | return ret; |
763 | } | 728 | } |
764 | 729 | ||
730 | static int sa1100_irda_startup(struct sa1100_irda *si) | ||
731 | { | ||
732 | int ret; | ||
733 | |||
734 | /* | ||
735 | * Ensure that the ports for this device are setup correctly. | ||
736 | */ | ||
737 | if (si->pdata->startup) { | ||
738 | ret = si->pdata->startup(si->dev); | ||
739 | if (ret) | ||
740 | return ret; | ||
741 | } | ||
742 | |||
743 | /* | ||
744 | * Configure PPC for IRDA - we want to drive TXD2 low. | ||
745 | * We also want to drive this pin low during sleep. | ||
746 | */ | ||
747 | PPSR &= ~PPC_TXD2; | ||
748 | PSDR &= ~PPC_TXD2; | ||
749 | PPDR |= PPC_TXD2; | ||
750 | |||
751 | /* | ||
752 | * Enable HP-SIR modulation, and ensure that the port is disabled. | ||
753 | */ | ||
754 | Ser2UTCR3 = 0; | ||
755 | Ser2HSCR0 = HSCR0_UART; | ||
756 | Ser2UTCR4 = si->utcr4; | ||
757 | Ser2UTCR0 = UTCR0_8BitData; | ||
758 | Ser2HSCR2 = HSCR2_TrDataH | HSCR2_RcDataL; | ||
759 | |||
760 | /* | ||
761 | * Clear status register | ||
762 | */ | ||
763 | Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; | ||
764 | |||
765 | ret = sa1100_irda_set_speed(si, si->speed = 9600); | ||
766 | if (ret) { | ||
767 | Ser2UTCR3 = 0; | ||
768 | Ser2HSCR0 = 0; | ||
769 | |||
770 | if (si->pdata->shutdown) | ||
771 | si->pdata->shutdown(si->dev); | ||
772 | } | ||
773 | |||
774 | return ret; | ||
775 | } | ||
776 | |||
777 | static void sa1100_irda_shutdown(struct sa1100_irda *si) | ||
778 | { | ||
779 | /* | ||
780 | * Stop all DMA activity. | ||
781 | */ | ||
782 | dmaengine_terminate_all(si->dma_rx.chan); | ||
783 | dmaengine_terminate_all(si->dma_tx.chan); | ||
784 | |||
785 | /* Disable the port. */ | ||
786 | Ser2UTCR3 = 0; | ||
787 | Ser2HSCR0 = 0; | ||
788 | |||
789 | if (si->pdata->shutdown) | ||
790 | si->pdata->shutdown(si->dev); | ||
791 | } | ||
792 | |||
765 | static int sa1100_irda_start(struct net_device *dev) | 793 | static int sa1100_irda_start(struct net_device *dev) |
766 | { | 794 | { |
767 | struct sa1100_irda *si = netdev_priv(dev); | 795 | struct sa1100_irda *si = netdev_priv(dev); |
@@ -769,26 +797,17 @@ static int sa1100_irda_start(struct net_device *dev) | |||
769 | 797 | ||
770 | si->speed = 9600; | 798 | si->speed = 9600; |
771 | 799 | ||
772 | err = request_irq(dev->irq, sa1100_irda_irq, 0, dev->name, dev); | 800 | err = sa1100_irda_dma_request(si->dev, &si->dma_rx, "Ser2ICPRc", |
773 | if (err) | 801 | &sa1100_irda_fir_rx); |
774 | goto err_irq; | ||
775 | |||
776 | err = sa1100_request_dma(DMA_Ser2HSSPRd, "IrDA receive", | ||
777 | NULL, NULL, &si->rxdma); | ||
778 | if (err) | 802 | if (err) |
779 | goto err_rx_dma; | 803 | goto err_rx_dma; |
780 | 804 | ||
781 | err = sa1100_request_dma(DMA_Ser2HSSPWr, "IrDA transmit", | 805 | err = sa1100_irda_dma_request(si->dev, &si->dma_tx, "Ser2ICPTr", |
782 | sa1100_irda_txdma_irq, dev, &si->txdma); | 806 | &sa1100_irda_sir_tx); |
783 | if (err) | 807 | if (err) |
784 | goto err_tx_dma; | 808 | goto err_tx_dma; |
785 | 809 | ||
786 | /* | 810 | /* |
787 | * The interrupt must remain disabled for now. | ||
788 | */ | ||
789 | disable_irq(dev->irq); | ||
790 | |||
791 | /* | ||
792 | * Setup the serial port for the specified speed. | 811 | * Setup the serial port for the specified speed. |
793 | */ | 812 | */ |
794 | err = sa1100_irda_startup(si); | 813 | err = sa1100_irda_startup(si); |
@@ -803,44 +822,60 @@ static int sa1100_irda_start(struct net_device *dev) | |||
803 | if (!si->irlap) | 822 | if (!si->irlap) |
804 | goto err_irlap; | 823 | goto err_irlap; |
805 | 824 | ||
825 | err = request_irq(dev->irq, sa1100_irda_irq, 0, dev->name, dev); | ||
826 | if (err) | ||
827 | goto err_irq; | ||
828 | |||
806 | /* | 829 | /* |
807 | * Now enable the interrupt and start the queue | 830 | * Now enable the interrupt and start the queue |
808 | */ | 831 | */ |
809 | si->open = 1; | 832 | si->open = 1; |
810 | sa1100_set_power(si, power_level); /* low power mode */ | 833 | sa1100_set_power(si, power_level); /* low power mode */ |
811 | enable_irq(dev->irq); | 834 | |
812 | netif_start_queue(dev); | 835 | netif_start_queue(dev); |
813 | return 0; | 836 | return 0; |
814 | 837 | ||
838 | err_irq: | ||
839 | irlap_close(si->irlap); | ||
815 | err_irlap: | 840 | err_irlap: |
816 | si->open = 0; | 841 | si->open = 0; |
817 | sa1100_irda_shutdown(si); | 842 | sa1100_irda_shutdown(si); |
818 | err_startup: | 843 | err_startup: |
819 | sa1100_free_dma(si->txdma); | 844 | dma_release_channel(si->dma_tx.chan); |
820 | err_tx_dma: | 845 | err_tx_dma: |
821 | sa1100_free_dma(si->rxdma); | 846 | dma_release_channel(si->dma_rx.chan); |
822 | err_rx_dma: | 847 | err_rx_dma: |
823 | free_irq(dev->irq, dev); | ||
824 | err_irq: | ||
825 | return err; | 848 | return err; |
826 | } | 849 | } |
827 | 850 | ||
828 | static int sa1100_irda_stop(struct net_device *dev) | 851 | static int sa1100_irda_stop(struct net_device *dev) |
829 | { | 852 | { |
830 | struct sa1100_irda *si = netdev_priv(dev); | 853 | struct sa1100_irda *si = netdev_priv(dev); |
854 | struct sk_buff *skb; | ||
855 | |||
856 | netif_stop_queue(dev); | ||
831 | 857 | ||
832 | disable_irq(dev->irq); | 858 | si->open = 0; |
833 | sa1100_irda_shutdown(si); | 859 | sa1100_irda_shutdown(si); |
834 | 860 | ||
835 | /* | 861 | /* |
836 | * If we have been doing DMA receive, make sure we | 862 | * If we have been doing any DMA activity, make sure we |
837 | * tidy that up cleanly. | 863 | * tidy that up cleanly. |
838 | */ | 864 | */ |
839 | if (si->rxskb) { | 865 | skb = si->dma_rx.skb; |
840 | dma_unmap_single(si->dev, si->rxbuf_dma, HPSIR_MAX_RXLEN, | 866 | if (skb) { |
841 | DMA_FROM_DEVICE); | 867 | dma_unmap_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, |
842 | dev_kfree_skb(si->rxskb); | 868 | DMA_FROM_DEVICE); |
843 | si->rxskb = NULL; | 869 | dev_kfree_skb(skb); |
870 | si->dma_rx.skb = NULL; | ||
871 | } | ||
872 | |||
873 | skb = si->dma_tx.skb; | ||
874 | if (skb) { | ||
875 | dma_unmap_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, | ||
876 | DMA_TO_DEVICE); | ||
877 | dev_kfree_skb(skb); | ||
878 | si->dma_tx.skb = NULL; | ||
844 | } | 879 | } |
845 | 880 | ||
846 | /* Stop IrLAP */ | 881 | /* Stop IrLAP */ |
@@ -849,14 +884,11 @@ static int sa1100_irda_stop(struct net_device *dev) | |||
849 | si->irlap = NULL; | 884 | si->irlap = NULL; |
850 | } | 885 | } |
851 | 886 | ||
852 | netif_stop_queue(dev); | ||
853 | si->open = 0; | ||
854 | |||
855 | /* | 887 | /* |
856 | * Free resources | 888 | * Free resources |
857 | */ | 889 | */ |
858 | sa1100_free_dma(si->txdma); | 890 | dma_release_channel(si->dma_tx.chan); |
859 | sa1100_free_dma(si->rxdma); | 891 | dma_release_channel(si->dma_rx.chan); |
860 | free_irq(dev->irq, dev); | 892 | free_irq(dev->irq, dev); |
861 | 893 | ||
862 | sa1100_set_power(si, 0); | 894 | sa1100_set_power(si, 0); |
@@ -888,11 +920,15 @@ static int sa1100_irda_probe(struct platform_device *pdev) | |||
888 | struct net_device *dev; | 920 | struct net_device *dev; |
889 | struct sa1100_irda *si; | 921 | struct sa1100_irda *si; |
890 | unsigned int baudrate_mask; | 922 | unsigned int baudrate_mask; |
891 | int err; | 923 | int err, irq; |
892 | 924 | ||
893 | if (!pdev->dev.platform_data) | 925 | if (!pdev->dev.platform_data) |
894 | return -EINVAL; | 926 | return -EINVAL; |
895 | 927 | ||
928 | irq = platform_get_irq(pdev, 0); | ||
929 | if (irq <= 0) | ||
930 | return irq < 0 ? irq : -ENXIO; | ||
931 | |||
896 | err = request_mem_region(__PREG(Ser2UTCR0), 0x24, "IrDA") ? 0 : -EBUSY; | 932 | err = request_mem_region(__PREG(Ser2UTCR0), 0x24, "IrDA") ? 0 : -EBUSY; |
897 | if (err) | 933 | if (err) |
898 | goto err_mem_1; | 934 | goto err_mem_1; |
@@ -907,22 +943,27 @@ static int sa1100_irda_probe(struct platform_device *pdev) | |||
907 | if (!dev) | 943 | if (!dev) |
908 | goto err_mem_4; | 944 | goto err_mem_4; |
909 | 945 | ||
946 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
947 | |||
910 | si = netdev_priv(dev); | 948 | si = netdev_priv(dev); |
911 | si->dev = &pdev->dev; | 949 | si->dev = &pdev->dev; |
912 | si->pdata = pdev->dev.platform_data; | 950 | si->pdata = pdev->dev.platform_data; |
913 | 951 | ||
952 | sg_init_table(&si->dma_rx.sg, 1); | ||
953 | sg_init_table(&si->dma_tx.sg, 1); | ||
954 | |||
914 | /* | 955 | /* |
915 | * Initialise the HP-SIR buffers | 956 | * Initialise the HP-SIR buffers |
916 | */ | 957 | */ |
917 | err = sa1100_irda_init_iobuf(&si->rx_buff, 14384); | 958 | err = sa1100_irda_init_iobuf(&si->rx_buff, 14384); |
918 | if (err) | 959 | if (err) |
919 | goto err_mem_5; | 960 | goto err_mem_5; |
920 | err = sa1100_irda_init_iobuf(&si->tx_buff, 4000); | 961 | err = sa1100_irda_init_iobuf(&si->tx_buff, IRDA_SIR_MAX_FRAME); |
921 | if (err) | 962 | if (err) |
922 | goto err_mem_5; | 963 | goto err_mem_5; |
923 | 964 | ||
924 | dev->netdev_ops = &sa1100_irda_netdev_ops; | 965 | dev->netdev_ops = &sa1100_irda_netdev_ops; |
925 | dev->irq = IRQ_Ser2ICP; | 966 | dev->irq = irq; |
926 | 967 | ||
927 | irda_init_max_qos_capabilies(&si->qos); | 968 | irda_init_max_qos_capabilies(&si->qos); |
928 | 969 | ||
@@ -996,6 +1037,74 @@ static int sa1100_irda_remove(struct platform_device *pdev) | |||
996 | return 0; | 1037 | return 0; |
997 | } | 1038 | } |
998 | 1039 | ||
1040 | #ifdef CONFIG_PM | ||
1041 | /* | ||
1042 | * Suspend the IrDA interface. | ||
1043 | */ | ||
1044 | static int sa1100_irda_suspend(struct platform_device *pdev, pm_message_t state) | ||
1045 | { | ||
1046 | struct net_device *dev = platform_get_drvdata(pdev); | ||
1047 | struct sa1100_irda *si; | ||
1048 | |||
1049 | if (!dev) | ||
1050 | return 0; | ||
1051 | |||
1052 | si = netdev_priv(dev); | ||
1053 | if (si->open) { | ||
1054 | /* | ||
1055 | * Stop the transmit queue | ||
1056 | */ | ||
1057 | netif_device_detach(dev); | ||
1058 | disable_irq(dev->irq); | ||
1059 | sa1100_irda_shutdown(si); | ||
1060 | __sa1100_irda_set_power(si, 0); | ||
1061 | } | ||
1062 | |||
1063 | return 0; | ||
1064 | } | ||
1065 | |||
1066 | /* | ||
1067 | * Resume the IrDA interface. | ||
1068 | */ | ||
1069 | static int sa1100_irda_resume(struct platform_device *pdev) | ||
1070 | { | ||
1071 | struct net_device *dev = platform_get_drvdata(pdev); | ||
1072 | struct sa1100_irda *si; | ||
1073 | |||
1074 | if (!dev) | ||
1075 | return 0; | ||
1076 | |||
1077 | si = netdev_priv(dev); | ||
1078 | if (si->open) { | ||
1079 | /* | ||
1080 | * If we missed a speed change, initialise at the new speed | ||
1081 | * directly. It is debatable whether this is actually | ||
1082 | * required, but in the interests of continuing from where | ||
1083 | * we left off it is desirable. The converse argument is | ||
1084 | * that we should re-negotiate at 9600 baud again. | ||
1085 | */ | ||
1086 | if (si->newspeed) { | ||
1087 | si->speed = si->newspeed; | ||
1088 | si->newspeed = 0; | ||
1089 | } | ||
1090 | |||
1091 | sa1100_irda_startup(si); | ||
1092 | __sa1100_irda_set_power(si, si->power); | ||
1093 | enable_irq(dev->irq); | ||
1094 | |||
1095 | /* | ||
1096 | * This automatically wakes up the queue | ||
1097 | */ | ||
1098 | netif_device_attach(dev); | ||
1099 | } | ||
1100 | |||
1101 | return 0; | ||
1102 | } | ||
1103 | #else | ||
1104 | #define sa1100_irda_suspend NULL | ||
1105 | #define sa1100_irda_resume NULL | ||
1106 | #endif | ||
1107 | |||
999 | static struct platform_driver sa1100ir_driver = { | 1108 | static struct platform_driver sa1100ir_driver = { |
1000 | .probe = sa1100_irda_probe, | 1109 | .probe = sa1100_irda_probe, |
1001 | .remove = sa1100_irda_remove, | 1110 | .remove = sa1100_irda_remove, |
diff --git a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1100_neponset.c index c95639b5f2a0..4300a7fb3edb 100644 --- a/drivers/pcmcia/sa1100_neponset.c +++ b/drivers/pcmcia/sa1100_neponset.c | |||
@@ -94,12 +94,7 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta | |||
94 | 94 | ||
95 | ret = sa1111_pcmcia_configure_socket(skt, state); | 95 | ret = sa1111_pcmcia_configure_socket(skt, state); |
96 | if (ret == 0) { | 96 | if (ret == 0) { |
97 | unsigned long flags; | 97 | neponset_ncr_frob(ncr_mask, ncr_set); |
98 | |||
99 | local_irq_save(flags); | ||
100 | NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set; | ||
101 | |||
102 | local_irq_restore(flags); | ||
103 | sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); | 98 | sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); |
104 | } | 99 | } |
105 | 100 | ||
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index 27f2fe3b7fb4..33568e18998b 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c | |||
@@ -22,6 +22,40 @@ | |||
22 | 22 | ||
23 | #include "sa1111_generic.h" | 23 | #include "sa1111_generic.h" |
24 | 24 | ||
25 | /* | ||
26 | * These are offsets from the above base. | ||
27 | */ | ||
28 | #define PCCR 0x0000 | ||
29 | #define PCSSR 0x0004 | ||
30 | #define PCSR 0x0008 | ||
31 | |||
32 | #define PCSR_S0_READY (1<<0) | ||
33 | #define PCSR_S1_READY (1<<1) | ||
34 | #define PCSR_S0_DETECT (1<<2) | ||
35 | #define PCSR_S1_DETECT (1<<3) | ||
36 | #define PCSR_S0_VS1 (1<<4) | ||
37 | #define PCSR_S0_VS2 (1<<5) | ||
38 | #define PCSR_S1_VS1 (1<<6) | ||
39 | #define PCSR_S1_VS2 (1<<7) | ||
40 | #define PCSR_S0_WP (1<<8) | ||
41 | #define PCSR_S1_WP (1<<9) | ||
42 | #define PCSR_S0_BVD1 (1<<10) | ||
43 | #define PCSR_S0_BVD2 (1<<11) | ||
44 | #define PCSR_S1_BVD1 (1<<12) | ||
45 | #define PCSR_S1_BVD2 (1<<13) | ||
46 | |||
47 | #define PCCR_S0_RST (1<<0) | ||
48 | #define PCCR_S1_RST (1<<1) | ||
49 | #define PCCR_S0_FLT (1<<2) | ||
50 | #define PCCR_S1_FLT (1<<3) | ||
51 | #define PCCR_S0_PWAITEN (1<<4) | ||
52 | #define PCCR_S1_PWAITEN (1<<5) | ||
53 | #define PCCR_S0_PSE (1<<6) | ||
54 | #define PCCR_S1_PSE (1<<7) | ||
55 | |||
56 | #define PCSSR_S0_SLEEP (1<<0) | ||
57 | #define PCSSR_S1_SLEEP (1<<1) | ||
58 | |||
25 | #define IDX_IRQ_S0_READY_NINT (0) | 59 | #define IDX_IRQ_S0_READY_NINT (0) |
26 | #define IDX_IRQ_S0_CD_VALID (1) | 60 | #define IDX_IRQ_S0_CD_VALID (1) |
27 | #define IDX_IRQ_S0_BVD1_STSCHG (2) | 61 | #define IDX_IRQ_S0_BVD1_STSCHG (2) |
@@ -49,7 +83,7 @@ static void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | |||
49 | void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 83 | void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) |
50 | { | 84 | { |
51 | struct sa1111_pcmcia_socket *s = to_skt(skt); | 85 | struct sa1111_pcmcia_socket *s = to_skt(skt); |
52 | unsigned long status = sa1111_readl(s->dev->mapbase + SA1111_PCSR); | 86 | unsigned long status = sa1111_readl(s->dev->mapbase + PCSR); |
53 | 87 | ||
54 | switch (skt->nr) { | 88 | switch (skt->nr) { |
55 | case 0: | 89 | case 0: |
@@ -105,10 +139,10 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s | |||
105 | pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT; | 139 | pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT; |
106 | 140 | ||
107 | local_irq_save(flags); | 141 | local_irq_save(flags); |
108 | val = sa1111_readl(s->dev->mapbase + SA1111_PCCR); | 142 | val = sa1111_readl(s->dev->mapbase + PCCR); |
109 | val &= ~pccr_skt_mask; | 143 | val &= ~pccr_skt_mask; |
110 | val |= pccr_set_mask & pccr_skt_mask; | 144 | val |= pccr_set_mask & pccr_skt_mask; |
111 | sa1111_writel(val, s->dev->mapbase + SA1111_PCCR); | 145 | sa1111_writel(val, s->dev->mapbase + PCCR); |
112 | local_irq_restore(flags); | 146 | local_irq_restore(flags); |
113 | 147 | ||
114 | return 0; | 148 | return 0; |
@@ -163,12 +197,18 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, | |||
163 | static int pcmcia_probe(struct sa1111_dev *dev) | 197 | static int pcmcia_probe(struct sa1111_dev *dev) |
164 | { | 198 | { |
165 | void __iomem *base; | 199 | void __iomem *base; |
200 | int ret; | ||
201 | |||
202 | ret = sa1111_enable_device(dev); | ||
203 | if (ret) | ||
204 | return ret; | ||
166 | 205 | ||
167 | dev_set_drvdata(&dev->dev, NULL); | 206 | dev_set_drvdata(&dev->dev, NULL); |
168 | 207 | ||
169 | if (!request_mem_region(dev->res.start, 512, | 208 | if (!request_mem_region(dev->res.start, 512, SA1111_DRIVER_NAME(dev))) { |
170 | SA1111_DRIVER_NAME(dev))) | 209 | sa1111_disable_device(dev); |
171 | return -EBUSY; | 210 | return -EBUSY; |
211 | } | ||
172 | 212 | ||
173 | base = dev->mapbase; | 213 | base = dev->mapbase; |
174 | 214 | ||
@@ -181,8 +221,8 @@ static int pcmcia_probe(struct sa1111_dev *dev) | |||
181 | /* | 221 | /* |
182 | * Initialise the suspend state. | 222 | * Initialise the suspend state. |
183 | */ | 223 | */ |
184 | sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + SA1111_PCSSR); | 224 | sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + PCSSR); |
185 | sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + SA1111_PCCR); | 225 | sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + PCCR); |
186 | 226 | ||
187 | #ifdef CONFIG_SA1100_BADGE4 | 227 | #ifdef CONFIG_SA1100_BADGE4 |
188 | pcmcia_badge4_init(&dev->dev); | 228 | pcmcia_badge4_init(&dev->dev); |
@@ -212,6 +252,7 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev) | |||
212 | } | 252 | } |
213 | 253 | ||
214 | release_mem_region(dev->res.start, 512); | 254 | release_mem_region(dev->res.start, 512); |
255 | sa1111_disable_device(dev); | ||
215 | return 0; | 256 | return 0; |
216 | } | 257 | } |
217 | 258 | ||
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 4bde4f9821ba..e1004fb37bd9 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c | |||
@@ -16,29 +16,115 @@ | |||
16 | #include <mach/hardware.h> | 16 | #include <mach/hardware.h> |
17 | #include <asm/mach-types.h> | 17 | #include <asm/mach-types.h> |
18 | #include <mach/assabet.h> | 18 | #include <mach/assabet.h> |
19 | #include <mach/badge4.h> | ||
20 | #include <asm/hardware/sa1111.h> | 19 | #include <asm/hardware/sa1111.h> |
21 | 20 | ||
22 | #ifndef CONFIG_SA1111 | 21 | #ifndef CONFIG_SA1111 |
23 | #error "This file is SA-1111 bus glue. CONFIG_SA1111 must be defined." | 22 | #error "This file is SA-1111 bus glue. CONFIG_SA1111 must be defined." |
24 | #endif | 23 | #endif |
25 | 24 | ||
26 | extern int usb_disabled(void); | 25 | #define USB_STATUS 0x0118 |
26 | #define USB_RESET 0x011c | ||
27 | #define USB_IRQTEST 0x0120 | ||
28 | |||
29 | #define USB_RESET_FORCEIFRESET (1 << 0) | ||
30 | #define USB_RESET_FORCEHCRESET (1 << 1) | ||
31 | #define USB_RESET_CLKGENRESET (1 << 2) | ||
32 | #define USB_RESET_SIMSCALEDOWN (1 << 3) | ||
33 | #define USB_RESET_USBINTTEST (1 << 4) | ||
34 | #define USB_RESET_SLEEPSTBYEN (1 << 5) | ||
35 | #define USB_RESET_PWRSENSELOW (1 << 6) | ||
36 | #define USB_RESET_PWRCTRLLOW (1 << 7) | ||
37 | |||
38 | #define USB_STATUS_IRQHCIRMTWKUP (1 << 7) | ||
39 | #define USB_STATUS_IRQHCIBUFFACC (1 << 8) | ||
40 | #define USB_STATUS_NIRQHCIM (1 << 9) | ||
41 | #define USB_STATUS_NHCIMFCLR (1 << 10) | ||
42 | #define USB_STATUS_USBPWRSENSE (1 << 11) | ||
27 | 43 | ||
28 | /*-------------------------------------------------------------------------*/ | 44 | #if 0 |
45 | static void dump_hci_status(struct usb_hcd *hcd, const char *label) | ||
46 | { | ||
47 | unsigned long status = sa1111_readl(hcd->regs + USB_STATUS); | ||
48 | |||
49 | dbg("%s USB_STATUS = { %s%s%s%s%s}", label, | ||
50 | ((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""), | ||
51 | ((status & USB_STATUS_IRQHCIBUFFACC) ? "IRQHCIBUFFACC " : ""), | ||
52 | ((status & USB_STATUS_NIRQHCIM) ? "" : "IRQHCIM "), | ||
53 | ((status & USB_STATUS_NHCIMFCLR) ? "" : "HCIMFCLR "), | ||
54 | ((status & USB_STATUS_USBPWRSENSE) ? "USBPWRSENSE " : "")); | ||
55 | } | ||
56 | #endif | ||
29 | 57 | ||
30 | static void sa1111_start_hc(struct sa1111_dev *dev) | 58 | static int ohci_sa1111_reset(struct usb_hcd *hcd) |
31 | { | 59 | { |
32 | unsigned int usb_rst = 0; | 60 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
61 | |||
62 | ohci_hcd_init(ohci); | ||
63 | return ohci_init(ohci); | ||
64 | } | ||
33 | 65 | ||
34 | printk(KERN_DEBUG "%s: starting SA-1111 OHCI USB Controller\n", | 66 | static int __devinit ohci_sa1111_start(struct usb_hcd *hcd) |
35 | __FILE__); | 67 | { |
68 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
69 | int ret; | ||
36 | 70 | ||
37 | #ifdef CONFIG_SA1100_BADGE4 | 71 | ret = ohci_run(ohci); |
38 | if (machine_is_badge4()) { | 72 | if (ret < 0) { |
39 | badge4_set_5V(BADGE4_5V_USB, 1); | 73 | ohci_err(ohci, "can't start\n"); |
74 | ohci_stop(hcd); | ||
40 | } | 75 | } |
76 | return ret; | ||
77 | } | ||
78 | |||
79 | static const struct hc_driver ohci_sa1111_hc_driver = { | ||
80 | .description = hcd_name, | ||
81 | .product_desc = "SA-1111 OHCI", | ||
82 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
83 | |||
84 | /* | ||
85 | * generic hardware linkage | ||
86 | */ | ||
87 | .irq = ohci_irq, | ||
88 | .flags = HCD_USB11 | HCD_MEMORY, | ||
89 | |||
90 | /* | ||
91 | * basic lifecycle operations | ||
92 | */ | ||
93 | .reset = ohci_sa1111_reset, | ||
94 | .start = ohci_sa1111_start, | ||
95 | .stop = ohci_stop, | ||
96 | .shutdown = ohci_shutdown, | ||
97 | |||
98 | /* | ||
99 | * managing i/o requests and associated device resources | ||
100 | */ | ||
101 | .urb_enqueue = ohci_urb_enqueue, | ||
102 | .urb_dequeue = ohci_urb_dequeue, | ||
103 | .endpoint_disable = ohci_endpoint_disable, | ||
104 | |||
105 | /* | ||
106 | * scheduling support | ||
107 | */ | ||
108 | .get_frame_number = ohci_get_frame, | ||
109 | |||
110 | /* | ||
111 | * root hub support | ||
112 | */ | ||
113 | .hub_status_data = ohci_hub_status_data, | ||
114 | .hub_control = ohci_hub_control, | ||
115 | #ifdef CONFIG_PM | ||
116 | .bus_suspend = ohci_bus_suspend, | ||
117 | .bus_resume = ohci_bus_resume, | ||
41 | #endif | 118 | #endif |
119 | .start_port_reset = ohci_start_port_reset, | ||
120 | }; | ||
121 | |||
122 | static int sa1111_start_hc(struct sa1111_dev *dev) | ||
123 | { | ||
124 | unsigned int usb_rst = 0; | ||
125 | int ret; | ||
126 | |||
127 | dev_dbg(&dev->dev, "starting SA-1111 OHCI USB Controller\n"); | ||
42 | 128 | ||
43 | if (machine_is_xp860() || | 129 | if (machine_is_xp860() || |
44 | machine_has_neponset() || | 130 | machine_has_neponset() || |
@@ -51,220 +137,121 @@ static void sa1111_start_hc(struct sa1111_dev *dev) | |||
51 | * host controller in reset. | 137 | * host controller in reset. |
52 | */ | 138 | */ |
53 | sa1111_writel(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET, | 139 | sa1111_writel(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET, |
54 | dev->mapbase + SA1111_USB_RESET); | 140 | dev->mapbase + USB_RESET); |
55 | 141 | ||
56 | /* | 142 | /* |
57 | * Now, carefully enable the USB clock, and take | 143 | * Now, carefully enable the USB clock, and take |
58 | * the USB host controller out of reset. | 144 | * the USB host controller out of reset. |
59 | */ | 145 | */ |
60 | sa1111_enable_device(dev); | 146 | ret = sa1111_enable_device(dev); |
61 | udelay(11); | 147 | if (ret == 0) { |
62 | sa1111_writel(usb_rst, dev->mapbase + SA1111_USB_RESET); | 148 | udelay(11); |
149 | sa1111_writel(usb_rst, dev->mapbase + USB_RESET); | ||
150 | } | ||
151 | |||
152 | return ret; | ||
63 | } | 153 | } |
64 | 154 | ||
65 | static void sa1111_stop_hc(struct sa1111_dev *dev) | 155 | static void sa1111_stop_hc(struct sa1111_dev *dev) |
66 | { | 156 | { |
67 | unsigned int usb_rst; | 157 | unsigned int usb_rst; |
68 | printk(KERN_DEBUG "%s: stopping SA-1111 OHCI USB Controller\n", | 158 | |
69 | __FILE__); | 159 | dev_dbg(&dev->dev, "stopping SA-1111 OHCI USB Controller\n"); |
70 | 160 | ||
71 | /* | 161 | /* |
72 | * Put the USB host controller into reset. | 162 | * Put the USB host controller into reset. |
73 | */ | 163 | */ |
74 | usb_rst = sa1111_readl(dev->mapbase + SA1111_USB_RESET); | 164 | usb_rst = sa1111_readl(dev->mapbase + USB_RESET); |
75 | sa1111_writel(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET, | 165 | sa1111_writel(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET, |
76 | dev->mapbase + SA1111_USB_RESET); | 166 | dev->mapbase + USB_RESET); |
77 | 167 | ||
78 | /* | 168 | /* |
79 | * Stop the USB clock. | 169 | * Stop the USB clock. |
80 | */ | 170 | */ |
81 | sa1111_disable_device(dev); | 171 | sa1111_disable_device(dev); |
82 | |||
83 | #ifdef CONFIG_SA1100_BADGE4 | ||
84 | if (machine_is_badge4()) { | ||
85 | /* Disable power to the USB bus */ | ||
86 | badge4_set_5V(BADGE4_5V_USB, 0); | ||
87 | } | ||
88 | #endif | ||
89 | } | ||
90 | |||
91 | |||
92 | /*-------------------------------------------------------------------------*/ | ||
93 | |||
94 | #if 0 | ||
95 | static void dump_hci_status(struct usb_hcd *hcd, const char *label) | ||
96 | { | ||
97 | unsigned long status = sa1111_readl(hcd->regs + SA1111_USB_STATUS); | ||
98 | |||
99 | dbg ("%s USB_STATUS = { %s%s%s%s%s}", label, | ||
100 | ((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""), | ||
101 | ((status & USB_STATUS_IRQHCIBUFFACC) ? "IRQHCIBUFFACC " : ""), | ||
102 | ((status & USB_STATUS_NIRQHCIM) ? "" : "IRQHCIM "), | ||
103 | ((status & USB_STATUS_NHCIMFCLR) ? "" : "HCIMFCLR "), | ||
104 | ((status & USB_STATUS_USBPWRSENSE) ? "USBPWRSENSE " : "")); | ||
105 | } | 172 | } |
106 | #endif | ||
107 | |||
108 | /*-------------------------------------------------------------------------*/ | ||
109 | |||
110 | /* configure so an HC device and id are always provided */ | ||
111 | /* always called with process context; sleeping is OK */ | ||
112 | |||
113 | 173 | ||
114 | /** | 174 | /** |
115 | * usb_hcd_sa1111_probe - initialize SA-1111-based HCDs | 175 | * ohci_hcd_sa1111_probe - initialize SA-1111-based HCDs |
116 | * Context: !in_interrupt() | ||
117 | * | 176 | * |
118 | * Allocates basic resources for this USB host controller, and | 177 | * Allocates basic resources for this USB host controller, and |
119 | * then invokes the start() method for the HCD associated with it | 178 | * then invokes the start() method for the HCD associated with it. |
120 | * through the hotplug entry's driver_data. | ||
121 | * | ||
122 | * Store this function in the HCD's struct pci_driver as probe(). | ||
123 | */ | 179 | */ |
124 | int usb_hcd_sa1111_probe (const struct hc_driver *driver, | 180 | static int ohci_hcd_sa1111_probe(struct sa1111_dev *dev) |
125 | struct sa1111_dev *dev) | ||
126 | { | 181 | { |
127 | struct usb_hcd *hcd; | 182 | struct usb_hcd *hcd; |
128 | int retval; | 183 | int ret; |
129 | 184 | ||
130 | hcd = usb_create_hcd (driver, &dev->dev, "sa1111"); | 185 | if (usb_disabled()) |
186 | return -ENODEV; | ||
187 | |||
188 | hcd = usb_create_hcd(&ohci_sa1111_hc_driver, &dev->dev, "sa1111"); | ||
131 | if (!hcd) | 189 | if (!hcd) |
132 | return -ENOMEM; | 190 | return -ENOMEM; |
191 | |||
133 | hcd->rsrc_start = dev->res.start; | 192 | hcd->rsrc_start = dev->res.start; |
134 | hcd->rsrc_len = resource_size(&dev->res); | 193 | hcd->rsrc_len = resource_size(&dev->res); |
135 | 194 | ||
136 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | 195 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { |
137 | dbg("request_mem_region failed"); | 196 | dbg("request_mem_region failed"); |
138 | retval = -EBUSY; | 197 | ret = -EBUSY; |
139 | goto err1; | 198 | goto err1; |
140 | } | 199 | } |
200 | |||
141 | hcd->regs = dev->mapbase; | 201 | hcd->regs = dev->mapbase; |
142 | 202 | ||
143 | sa1111_start_hc(dev); | 203 | ret = sa1111_start_hc(dev); |
144 | ohci_hcd_init(hcd_to_ohci(hcd)); | 204 | if (ret) |
205 | goto err2; | ||
145 | 206 | ||
146 | retval = usb_add_hcd(hcd, dev->irq[1], 0); | 207 | ret = usb_add_hcd(hcd, dev->irq[1], 0); |
147 | if (retval == 0) | 208 | if (ret == 0) |
148 | return retval; | 209 | return ret; |
149 | 210 | ||
150 | sa1111_stop_hc(dev); | 211 | sa1111_stop_hc(dev); |
212 | err2: | ||
151 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 213 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
152 | err1: | 214 | err1: |
153 | usb_put_hcd(hcd); | 215 | usb_put_hcd(hcd); |
154 | return retval; | 216 | return ret; |
155 | } | 217 | } |
156 | 218 | ||
157 | |||
158 | /* may be called without controller electrically present */ | ||
159 | /* may be called with controller, bus, and devices active */ | ||
160 | |||
161 | /** | 219 | /** |
162 | * usb_hcd_sa1111_remove - shutdown processing for SA-1111-based HCDs | 220 | * ohci_hcd_sa1111_remove - shutdown processing for SA-1111-based HCDs |
163 | * @dev: USB Host Controller being removed | 221 | * @dev: USB Host Controller being removed |
164 | * Context: !in_interrupt() | ||
165 | * | ||
166 | * Reverses the effect of usb_hcd_sa1111_probe(), first invoking | ||
167 | * the HCD's stop() method. It is always called from a thread | ||
168 | * context, normally "rmmod", "apmd", or something similar. | ||
169 | * | 222 | * |
223 | * Reverses the effect of ohci_hcd_sa1111_probe(), first invoking | ||
224 | * the HCD's stop() method. | ||
170 | */ | 225 | */ |
171 | void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev) | 226 | static int ohci_hcd_sa1111_remove(struct sa1111_dev *dev) |
172 | { | 227 | { |
228 | struct usb_hcd *hcd = sa1111_get_drvdata(dev); | ||
229 | |||
173 | usb_remove_hcd(hcd); | 230 | usb_remove_hcd(hcd); |
174 | sa1111_stop_hc(dev); | 231 | sa1111_stop_hc(dev); |
175 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 232 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
176 | usb_put_hcd(hcd); | 233 | usb_put_hcd(hcd); |
177 | } | ||
178 | |||
179 | /*-------------------------------------------------------------------------*/ | ||
180 | 234 | ||
181 | static int __devinit | ||
182 | ohci_sa1111_start (struct usb_hcd *hcd) | ||
183 | { | ||
184 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
185 | int ret; | ||
186 | |||
187 | if ((ret = ohci_init(ohci)) < 0) | ||
188 | return ret; | ||
189 | |||
190 | if ((ret = ohci_run (ohci)) < 0) { | ||
191 | err ("can't start %s", hcd->self.bus_name); | ||
192 | ohci_stop (hcd); | ||
193 | return ret; | ||
194 | } | ||
195 | return 0; | 235 | return 0; |
196 | } | 236 | } |
197 | 237 | ||
198 | /*-------------------------------------------------------------------------*/ | 238 | static void ohci_hcd_sa1111_shutdown(struct sa1111_dev *dev) |
199 | |||
200 | static const struct hc_driver ohci_sa1111_hc_driver = { | ||
201 | .description = hcd_name, | ||
202 | .product_desc = "SA-1111 OHCI", | ||
203 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
204 | |||
205 | /* | ||
206 | * generic hardware linkage | ||
207 | */ | ||
208 | .irq = ohci_irq, | ||
209 | .flags = HCD_USB11 | HCD_MEMORY, | ||
210 | |||
211 | /* | ||
212 | * basic lifecycle operations | ||
213 | */ | ||
214 | .start = ohci_sa1111_start, | ||
215 | .stop = ohci_stop, | ||
216 | |||
217 | /* | ||
218 | * managing i/o requests and associated device resources | ||
219 | */ | ||
220 | .urb_enqueue = ohci_urb_enqueue, | ||
221 | .urb_dequeue = ohci_urb_dequeue, | ||
222 | .endpoint_disable = ohci_endpoint_disable, | ||
223 | |||
224 | /* | ||
225 | * scheduling support | ||
226 | */ | ||
227 | .get_frame_number = ohci_get_frame, | ||
228 | |||
229 | /* | ||
230 | * root hub support | ||
231 | */ | ||
232 | .hub_status_data = ohci_hub_status_data, | ||
233 | .hub_control = ohci_hub_control, | ||
234 | #ifdef CONFIG_PM | ||
235 | .bus_suspend = ohci_bus_suspend, | ||
236 | .bus_resume = ohci_bus_resume, | ||
237 | #endif | ||
238 | .start_port_reset = ohci_start_port_reset, | ||
239 | }; | ||
240 | |||
241 | /*-------------------------------------------------------------------------*/ | ||
242 | |||
243 | static int ohci_hcd_sa1111_drv_probe(struct sa1111_dev *dev) | ||
244 | { | ||
245 | int ret; | ||
246 | |||
247 | if (usb_disabled()) | ||
248 | return -ENODEV; | ||
249 | |||
250 | ret = usb_hcd_sa1111_probe(&ohci_sa1111_hc_driver, dev); | ||
251 | return ret; | ||
252 | } | ||
253 | |||
254 | static int ohci_hcd_sa1111_drv_remove(struct sa1111_dev *dev) | ||
255 | { | 239 | { |
256 | struct usb_hcd *hcd = sa1111_get_drvdata(dev); | 240 | struct usb_hcd *hcd = sa1111_get_drvdata(dev); |
257 | 241 | ||
258 | usb_hcd_sa1111_remove(hcd, dev); | 242 | if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { |
259 | return 0; | 243 | hcd->driver->shutdown(hcd); |
244 | sa1111_stop_hc(dev); | ||
245 | } | ||
260 | } | 246 | } |
261 | 247 | ||
262 | static struct sa1111_driver ohci_hcd_sa1111_driver = { | 248 | static struct sa1111_driver ohci_hcd_sa1111_driver = { |
263 | .drv = { | 249 | .drv = { |
264 | .name = "sa1111-ohci", | 250 | .name = "sa1111-ohci", |
251 | .owner = THIS_MODULE, | ||
265 | }, | 252 | }, |
266 | .devid = SA1111_DEVID_USB, | 253 | .devid = SA1111_DEVID_USB, |
267 | .probe = ohci_hcd_sa1111_drv_probe, | 254 | .probe = ohci_hcd_sa1111_probe, |
268 | .remove = ohci_hcd_sa1111_drv_remove, | 255 | .remove = ohci_hcd_sa1111_remove, |
256 | .shutdown = ohci_hcd_sa1111_shutdown, | ||
269 | }; | 257 | }; |
270 | |||
diff --git a/include/linux/sa11x0-dma.h b/include/linux/sa11x0-dma.h new file mode 100644 index 000000000000..65839a58b8e5 --- /dev/null +++ b/include/linux/sa11x0-dma.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * SA11x0 DMA Engine support | ||
3 | * | ||
4 | * Copyright (C) 2012 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #ifndef __LINUX_SA11X0_DMA_H | ||
11 | #define __LINUX_SA11X0_DMA_H | ||
12 | |||
13 | struct dma_chan; | ||
14 | |||
15 | #if defined(CONFIG_DMA_SA11X0) || defined(CONFIG_DMA_SA11X0_MODULE) | ||
16 | bool sa11x0_dma_filter_fn(struct dma_chan *, void *); | ||
17 | #else | ||
18 | static inline bool sa11x0_dma_filter_fn(struct dma_chan *c, void *d) | ||
19 | { | ||
20 | return false; | ||
21 | } | ||
22 | #endif | ||
23 | |||
24 | #endif | ||