diff options
Diffstat (limited to 'arch/sparc64/kernel/pci.c')
-rw-r--r-- | arch/sparc64/kernel/pci.c | 62 |
1 files changed, 51 insertions, 11 deletions
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 77449a005752..3d93e9203ba2 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -283,12 +283,6 @@ int __init pcic_present(void) | |||
283 | return pci_controller_scan(pci_is_controller); | 283 | return pci_controller_scan(pci_is_controller); |
284 | } | 284 | } |
285 | 285 | ||
286 | const struct pci_iommu_ops *pci_iommu_ops; | ||
287 | EXPORT_SYMBOL(pci_iommu_ops); | ||
288 | |||
289 | extern const struct pci_iommu_ops pci_sun4u_iommu_ops, | ||
290 | pci_sun4v_iommu_ops; | ||
291 | |||
292 | /* Find each controller in the system, attach and initialize | 286 | /* Find each controller in the system, attach and initialize |
293 | * software state structure for each and link into the | 287 | * software state structure for each and link into the |
294 | * pci_pbm_root. Setup the controller enough such | 288 | * pci_pbm_root. Setup the controller enough such |
@@ -296,11 +290,6 @@ extern const struct pci_iommu_ops pci_sun4u_iommu_ops, | |||
296 | */ | 290 | */ |
297 | static void __init pci_controller_probe(void) | 291 | static void __init pci_controller_probe(void) |
298 | { | 292 | { |
299 | if (tlb_type == hypervisor) | ||
300 | pci_iommu_ops = &pci_sun4v_iommu_ops; | ||
301 | else | ||
302 | pci_iommu_ops = &pci_sun4u_iommu_ops; | ||
303 | |||
304 | printk("PCI: Probing for controllers.\n"); | 293 | printk("PCI: Probing for controllers.\n"); |
305 | 294 | ||
306 | pci_controller_scan(pci_controller_init); | 295 | pci_controller_scan(pci_controller_init); |
@@ -406,6 +395,10 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
406 | sd->op = of_find_device_by_node(node); | 395 | sd->op = of_find_device_by_node(node); |
407 | sd->msi_num = 0xffffffff; | 396 | sd->msi_num = 0xffffffff; |
408 | 397 | ||
398 | sd = &sd->op->dev.archdata; | ||
399 | sd->iommu = pbm->iommu; | ||
400 | sd->stc = &pbm->stc; | ||
401 | |||
409 | type = of_get_property(node, "device_type", NULL); | 402 | type = of_get_property(node, "device_type", NULL); |
410 | if (type == NULL) | 403 | if (type == NULL) |
411 | type = ""; | 404 | type = ""; |
@@ -1226,4 +1219,51 @@ struct device_node *pci_device_to_OF_node(struct pci_dev *pdev) | |||
1226 | } | 1219 | } |
1227 | EXPORT_SYMBOL(pci_device_to_OF_node); | 1220 | EXPORT_SYMBOL(pci_device_to_OF_node); |
1228 | 1221 | ||
1222 | static void ali_sound_dma_hack(struct pci_dev *pdev, int set_bit) | ||
1223 | { | ||
1224 | struct pci_dev *ali_isa_bridge; | ||
1225 | u8 val; | ||
1226 | |||
1227 | /* ALI sound chips generate 31-bits of DMA, a special register | ||
1228 | * determines what bit 31 is emitted as. | ||
1229 | */ | ||
1230 | ali_isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, | ||
1231 | PCI_DEVICE_ID_AL_M1533, | ||
1232 | NULL); | ||
1233 | |||
1234 | pci_read_config_byte(ali_isa_bridge, 0x7e, &val); | ||
1235 | if (set_bit) | ||
1236 | val |= 0x01; | ||
1237 | else | ||
1238 | val &= ~0x01; | ||
1239 | pci_write_config_byte(ali_isa_bridge, 0x7e, val); | ||
1240 | pci_dev_put(ali_isa_bridge); | ||
1241 | } | ||
1242 | |||
1243 | int pci_dma_supported(struct pci_dev *pdev, u64 device_mask) | ||
1244 | { | ||
1245 | u64 dma_addr_mask; | ||
1246 | |||
1247 | if (pdev == NULL) { | ||
1248 | dma_addr_mask = 0xffffffff; | ||
1249 | } else { | ||
1250 | struct iommu *iommu = pdev->dev.archdata.iommu; | ||
1251 | |||
1252 | dma_addr_mask = iommu->dma_addr_mask; | ||
1253 | |||
1254 | if (pdev->vendor == PCI_VENDOR_ID_AL && | ||
1255 | pdev->device == PCI_DEVICE_ID_AL_M5451 && | ||
1256 | device_mask == 0x7fffffff) { | ||
1257 | ali_sound_dma_hack(pdev, | ||
1258 | (dma_addr_mask & 0x80000000) != 0); | ||
1259 | return 1; | ||
1260 | } | ||
1261 | } | ||
1262 | |||
1263 | if (device_mask >= (1UL << 32UL)) | ||
1264 | return 0; | ||
1265 | |||
1266 | return (device_mask & dma_addr_mask) == dma_addr_mask; | ||
1267 | } | ||
1268 | |||
1229 | #endif /* !(CONFIG_PCI) */ | 1269 | #endif /* !(CONFIG_PCI) */ |