static int ppc_swiotlb_bus_notify(struct notifier_block *nb, unsigned long action, void *data) { struct device *dev = data; struct dev_archdata *sd; /* We are only intereted in device addition */ if (action != BUS_NOTIFY_ADD_DEVICE) return 0; sd = &dev->archdata; sd->max_direct_dma_addr = 0; /* May need to bounce if the device can't address all of DRAM */ if ((dma_get_mask(dev) + 1) < memblock_end_of_DRAM()) set_dma_ops(dev, &swiotlb_dma_ops); return NOTIFY_DONE; }
static int kdwc3_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *node = pdev->dev.of_node; struct dwc3_keystone *kdwc; struct resource *res; int error, irq; kdwc = devm_kzalloc(dev, sizeof(*kdwc), GFP_KERNEL); if (!kdwc) return -ENOMEM; platform_set_drvdata(pdev, kdwc); kdwc->dev = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); kdwc->usbss = devm_ioremap_resource(dev, res); if (IS_ERR(kdwc->usbss)) return PTR_ERR(kdwc->usbss); kdwc3_dma_mask = dma_get_mask(dev); dev->dma_mask = &kdwc3_dma_mask; kdwc->clk = devm_clk_get(kdwc->dev, "usb"); error = clk_prepare_enable(kdwc->clk); if (error < 0) { dev_err(kdwc->dev, "unable to enable usb clock, error %d\n", error); return error; } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "missing irq\n"); error = irq; goto err_irq; } error = devm_request_irq(dev, irq, dwc3_keystone_interrupt, IRQF_SHARED, dev_name(dev), kdwc); if (error) { dev_err(dev, "failed to request IRQ #%d --> %d\n", irq, error); goto err_irq; } kdwc3_enable_irqs(kdwc); error = of_platform_populate(node, NULL, NULL, dev); if (error) { dev_err(&pdev->dev, "failed to create dwc3 core\n"); goto err_core; } return 0; err_core: kdwc3_disable_irqs(kdwc); err_irq: clk_disable_unprepare(kdwc->clk); return error; }
static int kp2000_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int err = 0; struct kp2000_device *pcard; int rv; unsigned long reg_bar_phys_addr; unsigned long reg_bar_phys_len; unsigned long dma_bar_phys_addr; unsigned long dma_bar_phys_len; u16 regval; dev_dbg(&pdev->dev, "kp2000_pcie_probe(pdev = [%p], id = [%p])\n", pdev, id); /* * Step 1: Allocate a struct for the pcard */ pcard = kzalloc(sizeof(struct kp2000_device), GFP_KERNEL); if (NULL == pcard) { dev_err(&pdev->dev, "probe: failed to allocate private card data\n"); return -ENOMEM; } dev_dbg(&pdev->dev, "probe: allocated struct kp2000_device @ %p\n", pcard); /* * Step 2: Initialize trivial pcard elements */ err = ida_simple_get(&card_num_ida, 1, INT_MAX, GFP_KERNEL); if (err < 0) { dev_err(&pdev->dev, "probe: failed to get card number (%d)\n", err); goto out2; } pcard->card_num = err; scnprintf(pcard->name, 16, "kpcard%u", pcard->card_num); mutex_init(&pcard->sem); mutex_lock(&pcard->sem); pcard->pdev = pdev; pci_set_drvdata(pdev, pcard); /* * Step 3: Enable PCI device */ err = pci_enable_device(pcard->pdev); if (err) { dev_err(&pcard->pdev->dev, "probe: failed to enable PCIE2000 PCIe device (%d)\n", err); goto out3; } /* * Step 4: Setup the Register BAR */ reg_bar_phys_addr = pci_resource_start(pcard->pdev, REG_BAR); reg_bar_phys_len = pci_resource_len(pcard->pdev, REG_BAR); pcard->regs_bar_base = ioremap_nocache(reg_bar_phys_addr, PAGE_SIZE); if (NULL == pcard->regs_bar_base) { dev_err(&pcard->pdev->dev, "probe: REG_BAR could not remap memory to virtual space\n"); err = -ENODEV; goto out4; } dev_dbg(&pcard->pdev->dev, "probe: REG_BAR virt hardware address start [%p]\n", pcard->regs_bar_base); err = pci_request_region(pcard->pdev, REG_BAR, KP_DRIVER_NAME_KP2000); if (err) { iounmap(pcard->regs_bar_base); dev_err(&pcard->pdev->dev, "probe: failed to acquire PCI region (%d)\n", err); err = -ENODEV; goto out4; } pcard->regs_base_resource.start = reg_bar_phys_addr; pcard->regs_base_resource.end = reg_bar_phys_addr + reg_bar_phys_len - 1; pcard->regs_base_resource.flags = IORESOURCE_MEM; /* * Step 5: Setup the DMA BAR */ dma_bar_phys_addr = pci_resource_start(pcard->pdev, DMA_BAR); dma_bar_phys_len = pci_resource_len(pcard->pdev, DMA_BAR); pcard->dma_bar_base = ioremap_nocache(dma_bar_phys_addr, dma_bar_phys_len); if (NULL == pcard->dma_bar_base) { dev_err(&pcard->pdev->dev, "probe: DMA_BAR could not remap memory to virtual space\n"); err = -ENODEV; goto out5; } dev_dbg(&pcard->pdev->dev, "probe: DMA_BAR virt hardware address start [%p]\n", pcard->dma_bar_base); pcard->dma_common_regs = pcard->dma_bar_base + KPC_DMA_COMMON_OFFSET; err = pci_request_region(pcard->pdev, DMA_BAR, "kp2000_pcie"); if (err) { iounmap(pcard->dma_bar_base); dev_err(&pcard->pdev->dev, "probe: failed to acquire PCI region (%d)\n", err); err = -ENODEV; goto out5; } pcard->dma_base_resource.start = dma_bar_phys_addr; pcard->dma_base_resource.end = dma_bar_phys_addr + dma_bar_phys_len - 1; pcard->dma_base_resource.flags = IORESOURCE_MEM; /* * Step 6: System Regs */ pcard->sysinfo_regs_base = pcard->regs_bar_base; err = read_system_regs(pcard); if (err) goto out6; // Disable all "user" interrupts because they're not used yet. writeq(0xFFFFFFFFFFFFFFFF, pcard->sysinfo_regs_base + REG_INTERRUPT_MASK); /* * Step 7: Configure PCI thingies */ // let the card master PCIe pci_set_master(pcard->pdev); // enable IO and mem if not already done pci_read_config_word(pcard->pdev, PCI_COMMAND, ®val); regval |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY); pci_write_config_word(pcard->pdev, PCI_COMMAND, regval); // Clear relaxed ordering bit pcie_capability_clear_and_set_word(pcard->pdev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN, 0); // Set Max_Payload_Size and Max_Read_Request_Size regval = (0x0) << 5; // Max_Payload_Size = 128 B pcie_capability_clear_and_set_word(pcard->pdev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_PAYLOAD, regval); regval = (0x0) << 12; // Max_Read_Request_Size = 128 B pcie_capability_clear_and_set_word(pcard->pdev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_READRQ, regval); // Enable error reporting for: Correctable Errors, Non-Fatal Errors, // Fatal Errors, Unsupported Requests pcie_capability_clear_and_set_word(pcard->pdev, PCI_EXP_DEVCTL, 0, PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE); err = dma_set_mask(PCARD_TO_DEV(pcard), DMA_BIT_MASK(64)); if (err) { dev_err(&pcard->pdev->dev, "CANNOT use DMA mask %0llx\n", DMA_BIT_MASK(64)); goto out7; } dev_dbg(&pcard->pdev->dev, "Using DMA mask %0llx\n", dma_get_mask(PCARD_TO_DEV(pcard))); /* * Step 8: Configure IRQs */ err = pci_enable_msi(pcard->pdev); if (err < 0) goto out8a; rv = request_irq(pcard->pdev->irq, kp2000_irq_handler, IRQF_SHARED, pcard->name, pcard); if (rv) { dev_err(&pcard->pdev->dev, "kp2000_pcie_probe: failed to request_irq: %d\n", rv); goto out8b; } /* * Step 9: Setup sysfs attributes */ err = sysfs_create_files(&(pdev->dev.kobj), kp_attr_list); if (err) { dev_err(&pdev->dev, "Failed to add sysfs files: %d\n", err); goto out9; } /* * Step 10: Setup misc device */ pcard->miscdev.minor = MISC_DYNAMIC_MINOR; pcard->miscdev.fops = &kp2000_fops; pcard->miscdev.parent = &pcard->pdev->dev; pcard->miscdev.name = pcard->name; err = misc_register(&pcard->miscdev); if (err) { dev_err(&pcard->pdev->dev, "kp2000_pcie_probe: misc_register failed: %d\n", err); goto out10; } /* * Step 11: Probe cores */ err = kp2000_probe_cores(pcard); if (err) goto out11; /* * Step 12: Enable IRQs in HW */ writel(KPC_DMA_CARD_IRQ_ENABLE | KPC_DMA_CARD_USER_INTERRUPT_MODE, pcard->dma_common_regs); dev_dbg(&pcard->pdev->dev, "kp2000_pcie_probe() complete!\n"); mutex_unlock(&pcard->sem); return 0; out11: misc_deregister(&pcard->miscdev); out10: sysfs_remove_files(&(pdev->dev.kobj), kp_attr_list); out9: free_irq(pcard->pdev->irq, pcard); out8b: pci_disable_msi(pcard->pdev); out8a: out7: out6: iounmap(pcard->dma_bar_base); pci_release_region(pdev, DMA_BAR); pcard->dma_bar_base = NULL; out5: iounmap(pcard->regs_bar_base); pci_release_region(pdev, REG_BAR); pcard->regs_bar_base = NULL; out4: pci_disable_device(pcard->pdev); out3: mutex_unlock(&pcard->sem); ida_simple_remove(&card_num_ida, pcard->card_num); out2: kfree(pcard); return err; }
int __weak swiotlb_arch_address_needs_mapping(struct device *hwdev, dma_addr_t addr, size_t size) { return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size); }