diff options
Diffstat (limited to 'arch/sparc/kernel/pci.c')
-rw-r--r-- | arch/sparc/kernel/pci.c | 95 |
1 files changed, 92 insertions, 3 deletions
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index c68648662802..5ac539a5930f 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
@@ -247,6 +247,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
247 | struct pci_bus *bus, int devfn) | 247 | struct pci_bus *bus, int devfn) |
248 | { | 248 | { |
249 | struct dev_archdata *sd; | 249 | struct dev_archdata *sd; |
250 | struct pci_slot *slot; | ||
250 | struct of_device *op; | 251 | struct of_device *op; |
251 | struct pci_dev *dev; | 252 | struct pci_dev *dev; |
252 | const char *type; | 253 | const char *type; |
@@ -286,6 +287,11 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
286 | dev->dev.bus = &pci_bus_type; | 287 | dev->dev.bus = &pci_bus_type; |
287 | dev->devfn = devfn; | 288 | dev->devfn = devfn; |
288 | dev->multifunction = 0; /* maybe a lie? */ | 289 | dev->multifunction = 0; /* maybe a lie? */ |
290 | set_pcie_port_type(dev); | ||
291 | |||
292 | list_for_each_entry(slot, &dev->bus->slots, list) | ||
293 | if (PCI_SLOT(dev->devfn) == slot->number) | ||
294 | dev->slot = slot; | ||
289 | 295 | ||
290 | dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); | 296 | dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); |
291 | dev->device = of_getintprop_default(node, "device-id", 0xffff); | 297 | dev->device = of_getintprop_default(node, "device-id", 0xffff); |
@@ -322,6 +328,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
322 | 328 | ||
323 | dev->current_state = 4; /* unknown power state */ | 329 | dev->current_state = 4; /* unknown power state */ |
324 | dev->error_state = pci_channel_io_normal; | 330 | dev->error_state = pci_channel_io_normal; |
331 | dev->dma_mask = 0xffffffff; | ||
325 | 332 | ||
326 | if (!strcmp(node->name, "pci")) { | 333 | if (!strcmp(node->name, "pci")) { |
327 | /* a PCI-PCI bridge */ | 334 | /* a PCI-PCI bridge */ |
@@ -715,9 +722,10 @@ void pcibios_update_irq(struct pci_dev *pdev, int irq) | |||
715 | { | 722 | { |
716 | } | 723 | } |
717 | 724 | ||
718 | void pcibios_align_resource(void *data, struct resource *res, | 725 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, |
719 | resource_size_t size, resource_size_t align) | 726 | resource_size_t size, resource_size_t align) |
720 | { | 727 | { |
728 | return res->start; | ||
721 | } | 729 | } |
722 | 730 | ||
723 | int pcibios_enable_device(struct pci_dev *dev, int mask) | 731 | int pcibios_enable_device(struct pci_dev *dev, int mask) |
@@ -1064,7 +1072,6 @@ int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask) | |||
1064 | 1072 | ||
1065 | return (device_mask & dma_addr_mask) == dma_addr_mask; | 1073 | return (device_mask & dma_addr_mask) == dma_addr_mask; |
1066 | } | 1074 | } |
1067 | EXPORT_SYMBOL(pci_dma_supported); | ||
1068 | 1075 | ||
1069 | void pci_resource_to_user(const struct pci_dev *pdev, int bar, | 1076 | void pci_resource_to_user(const struct pci_dev *pdev, int bar, |
1070 | const struct resource *rp, resource_size_t *start, | 1077 | const struct resource *rp, resource_size_t *start, |
@@ -1081,3 +1088,85 @@ void pci_resource_to_user(const struct pci_dev *pdev, int bar, | |||
1081 | *start = rp->start - offset; | 1088 | *start = rp->start - offset; |
1082 | *end = rp->end - offset; | 1089 | *end = rp->end - offset; |
1083 | } | 1090 | } |
1091 | |||
1092 | static int __init pcibios_init(void) | ||
1093 | { | ||
1094 | pci_dfl_cache_line_size = 64 >> 2; | ||
1095 | return 0; | ||
1096 | } | ||
1097 | subsys_initcall(pcibios_init); | ||
1098 | |||
1099 | #ifdef CONFIG_SYSFS | ||
1100 | static void __devinit pci_bus_slot_names(struct device_node *node, | ||
1101 | struct pci_bus *bus) | ||
1102 | { | ||
1103 | const struct pci_slot_names { | ||
1104 | u32 slot_mask; | ||
1105 | char names[0]; | ||
1106 | } *prop; | ||
1107 | const char *sp; | ||
1108 | int len, i; | ||
1109 | u32 mask; | ||
1110 | |||
1111 | prop = of_get_property(node, "slot-names", &len); | ||
1112 | if (!prop) | ||
1113 | return; | ||
1114 | |||
1115 | mask = prop->slot_mask; | ||
1116 | sp = prop->names; | ||
1117 | |||
1118 | if (ofpci_verbose) | ||
1119 | printk("PCI: Making slots for [%s] mask[0x%02x]\n", | ||
1120 | node->full_name, mask); | ||
1121 | |||
1122 | i = 0; | ||
1123 | while (mask) { | ||
1124 | struct pci_slot *pci_slot; | ||
1125 | u32 this_bit = 1 << i; | ||
1126 | |||
1127 | if (!(mask & this_bit)) { | ||
1128 | i++; | ||
1129 | continue; | ||
1130 | } | ||
1131 | |||
1132 | if (ofpci_verbose) | ||
1133 | printk("PCI: Making slot [%s]\n", sp); | ||
1134 | |||
1135 | pci_slot = pci_create_slot(bus, i, sp, NULL); | ||
1136 | if (IS_ERR(pci_slot)) | ||
1137 | printk(KERN_ERR "PCI: pci_create_slot returned %ld\n", | ||
1138 | PTR_ERR(pci_slot)); | ||
1139 | |||
1140 | sp += strlen(sp) + 1; | ||
1141 | mask &= ~this_bit; | ||
1142 | i++; | ||
1143 | } | ||
1144 | } | ||
1145 | |||
1146 | static int __init of_pci_slot_init(void) | ||
1147 | { | ||
1148 | struct pci_bus *pbus = NULL; | ||
1149 | |||
1150 | while ((pbus = pci_find_next_bus(pbus)) != NULL) { | ||
1151 | struct device_node *node; | ||
1152 | |||
1153 | if (pbus->self) { | ||
1154 | struct dev_archdata *sd = pbus->self->sysdata; | ||
1155 | |||
1156 | /* PCI->PCI bridge */ | ||
1157 | node = sd->prom_node; | ||
1158 | } else { | ||
1159 | struct pci_pbm_info *pbm = pbus->sysdata; | ||
1160 | |||
1161 | /* Host PCI controller */ | ||
1162 | node = pbm->op->node; | ||
1163 | } | ||
1164 | |||
1165 | pci_bus_slot_names(node, pbus); | ||
1166 | } | ||
1167 | |||
1168 | return 0; | ||
1169 | } | ||
1170 | |||
1171 | module_init(of_pci_slot_init); | ||
1172 | #endif | ||