aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_psycho.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-27 12:29:04 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-27 12:29:04 -0400
commit0278ef8b484a71917bd4f03a763285cdaac10954 (patch)
tree8f6f7bf2e2a85b4643dfe3d0475811ce858fb4fc /arch/sparc64/kernel/pci_psycho.c
parent15c54033964a943de7b0763efd3bd0ede7326395 (diff)
parentcd9ad58d4061494e7fdd70ded7bcf2418daf356a (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6: (67 commits) [SCSI] SUNESP: Complete driver rewrite to version 2.0 [SPARC64]: Convert PCI over to generic struct iommu/strbuf. [SPARC]: device_node name constification fallout [SPARC64]: Convert SBUS over to generic iommu/strbuf structs. [SPARC64]: Add generic iommu and strbuf structs to iommu.h [SPARC64]: Consolidate {sbus,pci}_iommu_arena. [SPARC]: Make device_node name and type const [SPARC64]: constify some paramaters of OF routines [TIGON3]: of_get_property() returns const. [SPARC64]: Fix PCI rework to adhere to of_get_property() const return. [SPARC64]: Document and fix calculation of pages_avail. [SPARC64]: Make sure pbm->prom_node is setup easly enough in psycho.c [SPARC64]: Use bootmem_bootmap_pages() in choose_bootmap_pfn(). [SPARC64]: Add proper header file extern for cmdline_memory_size. [SPARC64]: Kill sparc_ultra_dump_{i,d}tlb() [SPARC64]: Use DECLARE_BITMAP and BITS_TO_LONGS in mm/init.c [SPARC64]: Give move verbose show_mem() output just like i386. [SPARC64]: Mark show_mem() printk's with KERN_INFO. [SPARC64]: Kill kvaddr_to_phys() and friends. [SPARC64]: Privatize sun4u_get_pte() and fix name. ...
Diffstat (limited to 'arch/sparc64/kernel/pci_psycho.c')
-rw-r--r--arch/sparc64/kernel/pci_psycho.c154
1 files changed, 18 insertions, 136 deletions
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index fda5db223d96..253d40ec2245 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -1,7 +1,6 @@
1/* $Id: pci_psycho.c,v 1.33 2002/02/01 00:58:33 davem Exp $ 1/* pci_psycho.c: PSYCHO/U2P specific PCI controller support.
2 * pci_psycho.c: PSYCHO/U2P specific PCI controller support.
3 * 2 *
4 * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) 3 * Copyright (C) 1997, 1998, 1999, 2007 David S. Miller (davem@davemloft.net)
5 * Copyright (C) 1998, 1999 Eddie C. Dost (ecd@skynet.be) 4 * Copyright (C) 1998, 1999 Eddie C. Dost (ecd@skynet.be)
6 * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com) 5 * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com)
7 */ 6 */
@@ -119,6 +118,10 @@ static int psycho_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
119 u16 tmp16; 118 u16 tmp16;
120 u8 tmp8; 119 u8 tmp8;
121 120
121 if (bus_dev == pbm->pci_bus && devfn == 0x00)
122 return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
123 size, value);
124
122 switch (size) { 125 switch (size) {
123 case 1: 126 case 1:
124 *value = 0xff; 127 *value = 0xff;
@@ -172,6 +175,9 @@ static int psycho_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
172 unsigned char bus = bus_dev->number; 175 unsigned char bus = bus_dev->number;
173 u32 *addr; 176 u32 *addr;
174 177
178 if (bus_dev == pbm->pci_bus && devfn == 0x00)
179 return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
180 size, value);
175 addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where); 181 addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where);
176 if (!addr) 182 if (!addr)
177 return PCIBIOS_SUCCESSFUL; 183 return PCIBIOS_SUCCESSFUL;
@@ -263,7 +269,7 @@ static void __psycho_check_one_stc(struct pci_controller_info *p,
263 struct pci_pbm_info *pbm, 269 struct pci_pbm_info *pbm,
264 int is_pbm_a) 270 int is_pbm_a)
265{ 271{
266 struct pci_strbuf *strbuf = &pbm->stc; 272 struct strbuf *strbuf = &pbm->stc;
267 unsigned long regbase = p->pbm_A.controller_regs; 273 unsigned long regbase = p->pbm_A.controller_regs;
268 unsigned long err_base, tag_base, line_base; 274 unsigned long err_base, tag_base, line_base;
269 u64 control; 275 u64 control;
@@ -412,7 +418,7 @@ static void psycho_check_iommu_error(struct pci_controller_info *p,
412 unsigned long afar, 418 unsigned long afar,
413 enum psycho_error_type type) 419 enum psycho_error_type type)
414{ 420{
415 struct pci_iommu *iommu = p->pbm_A.iommu; 421 struct iommu *iommu = p->pbm_A.iommu;
416 unsigned long iommu_tag[16]; 422 unsigned long iommu_tag[16];
417 unsigned long iommu_data[16]; 423 unsigned long iommu_data[16];
418 unsigned long flags; 424 unsigned long flags;
@@ -895,59 +901,6 @@ static void psycho_register_error_handlers(struct pci_controller_info *p)
895} 901}
896 902
897/* PSYCHO boot time probing and initialization. */ 903/* PSYCHO boot time probing and initialization. */
898static void psycho_resource_adjust(struct pci_dev *pdev,
899 struct resource *res,
900 struct resource *root)
901{
902 res->start += root->start;
903 res->end += root->start;
904}
905
906static void psycho_base_address_update(struct pci_dev *pdev, int resource)
907{
908 struct pcidev_cookie *pcp = pdev->sysdata;
909 struct pci_pbm_info *pbm = pcp->pbm;
910 struct resource *res, *root;
911 u32 reg;
912 int where, size, is_64bit;
913
914 res = &pdev->resource[resource];
915 if (resource < 6) {
916 where = PCI_BASE_ADDRESS_0 + (resource * 4);
917 } else if (resource == PCI_ROM_RESOURCE) {
918 where = pdev->rom_base_reg;
919 } else {
920 /* Somebody might have asked allocation of a non-standard resource */
921 return;
922 }
923
924 is_64bit = 0;
925 if (res->flags & IORESOURCE_IO)
926 root = &pbm->io_space;
927 else {
928 root = &pbm->mem_space;
929 if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
930 == PCI_BASE_ADDRESS_MEM_TYPE_64)
931 is_64bit = 1;
932 }
933
934 size = res->end - res->start;
935 pci_read_config_dword(pdev, where, &reg);
936 reg = ((reg & size) |
937 (((u32)(res->start - root->start)) & ~size));
938 if (resource == PCI_ROM_RESOURCE) {
939 reg |= PCI_ROM_ADDRESS_ENABLE;
940 res->flags |= IORESOURCE_ROM_ENABLE;
941 }
942 pci_write_config_dword(pdev, where, reg);
943
944 /* This knows that the upper 32-bits of the address
945 * must be zero. Our PCI common layer enforces this.
946 */
947 if (is_64bit)
948 pci_write_config_dword(pdev, where + 4, 0);
949}
950
951static void pbm_config_busmastering(struct pci_pbm_info *pbm) 904static void pbm_config_busmastering(struct pci_pbm_info *pbm)
952{ 905{
953 u8 *addr; 906 u8 *addr;
@@ -968,28 +921,7 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm)
968static void pbm_scan_bus(struct pci_controller_info *p, 921static void pbm_scan_bus(struct pci_controller_info *p,
969 struct pci_pbm_info *pbm) 922 struct pci_pbm_info *pbm)
970{ 923{
971 struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); 924 pbm->pci_bus = pci_scan_one_pbm(pbm);
972
973 if (!cookie) {
974 prom_printf("PSYCHO: Critical allocation failure.\n");
975 prom_halt();
976 }
977
978 /* All we care about is the PBM. */
979 cookie->pbm = pbm;
980
981 pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno,
982 p->pci_ops,
983 pbm);
984 pci_fixup_host_bridge_self(pbm->pci_bus);
985 pbm->pci_bus->self->sysdata = cookie;
986
987 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
988 pci_record_assignments(pbm, pbm->pci_bus);
989 pci_assign_unassigned(pbm, pbm->pci_bus);
990 pci_fixup_irq(pbm, pbm->pci_bus);
991 pci_determine_66mhz_disposition(pbm, pbm->pci_bus);
992 pci_setup_busmastering(pbm, pbm->pci_bus);
993} 925}
994 926
995static void psycho_scan_bus(struct pci_controller_info *p) 927static void psycho_scan_bus(struct pci_controller_info *p)
@@ -1009,7 +941,7 @@ static void psycho_scan_bus(struct pci_controller_info *p)
1009 941
1010static void psycho_iommu_init(struct pci_controller_info *p) 942static void psycho_iommu_init(struct pci_controller_info *p)
1011{ 943{
1012 struct pci_iommu *iommu = p->pbm_A.iommu; 944 struct iommu *iommu = p->pbm_A.iommu;
1013 unsigned long i; 945 unsigned long i;
1014 u64 control; 946 u64 control;
1015 947
@@ -1094,19 +1026,6 @@ static void psycho_controller_hwinit(struct pci_controller_info *p)
1094 psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp); 1026 psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp);
1095} 1027}
1096 1028
1097static void pbm_register_toplevel_resources(struct pci_controller_info *p,
1098 struct pci_pbm_info *pbm)
1099{
1100 char *name = pbm->name;
1101
1102 pbm->io_space.name = pbm->mem_space.name = name;
1103
1104 request_resource(&ioport_resource, &pbm->io_space);
1105 request_resource(&iomem_resource, &pbm->mem_space);
1106 pci_register_legacy_regions(&pbm->io_space,
1107 &pbm->mem_space);
1108}
1109
1110static void psycho_pbm_strbuf_init(struct pci_controller_info *p, 1029static void psycho_pbm_strbuf_init(struct pci_controller_info *p,
1111 struct pci_pbm_info *pbm, 1030 struct pci_pbm_info *pbm,
1112 int is_pbm_a) 1031 int is_pbm_a)
@@ -1172,19 +1091,11 @@ static void psycho_pbm_init(struct pci_controller_info *p,
1172 unsigned int *busrange; 1091 unsigned int *busrange;
1173 struct property *prop; 1092 struct property *prop;
1174 struct pci_pbm_info *pbm; 1093 struct pci_pbm_info *pbm;
1175 int len;
1176 1094
1177 if (is_pbm_a) { 1095 if (is_pbm_a)
1178 pbm = &p->pbm_A; 1096 pbm = &p->pbm_A;
1179 pbm->pci_first_slot = 1; 1097 else
1180 pbm->io_space.start = pbm->controller_regs + PSYCHO_IOSPACE_A;
1181 pbm->mem_space.start = pbm->controller_regs + PSYCHO_MEMSPACE_A;
1182 } else {
1183 pbm = &p->pbm_B; 1098 pbm = &p->pbm_B;
1184 pbm->pci_first_slot = 2;
1185 pbm->io_space.start = pbm->controller_regs + PSYCHO_IOSPACE_B;
1186 pbm->mem_space.start = pbm->controller_regs + PSYCHO_MEMSPACE_B;
1187 }
1188 1099
1189 pbm->chip_type = PBM_CHIP_TYPE_PSYCHO; 1100 pbm->chip_type = PBM_CHIP_TYPE_PSYCHO;
1190 pbm->chip_version = 0; 1101 pbm->chip_version = 0;
@@ -1196,41 +1107,15 @@ static void psycho_pbm_init(struct pci_controller_info *p,
1196 if (prop) 1107 if (prop)
1197 pbm->chip_revision = *(int *) prop->value; 1108 pbm->chip_revision = *(int *) prop->value;
1198 1109
1199 pbm->io_space.end = pbm->io_space.start + PSYCHO_IOSPACE_SIZE;
1200 pbm->io_space.flags = IORESOURCE_IO;
1201 pbm->mem_space.end = pbm->mem_space.start + PSYCHO_MEMSPACE_SIZE;
1202 pbm->mem_space.flags = IORESOURCE_MEM;
1203
1204 pbm->parent = p; 1110 pbm->parent = p;
1205 pbm->prom_node = dp; 1111 pbm->prom_node = dp;
1206 pbm->name = dp->full_name; 1112 pbm->name = dp->full_name;
1207 1113
1208 pbm_register_toplevel_resources(p, pbm);
1209
1210 printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n", 1114 printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n",
1211 pbm->name, 1115 pbm->name,
1212 pbm->chip_version, pbm->chip_revision); 1116 pbm->chip_version, pbm->chip_revision);
1213 1117
1214 prop = of_find_property(dp, "ranges", &len); 1118 pci_determine_mem_io_space(pbm);
1215 if (prop) {
1216 pbm->pbm_ranges = prop->value;
1217 pbm->num_pbm_ranges =
1218 (len / sizeof(struct linux_prom_pci_ranges));
1219 } else {
1220 pbm->num_pbm_ranges = 0;
1221 }
1222
1223 prop = of_find_property(dp, "interrupt-map", &len);
1224 if (prop) {
1225 pbm->pbm_intmap = prop->value;
1226 pbm->num_pbm_intmap =
1227 (len / sizeof(struct linux_prom_pci_intmap));
1228
1229 prop = of_find_property(dp, "interrupt-map-mask", NULL);
1230 pbm->pbm_intmask = prop->value;
1231 } else {
1232 pbm->num_pbm_intmap = 0;
1233 }
1234 1119
1235 prop = of_find_property(dp, "bus-range", NULL); 1120 prop = of_find_property(dp, "bus-range", NULL);
1236 busrange = prop->value; 1121 busrange = prop->value;
@@ -1246,7 +1131,7 @@ void psycho_init(struct device_node *dp, char *model_name)
1246{ 1131{
1247 struct linux_prom64_registers *pr_regs; 1132 struct linux_prom64_registers *pr_regs;
1248 struct pci_controller_info *p; 1133 struct pci_controller_info *p;
1249 struct pci_iommu *iommu; 1134 struct iommu *iommu;
1250 struct property *prop; 1135 struct property *prop;
1251 u32 upa_portid; 1136 u32 upa_portid;
1252 int is_pbm_a; 1137 int is_pbm_a;
@@ -1269,7 +1154,7 @@ void psycho_init(struct device_node *dp, char *model_name)
1269 prom_printf("PSYCHO: Fatal memory allocation error.\n"); 1154 prom_printf("PSYCHO: Fatal memory allocation error.\n");
1270 prom_halt(); 1155 prom_halt();
1271 } 1156 }
1272 iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); 1157 iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC);
1273 if (!iommu) { 1158 if (!iommu) {
1274 prom_printf("PSYCHO: Fatal memory allocation error.\n"); 1159 prom_printf("PSYCHO: Fatal memory allocation error.\n");
1275 prom_halt(); 1160 prom_halt();
@@ -1282,10 +1167,7 @@ void psycho_init(struct device_node *dp, char *model_name)
1282 p->pbm_A.portid = upa_portid; 1167 p->pbm_A.portid = upa_portid;
1283 p->pbm_B.portid = upa_portid; 1168 p->pbm_B.portid = upa_portid;
1284 p->index = pci_num_controllers++; 1169 p->index = pci_num_controllers++;
1285 p->pbms_same_domain = 0;
1286 p->scan_bus = psycho_scan_bus; 1170 p->scan_bus = psycho_scan_bus;
1287 p->base_address_update = psycho_base_address_update;
1288 p->resource_adjust = psycho_resource_adjust;
1289 p->pci_ops = &psycho_ops; 1171 p->pci_ops = &psycho_ops;
1290 1172
1291 prop = of_find_property(dp, "reg", NULL); 1173 prop = of_find_property(dp, "reg", NULL);