aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-07-28 01:39:14 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-30 03:27:34 -0400
commitad7ad57c6127042c411353dddb723765964815db (patch)
tree600484291d9cfa68d54dc9b230f5bd115f495213 /arch/sparc64/kernel/pci.c
parentc7f439b99efbea74c70a5531f92566db5a6731f2 (diff)
[SPARC64]: Fix conflicts in SBUS/PCI/EBUS/ISA DMA handling.
Fully unify all of the DMA ops so that subordinate bus types to the DMA operation providers (such as ebus, isa, of_device) can work transparently. Basically, we just make sure that for every system device we create, the dev->archdata 'iommu' and 'stc' fields are filled in. Then we have two platform variants of the DMA ops, one for SUN4U which actually programs the real hardware, and one for SUN4V which makes hypervisor calls. This also fixes the crashes in parport_pc on sparc64, reported by Meelis Roos. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/pci.c')
-rw-r--r--arch/sparc64/kernel/pci.c62
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
286const struct pci_iommu_ops *pci_iommu_ops;
287EXPORT_SYMBOL(pci_iommu_ops);
288
289extern 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 */
297static void __init pci_controller_probe(void) 291static 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}
1227EXPORT_SYMBOL(pci_device_to_OF_node); 1220EXPORT_SYMBOL(pci_device_to_OF_node);
1228 1221
1222static 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
1243int 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) */