diff options
Diffstat (limited to 'drivers/atm')
-rw-r--r-- | drivers/atm/fore200e.c | 414 | ||||
-rw-r--r-- | drivers/atm/fore200e.h | 7 |
2 files changed, 189 insertions, 232 deletions
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 7213590b485d..c2fa9fdc5d32 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c | |||
@@ -47,8 +47,9 @@ | |||
47 | #include <asm/atomic.h> | 47 | #include <asm/atomic.h> |
48 | 48 | ||
49 | #ifdef CONFIG_SBUS | 49 | #ifdef CONFIG_SBUS |
50 | #include <linux/of.h> | ||
51 | #include <linux/of_device.h> | ||
50 | #include <asm/idprom.h> | 52 | #include <asm/idprom.h> |
51 | #include <asm/sbus.h> | ||
52 | #include <asm/openprom.h> | 53 | #include <asm/openprom.h> |
53 | #include <asm/oplib.h> | 54 | #include <asm/oplib.h> |
54 | #include <asm/pgtable.h> | 55 | #include <asm/pgtable.h> |
@@ -661,263 +662,189 @@ fore200e_pca_proc_read(struct fore200e* fore200e, char *page) | |||
661 | 662 | ||
662 | #ifdef CONFIG_SBUS | 663 | #ifdef CONFIG_SBUS |
663 | 664 | ||
664 | static u32 | 665 | static u32 fore200e_sba_read(volatile u32 __iomem *addr) |
665 | fore200e_sba_read(volatile u32 __iomem *addr) | ||
666 | { | 666 | { |
667 | return sbus_readl(addr); | 667 | return sbus_readl(addr); |
668 | } | 668 | } |
669 | 669 | ||
670 | 670 | static void fore200e_sba_write(u32 val, volatile u32 __iomem *addr) | |
671 | static void | ||
672 | fore200e_sba_write(u32 val, volatile u32 __iomem *addr) | ||
673 | { | 671 | { |
674 | sbus_writel(val, addr); | 672 | sbus_writel(val, addr); |
675 | } | 673 | } |
676 | 674 | ||
677 | 675 | static u32 fore200e_sba_dma_map(struct fore200e *fore200e, void* virt_addr, int size, int direction) | |
678 | static u32 | ||
679 | fore200e_sba_dma_map(struct fore200e* fore200e, void* virt_addr, int size, int direction) | ||
680 | { | 676 | { |
681 | struct sbus_dev *sdev = fore200e->bus_dev; | 677 | struct of_device *op = fore200e->bus_dev; |
682 | struct device *dev = &sdev->ofdev.dev; | 678 | u32 dma_addr; |
683 | u32 dma_addr = dma_map_single(dev, virt_addr, size, direction); | ||
684 | 679 | ||
685 | DPRINTK(3, "SBUS DVMA mapping: virt_addr = 0x%p, size = %d, direction = %d --> dma_addr = 0x%08x\n", | 680 | dma_addr = dma_map_single(&op->dev, virt_addr, size, direction); |
686 | virt_addr, size, direction, dma_addr); | 681 | |
682 | DPRINTK(3, "SBUS DVMA mapping: virt_addr = 0x%p, size = %d, direction = %d --> dma_addr = 0x%08x\n", | ||
683 | virt_addr, size, direction, dma_addr); | ||
687 | 684 | ||
688 | return dma_addr; | 685 | return dma_addr; |
689 | } | 686 | } |
690 | 687 | ||
691 | 688 | static void fore200e_sba_dma_unmap(struct fore200e *fore200e, u32 dma_addr, int size, int direction) | |
692 | static void | ||
693 | fore200e_sba_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size, int direction) | ||
694 | { | 689 | { |
695 | struct sbus_dev *sdev = fore200e->bus_dev; | 690 | struct of_device *op = fore200e->bus_dev; |
696 | struct device *dev = &sdev->ofdev.dev; | ||
697 | 691 | ||
698 | DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d,\n", | 692 | DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d,\n", |
699 | dma_addr, size, direction); | 693 | dma_addr, size, direction); |
700 | 694 | ||
701 | dma_unmap_single(dev, dma_addr, size, direction); | 695 | dma_unmap_single(&op->dev, dma_addr, size, direction); |
702 | } | 696 | } |
703 | 697 | ||
704 | 698 | static void fore200e_sba_dma_sync_for_cpu(struct fore200e *fore200e, u32 dma_addr, int size, int direction) | |
705 | static void | ||
706 | fore200e_sba_dma_sync_for_cpu(struct fore200e* fore200e, u32 dma_addr, int size, int direction) | ||
707 | { | 699 | { |
708 | struct sbus_dev *sdev = fore200e->bus_dev; | 700 | struct of_device *op = fore200e->bus_dev; |
709 | struct device *dev = &sdev->ofdev.dev; | ||
710 | 701 | ||
711 | DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); | 702 | DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); |
712 | 703 | ||
713 | dma_sync_single_for_cpu(dev, dma_addr, size, direction); | 704 | dma_sync_single_for_cpu(&op->dev, dma_addr, size, direction); |
714 | } | 705 | } |
715 | 706 | ||
716 | static void | 707 | static void fore200e_sba_dma_sync_for_device(struct fore200e *fore200e, u32 dma_addr, int size, int direction) |
717 | fore200e_sba_dma_sync_for_device(struct fore200e* fore200e, u32 dma_addr, int size, int direction) | ||
718 | { | 708 | { |
719 | struct sbus_dev *sdev = fore200e->bus_dev; | 709 | struct of_device *op = fore200e->bus_dev; |
720 | struct device *dev = &sdev->ofdev.dev; | ||
721 | 710 | ||
722 | DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); | 711 | DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); |
723 | 712 | ||
724 | dma_sync_single_for_device(dev, dma_addr, size, direction); | 713 | dma_sync_single_for_device(&op->dev, dma_addr, size, direction); |
725 | } | 714 | } |
726 | 715 | ||
727 | 716 | /* Allocate a DVMA consistent chunk of memory intended to act as a communication mechanism | |
728 | /* allocate a DVMA consistent chunk of memory intended to act as a communication mechanism | 717 | * (to hold descriptors, status, queues, etc.) shared by the driver and the adapter. |
729 | (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */ | 718 | */ |
730 | 719 | static int fore200e_sba_dma_chunk_alloc(struct fore200e *fore200e, struct chunk *chunk, | |
731 | static int | 720 | int size, int nbr, int alignment) |
732 | fore200e_sba_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, | ||
733 | int size, int nbr, int alignment) | ||
734 | { | 721 | { |
735 | struct sbus_dev *sdev = (struct sbus_dev *) fore200e->bus_dev; | 722 | struct of_device *op = fore200e->bus_dev; |
736 | struct device *dev = &sdev->ofdev.dev; | ||
737 | 723 | ||
738 | chunk->alloc_size = chunk->align_size = size * nbr; | 724 | chunk->alloc_size = chunk->align_size = size * nbr; |
739 | 725 | ||
740 | /* returned chunks are page-aligned */ | 726 | /* returned chunks are page-aligned */ |
741 | chunk->alloc_addr = dma_alloc_coherent(dev, chunk->alloc_size, | 727 | chunk->alloc_addr = dma_alloc_coherent(&op->dev, chunk->alloc_size, |
742 | &chunk->dma_addr, GFP_ATOMIC); | 728 | &chunk->dma_addr, GFP_ATOMIC); |
743 | 729 | ||
744 | if ((chunk->alloc_addr == NULL) || (chunk->dma_addr == 0)) | 730 | if ((chunk->alloc_addr == NULL) || (chunk->dma_addr == 0)) |
745 | return -ENOMEM; | 731 | return -ENOMEM; |
746 | 732 | ||
747 | chunk->align_addr = chunk->alloc_addr; | 733 | chunk->align_addr = chunk->alloc_addr; |
748 | 734 | ||
749 | return 0; | 735 | return 0; |
750 | } | 736 | } |
751 | 737 | ||
752 | |||
753 | /* free a DVMA consistent chunk of memory */ | 738 | /* free a DVMA consistent chunk of memory */ |
754 | 739 | static void fore200e_sba_dma_chunk_free(struct fore200e *fore200e, struct chunk *chunk) | |
755 | static void | ||
756 | fore200e_sba_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk) | ||
757 | { | 740 | { |
758 | struct sbus_dev *sdev = (struct sbus_dev *) fore200e->bus_dev; | 741 | struct of_device *op = fore200e->bus_dev; |
759 | struct device *dev = &sdev->ofdev.dev; | ||
760 | 742 | ||
761 | dma_free_coherent(dev, chunk->alloc_size, | 743 | dma_free_coherent(&op->dev, chunk->alloc_size, |
762 | chunk->alloc_addr, chunk->dma_addr); | 744 | chunk->alloc_addr, chunk->dma_addr); |
763 | } | 745 | } |
764 | 746 | ||
765 | 747 | static void fore200e_sba_irq_enable(struct fore200e *fore200e) | |
766 | static void | ||
767 | fore200e_sba_irq_enable(struct fore200e* fore200e) | ||
768 | { | 748 | { |
769 | u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY; | 749 | u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY; |
770 | fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr); | 750 | fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr); |
771 | } | 751 | } |
772 | 752 | ||
773 | 753 | static int fore200e_sba_irq_check(struct fore200e *fore200e) | |
774 | static int | ||
775 | fore200e_sba_irq_check(struct fore200e* fore200e) | ||
776 | { | 754 | { |
777 | return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ; | 755 | return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ; |
778 | } | 756 | } |
779 | 757 | ||
780 | 758 | static void fore200e_sba_irq_ack(struct fore200e *fore200e) | |
781 | static void | ||
782 | fore200e_sba_irq_ack(struct fore200e* fore200e) | ||
783 | { | 759 | { |
784 | u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY; | 760 | u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY; |
785 | fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr); | 761 | fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr); |
786 | } | 762 | } |
787 | 763 | ||
788 | 764 | static void fore200e_sba_reset(struct fore200e *fore200e) | |
789 | static void | ||
790 | fore200e_sba_reset(struct fore200e* fore200e) | ||
791 | { | 765 | { |
792 | fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr); | 766 | fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr); |
793 | fore200e_spin(10); | 767 | fore200e_spin(10); |
794 | fore200e->bus->write(0, fore200e->regs.sba.hcr); | 768 | fore200e->bus->write(0, fore200e->regs.sba.hcr); |
795 | } | 769 | } |
796 | 770 | ||
797 | 771 | static int __init fore200e_sba_map(struct fore200e *fore200e) | |
798 | static int __init | ||
799 | fore200e_sba_map(struct fore200e* fore200e) | ||
800 | { | 772 | { |
801 | struct sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev; | 773 | struct of_device *op = fore200e->bus_dev; |
802 | unsigned int bursts; | 774 | unsigned int bursts; |
803 | 775 | ||
804 | /* gain access to the SBA specific registers */ | 776 | /* gain access to the SBA specific registers */ |
805 | fore200e->regs.sba.hcr = sbus_ioremap(&sbus_dev->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR"); | 777 | fore200e->regs.sba.hcr = of_ioremap(&op->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR"); |
806 | fore200e->regs.sba.bsr = sbus_ioremap(&sbus_dev->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR"); | 778 | fore200e->regs.sba.bsr = of_ioremap(&op->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR"); |
807 | fore200e->regs.sba.isr = sbus_ioremap(&sbus_dev->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR"); | 779 | fore200e->regs.sba.isr = of_ioremap(&op->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR"); |
808 | fore200e->virt_base = sbus_ioremap(&sbus_dev->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM"); | 780 | fore200e->virt_base = of_ioremap(&op->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM"); |
809 | 781 | ||
810 | if (fore200e->virt_base == NULL) { | 782 | if (!fore200e->virt_base) { |
811 | printk(FORE200E "unable to map RAM of device %s\n", fore200e->name); | 783 | printk(FORE200E "unable to map RAM of device %s\n", fore200e->name); |
812 | return -EFAULT; | 784 | return -EFAULT; |
813 | } | 785 | } |
814 | 786 | ||
815 | DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base); | 787 | DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base); |
816 | 788 | ||
817 | fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */ | 789 | fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */ |
818 | 790 | ||
819 | /* get the supported DVMA burst sizes */ | 791 | /* get the supported DVMA burst sizes */ |
820 | bursts = prom_getintdefault(sbus_dev->bus->prom_node, "burst-sizes", 0x00); | 792 | bursts = of_getintprop_default(op->node->parent, "burst-sizes", 0x00); |
821 | 793 | ||
822 | if (sbus_can_dma_64bit()) | 794 | if (sbus_can_dma_64bit()) |
823 | sbus_set_sbus64(&sbus_dev->ofdev.dev, bursts); | 795 | sbus_set_sbus64(&op->dev, bursts); |
824 | 796 | ||
825 | fore200e->state = FORE200E_STATE_MAP; | 797 | fore200e->state = FORE200E_STATE_MAP; |
826 | return 0; | 798 | return 0; |
827 | } | 799 | } |
828 | 800 | ||
829 | 801 | static void fore200e_sba_unmap(struct fore200e *fore200e) | |
830 | static void | ||
831 | fore200e_sba_unmap(struct fore200e* fore200e) | ||
832 | { | 802 | { |
833 | sbus_iounmap(fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH); | 803 | struct of_device *op = fore200e->bus_dev; |
834 | sbus_iounmap(fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH); | ||
835 | sbus_iounmap(fore200e->regs.sba.isr, SBA200E_ISR_LENGTH); | ||
836 | sbus_iounmap(fore200e->virt_base, SBA200E_RAM_LENGTH); | ||
837 | } | ||
838 | 804 | ||
805 | of_iounmap(&op->resource[0], fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH); | ||
806 | of_iounmap(&op->resource[1], fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH); | ||
807 | of_iounmap(&op->resource[2], fore200e->regs.sba.isr, SBA200E_ISR_LENGTH); | ||
808 | of_iounmap(&op->resource[3], fore200e->virt_base, SBA200E_RAM_LENGTH); | ||
809 | } | ||
839 | 810 | ||
840 | static int __init | 811 | static int __init fore200e_sba_configure(struct fore200e *fore200e) |
841 | fore200e_sba_configure(struct fore200e* fore200e) | ||
842 | { | 812 | { |
843 | fore200e->state = FORE200E_STATE_CONFIGURE; | 813 | fore200e->state = FORE200E_STATE_CONFIGURE; |
844 | return 0; | 814 | return 0; |
845 | } | 815 | } |
846 | 816 | ||
847 | 817 | static int __init fore200e_sba_prom_read(struct fore200e *fore200e, struct prom_data *prom) | |
848 | static struct fore200e* __init | ||
849 | fore200e_sba_detect(const struct fore200e_bus* bus, int index) | ||
850 | { | 818 | { |
851 | struct fore200e* fore200e; | 819 | struct of_device *op = fore200e->bus_dev; |
852 | struct sbus_bus* sbus_bus; | 820 | const u8 *prop; |
853 | struct sbus_dev* sbus_dev = NULL; | 821 | int len; |
854 | |||
855 | unsigned int count = 0; | ||
856 | |||
857 | for_each_sbus (sbus_bus) { | ||
858 | for_each_sbusdev (sbus_dev, sbus_bus) { | ||
859 | if (strcmp(sbus_dev->prom_name, SBA200E_PROM_NAME) == 0) { | ||
860 | if (count >= index) | ||
861 | goto found; | ||
862 | count++; | ||
863 | } | ||
864 | } | ||
865 | } | ||
866 | return NULL; | ||
867 | |||
868 | found: | ||
869 | if (sbus_dev->num_registers != 4) { | ||
870 | printk(FORE200E "this %s device has %d instead of 4 registers\n", | ||
871 | bus->model_name, sbus_dev->num_registers); | ||
872 | return NULL; | ||
873 | } | ||
874 | |||
875 | fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL); | ||
876 | if (fore200e == NULL) | ||
877 | return NULL; | ||
878 | 822 | ||
879 | fore200e->bus = bus; | 823 | prop = of_get_property(op->node, "madaddrlo2", &len); |
880 | fore200e->bus_dev = sbus_dev; | 824 | if (!prop) |
881 | fore200e->irq = sbus_dev->irqs[ 0 ]; | 825 | return -ENODEV; |
826 | memcpy(&prom->mac_addr[4], prop, 4); | ||
882 | 827 | ||
883 | fore200e->phys_base = (unsigned long)sbus_dev; | 828 | prop = of_get_property(op->node, "madaddrhi4", &len); |
829 | if (!prop) | ||
830 | return -ENODEV; | ||
831 | memcpy(&prom->mac_addr[2], prop, 4); | ||
884 | 832 | ||
885 | sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1); | 833 | prom->serial_number = of_getintprop_default(op->node, "serialnumber", 0); |
834 | prom->hw_revision = of_getintprop_default(op->node, "promversion", 0); | ||
886 | 835 | ||
887 | return fore200e; | 836 | return 0; |
888 | } | 837 | } |
889 | 838 | ||
890 | 839 | static int fore200e_sba_proc_read(struct fore200e *fore200e, char *page) | |
891 | static int __init | ||
892 | fore200e_sba_prom_read(struct fore200e* fore200e, struct prom_data* prom) | ||
893 | { | 840 | { |
894 | struct sbus_dev* sbus_dev = (struct sbus_dev*) fore200e->bus_dev; | 841 | struct of_device *op = fore200e->bus_dev; |
895 | int len; | 842 | const struct linux_prom_registers *regs; |
896 | |||
897 | len = prom_getproperty(sbus_dev->prom_node, "macaddrlo2", &prom->mac_addr[ 4 ], 4); | ||
898 | if (len < 0) | ||
899 | return -EBUSY; | ||
900 | |||
901 | len = prom_getproperty(sbus_dev->prom_node, "macaddrhi4", &prom->mac_addr[ 2 ], 4); | ||
902 | if (len < 0) | ||
903 | return -EBUSY; | ||
904 | |||
905 | prom_getproperty(sbus_dev->prom_node, "serialnumber", | ||
906 | (char*)&prom->serial_number, sizeof(prom->serial_number)); | ||
907 | |||
908 | prom_getproperty(sbus_dev->prom_node, "promversion", | ||
909 | (char*)&prom->hw_revision, sizeof(prom->hw_revision)); | ||
910 | |||
911 | return 0; | ||
912 | } | ||
913 | 843 | ||
844 | regs = of_get_property(op->node, "reg", NULL); | ||
914 | 845 | ||
915 | static int | 846 | return sprintf(page, " SBUS slot/device:\t\t%d/'%s'\n", |
916 | fore200e_sba_proc_read(struct fore200e* fore200e, char *page) | 847 | (regs ? regs->which_io : 0), op->node->name); |
917 | { | ||
918 | struct sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev; | ||
919 | |||
920 | return sprintf(page, " SBUS slot/device:\t\t%d/'%s'\n", sbus_dev->slot, sbus_dev->prom_name); | ||
921 | } | 848 | } |
922 | #endif /* CONFIG_SBUS */ | 849 | #endif /* CONFIG_SBUS */ |
923 | 850 | ||
@@ -2586,7 +2513,7 @@ fore200e_load_and_start_fw(struct fore200e* fore200e) | |||
2586 | device = &((struct pci_dev *) fore200e->bus_dev)->dev; | 2513 | device = &((struct pci_dev *) fore200e->bus_dev)->dev; |
2587 | #ifdef CONFIG_SBUS | 2514 | #ifdef CONFIG_SBUS |
2588 | else if (strcmp(fore200e->bus->model_name, "SBA-200E") == 0) | 2515 | else if (strcmp(fore200e->bus->model_name, "SBA-200E") == 0) |
2589 | device = &((struct sbus_dev *) fore200e->bus_dev)->ofdev.dev; | 2516 | device = &((struct of_device *) fore200e->bus_dev)->dev; |
2590 | #endif | 2517 | #endif |
2591 | else | 2518 | else |
2592 | return err; | 2519 | return err; |
@@ -2715,6 +2642,66 @@ fore200e_init(struct fore200e* fore200e) | |||
2715 | return 0; | 2642 | return 0; |
2716 | } | 2643 | } |
2717 | 2644 | ||
2645 | #ifdef CONFIG_SBUS | ||
2646 | static int __devinit fore200e_sba_probe(struct of_device *op, | ||
2647 | const struct of_device_id *match) | ||
2648 | { | ||
2649 | const struct fore200e_bus *bus = match->data; | ||
2650 | struct fore200e *fore200e; | ||
2651 | static int index = 0; | ||
2652 | int err; | ||
2653 | |||
2654 | fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL); | ||
2655 | if (!fore200e) | ||
2656 | return -ENOMEM; | ||
2657 | |||
2658 | fore200e->bus = bus; | ||
2659 | fore200e->bus_dev = op; | ||
2660 | fore200e->irq = op->irqs[0]; | ||
2661 | fore200e->phys_base = op->resource[0].start; | ||
2662 | |||
2663 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); | ||
2664 | |||
2665 | err = fore200e_init(fore200e); | ||
2666 | if (err < 0) { | ||
2667 | fore200e_shutdown(fore200e); | ||
2668 | kfree(fore200e); | ||
2669 | return err; | ||
2670 | } | ||
2671 | |||
2672 | index++; | ||
2673 | dev_set_drvdata(&op->dev, fore200e); | ||
2674 | |||
2675 | return 0; | ||
2676 | } | ||
2677 | |||
2678 | static int __devexit fore200e_sba_remove(struct of_device *op) | ||
2679 | { | ||
2680 | struct fore200e *fore200e = dev_get_drvdata(&op->dev); | ||
2681 | |||
2682 | fore200e_shutdown(fore200e); | ||
2683 | kfree(fore200e); | ||
2684 | |||
2685 | return 0; | ||
2686 | } | ||
2687 | |||
2688 | static struct of_device_id fore200e_sba_match[] = { | ||
2689 | { | ||
2690 | .name = SBA200E_PROM_NAME, | ||
2691 | .data = (void *) &fore200e_bus[1], | ||
2692 | }, | ||
2693 | {}, | ||
2694 | }; | ||
2695 | MODULE_DEVICE_TABLE(of, fore200e_sba_match); | ||
2696 | |||
2697 | static struct of_platform_driver fore200e_sba_driver = { | ||
2698 | .name = "fore_200e", | ||
2699 | .match_table = fore200e_sba_match, | ||
2700 | .probe = fore200e_sba_probe, | ||
2701 | .remove = __devexit_p(fore200e_sba_remove), | ||
2702 | }; | ||
2703 | #endif | ||
2704 | |||
2718 | #ifdef CONFIG_PCI | 2705 | #ifdef CONFIG_PCI |
2719 | static int __devinit | 2706 | static int __devinit |
2720 | fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent) | 2707 | fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent) |
@@ -2798,67 +2785,40 @@ static struct pci_driver fore200e_pca_driver = { | |||
2798 | }; | 2785 | }; |
2799 | #endif | 2786 | #endif |
2800 | 2787 | ||
2801 | 2788 | static int __init fore200e_module_init(void) | |
2802 | static int __init | ||
2803 | fore200e_module_init(void) | ||
2804 | { | 2789 | { |
2805 | const struct fore200e_bus* bus; | 2790 | int err; |
2806 | struct fore200e* fore200e; | ||
2807 | int index; | ||
2808 | 2791 | ||
2809 | printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n"); | 2792 | printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n"); |
2810 | 2793 | ||
2811 | /* for each configured bus interface */ | 2794 | #ifdef CONFIG_SBUS |
2812 | for (bus = fore200e_bus; bus->model_name; bus++) { | 2795 | err = of_register_driver(&fore200e_sba_driver, &of_bus_type); |
2813 | 2796 | if (err) | |
2814 | /* detect all boards present on that bus */ | 2797 | return err; |
2815 | for (index = 0; bus->detect && (fore200e = bus->detect(bus, index)); index++) { | 2798 | #endif |
2816 | |||
2817 | printk(FORE200E "device %s found at 0x%lx, IRQ %s\n", | ||
2818 | fore200e->bus->model_name, | ||
2819 | fore200e->phys_base, fore200e_irq_itoa(fore200e->irq)); | ||
2820 | |||
2821 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); | ||
2822 | |||
2823 | if (fore200e_init(fore200e) < 0) { | ||
2824 | |||
2825 | fore200e_shutdown(fore200e); | ||
2826 | break; | ||
2827 | } | ||
2828 | |||
2829 | list_add(&fore200e->entry, &fore200e_boards); | ||
2830 | } | ||
2831 | } | ||
2832 | 2799 | ||
2833 | #ifdef CONFIG_PCI | 2800 | #ifdef CONFIG_PCI |
2834 | if (!pci_register_driver(&fore200e_pca_driver)) | 2801 | err = pci_register_driver(&fore200e_pca_driver); |
2835 | return 0; | ||
2836 | #endif | 2802 | #endif |
2837 | 2803 | ||
2838 | if (!list_empty(&fore200e_boards)) | 2804 | #ifdef CONFIG_SBUS |
2839 | return 0; | 2805 | if (err) |
2806 | of_unregister_driver(&fore200e_sba_driver); | ||
2807 | #endif | ||
2840 | 2808 | ||
2841 | return -ENODEV; | 2809 | return err; |
2842 | } | 2810 | } |
2843 | 2811 | ||
2844 | 2812 | static void __exit fore200e_module_cleanup(void) | |
2845 | static void __exit | ||
2846 | fore200e_module_cleanup(void) | ||
2847 | { | 2813 | { |
2848 | struct fore200e *fore200e, *next; | ||
2849 | |||
2850 | #ifdef CONFIG_PCI | 2814 | #ifdef CONFIG_PCI |
2851 | pci_unregister_driver(&fore200e_pca_driver); | 2815 | pci_unregister_driver(&fore200e_pca_driver); |
2816 | #endif | ||
2817 | #ifdef CONFIG_SBUS | ||
2818 | of_unregister_driver(&fore200e_sba_driver); | ||
2852 | #endif | 2819 | #endif |
2853 | |||
2854 | list_for_each_entry_safe(fore200e, next, &fore200e_boards, entry) { | ||
2855 | fore200e_shutdown(fore200e); | ||
2856 | kfree(fore200e); | ||
2857 | } | ||
2858 | DPRINTK(1, "module being removed\n"); | ||
2859 | } | 2820 | } |
2860 | 2821 | ||
2861 | |||
2862 | static int | 2822 | static int |
2863 | fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page) | 2823 | fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page) |
2864 | { | 2824 | { |
@@ -3177,7 +3137,6 @@ static const struct fore200e_bus fore200e_bus[] = { | |||
3177 | fore200e_pca_dma_sync_for_device, | 3137 | fore200e_pca_dma_sync_for_device, |
3178 | fore200e_pca_dma_chunk_alloc, | 3138 | fore200e_pca_dma_chunk_alloc, |
3179 | fore200e_pca_dma_chunk_free, | 3139 | fore200e_pca_dma_chunk_free, |
3180 | NULL, | ||
3181 | fore200e_pca_configure, | 3140 | fore200e_pca_configure, |
3182 | fore200e_pca_map, | 3141 | fore200e_pca_map, |
3183 | fore200e_pca_reset, | 3142 | fore200e_pca_reset, |
@@ -3199,7 +3158,6 @@ static const struct fore200e_bus fore200e_bus[] = { | |||
3199 | fore200e_sba_dma_sync_for_device, | 3158 | fore200e_sba_dma_sync_for_device, |
3200 | fore200e_sba_dma_chunk_alloc, | 3159 | fore200e_sba_dma_chunk_alloc, |
3201 | fore200e_sba_dma_chunk_free, | 3160 | fore200e_sba_dma_chunk_free, |
3202 | fore200e_sba_detect, | ||
3203 | fore200e_sba_configure, | 3161 | fore200e_sba_configure, |
3204 | fore200e_sba_map, | 3162 | fore200e_sba_map, |
3205 | fore200e_sba_reset, | 3163 | fore200e_sba_reset, |
diff --git a/drivers/atm/fore200e.h b/drivers/atm/fore200e.h index 5c6e7adcb19c..7f97c09aaea5 100644 --- a/drivers/atm/fore200e.h +++ b/drivers/atm/fore200e.h | |||
@@ -778,9 +778,9 @@ typedef struct fore200e_pca_regs { | |||
778 | /* SBA-200E registers */ | 778 | /* SBA-200E registers */ |
779 | 779 | ||
780 | typedef struct fore200e_sba_regs { | 780 | typedef struct fore200e_sba_regs { |
781 | volatile u32 __iomem *hcr; /* address of host control register */ | 781 | u32 __iomem *hcr; /* address of host control register */ |
782 | volatile u32 __iomem *bsr; /* address of burst transfer size register */ | 782 | u32 __iomem *bsr; /* address of burst transfer size register */ |
783 | volatile u32 __iomem *isr; /* address of interrupt level selection register */ | 783 | u32 __iomem *isr; /* address of interrupt level selection register */ |
784 | } fore200e_sba_regs_t; | 784 | } fore200e_sba_regs_t; |
785 | 785 | ||
786 | 786 | ||
@@ -810,7 +810,6 @@ typedef struct fore200e_bus { | |||
810 | void (*dma_sync_for_device)(struct fore200e*, u32, int, int); | 810 | void (*dma_sync_for_device)(struct fore200e*, u32, int, int); |
811 | int (*dma_chunk_alloc)(struct fore200e*, struct chunk*, int, int, int); | 811 | int (*dma_chunk_alloc)(struct fore200e*, struct chunk*, int, int, int); |
812 | void (*dma_chunk_free)(struct fore200e*, struct chunk*); | 812 | void (*dma_chunk_free)(struct fore200e*, struct chunk*); |
813 | struct fore200e* (*detect)(const struct fore200e_bus*, int); | ||
814 | int (*configure)(struct fore200e*); | 813 | int (*configure)(struct fore200e*); |
815 | int (*map)(struct fore200e*); | 814 | int (*map)(struct fore200e*); |
816 | void (*reset)(struct fore200e*); | 815 | void (*reset)(struct fore200e*); |