aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_sabre.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-30 06:14:01 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-30 06:14:01 -0400
commitedbe805b2b1044659e0727136213bdf42bd1b9d0 (patch)
tree8de4633f54048108743cbcbd071888c15617eac6 /arch/sparc64/kernel/pci_sabre.c
parentb20bfe41badcbf38512fbe1118fe2e0817098e77 (diff)
sparc64: Convert SABRE PCI controller driver into a real driver.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/pci_sabre.c')
-rw-r--r--arch/sparc64/kernel/pci_sabre.c126
1 files changed, 85 insertions, 41 deletions
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index ade5184e75d1..7cce4d8f4aae 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -16,13 +16,14 @@
16#include <asm/apb.h> 16#include <asm/apb.h>
17#include <asm/iommu.h> 17#include <asm/iommu.h>
18#include <asm/irq.h> 18#include <asm/irq.h>
19#include <asm/smp.h>
20#include <asm/oplib.h>
21#include <asm/prom.h> 19#include <asm/prom.h>
22 20
23#include "pci_impl.h" 21#include "pci_impl.h"
24#include "iommu_common.h" 22#include "iommu_common.h"
25 23
24#define DRIVER_NAME "sabre"
25#define PFX DRIVER_NAME ": "
26
26/* All SABRE registers are 64-bits. The following accessor 27/* All SABRE registers are 64-bits. The following accessor
27 * routines are how they are accessed. The REG parameter 28 * routines are how they are accessed. The REG parameter
28 * is a physical address. 29 * is a physical address.
@@ -656,8 +657,8 @@ static void __init sabre_scan_bus(struct pci_pbm_info *pbm)
656 * to live at bus 0. 657 * to live at bus 0.
657 */ 658 */
658 if (once != 0) { 659 if (once != 0) {
659 prom_printf("SABRE: Multiple controllers unsupported.\n"); 660 printk(KERN_ERR PFX "Multiple controllers unsupported.\n");
660 prom_halt(); 661 return;
661 } 662 }
662 once++; 663 once++;
663 664
@@ -705,8 +706,10 @@ static int sabre_iommu_init(struct pci_pbm_info *pbm,
705 */ 706 */
706 err = iommu_table_init(iommu, tsbsize * 1024 * 8, 707 err = iommu_table_init(iommu, tsbsize * 1024 * 8,
707 dvma_offset, dma_mask, pbm->numa_node); 708 dvma_offset, dma_mask, pbm->numa_node);
708 if (err) 709 if (err) {
710 printk(KERN_ERR PFX "iommu_table_init() failed\n");
709 return err; 711 return err;
712 }
710 713
711 sabre_write(pbm->controller_regs + SABRE_IOMMU_TSBBASE, 714 sabre_write(pbm->controller_regs + SABRE_IOMMU_TSBBASE,
712 __pa(iommu->page_table)); 715 __pa(iommu->page_table));
@@ -722,9 +725,8 @@ static int sabre_iommu_init(struct pci_pbm_info *pbm,
722 control |= SABRE_IOMMU_TSBSZ_128K; 725 control |= SABRE_IOMMU_TSBSZ_128K;
723 break; 726 break;
724 default: 727 default:
725 prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize); 728 printk(KERN_ERR PFX "Illegal TSB size %d\n", tsbsize);
726 prom_halt(); 729 return -EINVAL;
727 break;
728 } 730 }
729 sabre_write(pbm->controller_regs + SABRE_IOMMU_CONTROL, control); 731 sabre_write(pbm->controller_regs + SABRE_IOMMU_CONTROL, control);
730 732
@@ -739,7 +741,6 @@ static void __init sabre_pbm_init(struct pci_controller_info *p,
739 741
740 pbm->numa_node = -1; 742 pbm->numa_node = -1;
741 743
742 pbm->scan_bus = sabre_scan_bus;
743 pbm->pci_ops = &sun4u_pci_ops; 744 pbm->pci_ops = &sun4u_pci_ops;
744 pbm->config_space_reg_bits = 8; 745 pbm->config_space_reg_bits = 8;
745 746
@@ -751,46 +752,49 @@ static void __init sabre_pbm_init(struct pci_controller_info *p,
751 pci_get_pbm_props(pbm); 752 pci_get_pbm_props(pbm);
752 753
753 pci_determine_mem_io_space(pbm); 754 pci_determine_mem_io_space(pbm);
755
756 sabre_scan_bus(pbm);
754} 757}
755 758
756void __init sabre_init(struct device_node *dp, char *model_name) 759static int __devinit sabre_probe(struct of_device *op,
760 const struct of_device_id *match)
757{ 761{
758 const struct linux_prom64_registers *pr_regs; 762 const struct linux_prom64_registers *pr_regs;
763 struct device_node *dp = op->node;
759 struct pci_controller_info *p; 764 struct pci_controller_info *p;
760 struct pci_pbm_info *pbm; 765 struct pci_pbm_info *pbm;
766 u32 upa_portid, dma_mask;
761 struct iommu *iommu; 767 struct iommu *iommu;
762 int tsbsize; 768 int tsbsize, err;
763 const u32 *vdma; 769 const u32 *vdma;
764 u32 upa_portid, dma_mask;
765 u64 clear_irq; 770 u64 clear_irq;
766 771
767 hummingbird_p = 0; 772 hummingbird_p = (match->data != NULL);
768 if (!strcmp(model_name, "pci108e,a001")) 773 if (!hummingbird_p) {
769 hummingbird_p = 1; 774 struct device_node *cpu_dp;
770 else if (!strcmp(model_name, "SUNW,sabre")) { 775
771 const char *compat = of_get_property(dp, "compatible", NULL); 776 /* Of course, Sun has to encode things a thousand
772 if (compat && !strcmp(compat, "pci108e,a001")) 777 * different ways, inconsistently.
773 hummingbird_p = 1; 778 */
774 if (!hummingbird_p) { 779 for_each_node_by_type(cpu_dp, "cpu") {
775 struct device_node *dp; 780 if (!strcmp(cpu_dp->name, "SUNW,UltraSPARC-IIe"))
776 781 hummingbird_p = 1;
777 /* Of course, Sun has to encode things a thousand
778 * different ways, inconsistently.
779 */
780 for_each_node_by_type(dp, "cpu") {
781 if (!strcmp(dp->name, "SUNW,UltraSPARC-IIe"))
782 hummingbird_p = 1;
783 }
784 } 782 }
785 } 783 }
786 784
785 err = -ENOMEM;
787 p = kzalloc(sizeof(*p), GFP_ATOMIC); 786 p = kzalloc(sizeof(*p), GFP_ATOMIC);
788 if (!p) 787 if (!p) {
789 goto fatal_memory_error; 788 printk(KERN_ERR PFX "Cannot allocate controller info.\n");
789 goto out_free;
790 }
790 791
791 iommu = kzalloc(sizeof(*iommu), GFP_ATOMIC); 792 iommu = kzalloc(sizeof(*iommu), GFP_ATOMIC);
792 if (!iommu) 793 if (!iommu) {
793 goto fatal_memory_error; 794 printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n");
795 goto out_free;
796 }
797
794 pbm = &p->pbm_A; 798 pbm = &p->pbm_A;
795 pbm->iommu = iommu; 799 pbm->iommu = iommu;
796 800
@@ -806,6 +810,11 @@ void __init sabre_init(struct device_node *dp, char *model_name)
806 */ 810 */
807 811
808 pr_regs = of_get_property(dp, "reg", NULL); 812 pr_regs = of_get_property(dp, "reg", NULL);
813 err = -ENODEV;
814 if (!pr_regs) {
815 printk(KERN_ERR PFX "No reg property\n");
816 goto out_free;
817 }
809 818
810 /* 819 /*
811 * First REG in property is base of entire SABRE register space. 820 * First REG in property is base of entire SABRE register space.
@@ -832,6 +841,10 @@ void __init sabre_init(struct device_node *dp, char *model_name)
832 (pbm->controller_regs + SABRE_CONFIGSPACE); 841 (pbm->controller_regs + SABRE_CONFIGSPACE);
833 842
834 vdma = of_get_property(dp, "virtual-dma", NULL); 843 vdma = of_get_property(dp, "virtual-dma", NULL);
844 if (!vdma) {
845 printk(KERN_ERR PFX "No virtual-dma property\n");
846 goto out_free;
847 }
835 848
836 dma_mask = vdma[0]; 849 dma_mask = vdma[0];
837 switch(vdma[1]) { 850 switch(vdma[1]) {
@@ -849,20 +862,51 @@ void __init sabre_init(struct device_node *dp, char *model_name)
849 tsbsize = 128; 862 tsbsize = 128;
850 break; 863 break;
851 default: 864 default:
852 prom_printf("SABRE: strange virtual-dma size.\n"); 865 printk(KERN_ERR PFX "Strange virtual-dma size.\n");
853 prom_halt(); 866 goto out_free;
854 } 867 }
855 868
856 if (sabre_iommu_init(pbm, tsbsize, vdma[0], dma_mask)) 869 err = sabre_iommu_init(pbm, tsbsize, vdma[0], dma_mask);
857 goto fatal_memory_error; 870 if (err)
871 goto out_free;
858 872
859 /* 873 /*
860 * Look for APB underneath. 874 * Look for APB underneath.
861 */ 875 */
862 sabre_pbm_init(p, pbm, dp); 876 sabre_pbm_init(p, pbm, dp);
863 return; 877 return 0;
864 878
865fatal_memory_error: 879out_free:
866 prom_printf("SABRE: Fatal memory allocation error.\n"); 880 if (p) {
867 prom_halt(); 881 if (p->pbm_A.iommu)
882 kfree(p->pbm_A.iommu);
883 kfree(p);
884 }
885 return err;
868} 886}
887
888static struct of_device_id sabre_match[] = {
889 {
890 .name = "pci",
891 .compatible = "pci108e,a001",
892 .data = (void *) 1,
893 },
894 {
895 .name = "pci",
896 .compatible = "pci108e,a000",
897 },
898 {},
899};
900
901static struct of_platform_driver sabre_driver = {
902 .name = DRIVER_NAME,
903 .match_table = sabre_match,
904 .probe = sabre_probe,
905};
906
907static int __init sabre_init(void)
908{
909 return of_register_driver(&sabre_driver, &of_bus_type);
910}
911
912subsys_initcall(sabre_init);