2019-06-01 10:08:17 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2013-06-24 18:55:47 +03:00
/*
* linux / drivers / misc / xillybus_pcie . c
*
* Copyright 2011 Xillybus Ltd , http : //xillybus.com
*
* Driver for the Xillybus FPGA / host framework using PCI Express .
*/
# include <linux/module.h>
# include <linux/pci.h>
# include <linux/slab.h>
# include "xillybus.h"
MODULE_DESCRIPTION ( " Xillybus driver for PCIe " ) ;
MODULE_AUTHOR ( " Eli Billauer, Xillybus Ltd. " ) ;
MODULE_ALIAS ( " xillybus_pcie " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
# define PCI_DEVICE_ID_XILLYBUS 0xebeb
# define PCI_VENDOR_ID_ACTEL 0x11aa
# define PCI_VENDOR_ID_LATTICE 0x1204
2013-07-27 00:24:00 +03:00
static const char xillyname [ ] = " xillybus_pcie " ;
2013-12-03 08:26:00 +09:00
static const struct pci_device_id xillyids [ ] = {
2013-06-24 18:55:47 +03:00
{ PCI_DEVICE ( PCI_VENDOR_ID_XILINX , PCI_DEVICE_ID_XILLYBUS ) } ,
{ PCI_DEVICE ( PCI_VENDOR_ID_ALTERA , PCI_DEVICE_ID_XILLYBUS ) } ,
{ PCI_DEVICE ( PCI_VENDOR_ID_ACTEL , PCI_DEVICE_ID_XILLYBUS ) } ,
{ PCI_DEVICE ( PCI_VENDOR_ID_LATTICE , PCI_DEVICE_ID_XILLYBUS ) } ,
{ /* End: all zeroes */ }
} ;
static int xilly_probe ( struct pci_dev * pdev ,
2014-09-04 17:47:56 +03:00
const struct pci_device_id * ent )
2013-06-24 18:55:47 +03:00
{
struct xilly_endpoint * endpoint ;
2014-09-04 17:47:48 +03:00
int rc ;
2013-06-24 18:55:47 +03:00
2021-09-29 12:44:42 +03:00
endpoint = xillybus_init_endpoint ( & pdev - > dev ) ;
2013-06-24 18:55:47 +03:00
if ( ! endpoint )
return - ENOMEM ;
pci_set_drvdata ( pdev , endpoint ) ;
2021-09-29 12:44:42 +03:00
endpoint - > owner = THIS_MODULE ;
2014-05-11 19:53:46 +03:00
rc = pcim_enable_device ( pdev ) ;
2013-06-24 18:55:47 +03:00
if ( rc ) {
2013-10-19 01:02:26 +03:00
dev_err ( endpoint - > dev ,
2014-05-11 19:53:46 +03:00
" pcim_enable_device() failed. Aborting. \n " ) ;
return rc ;
2013-06-24 18:55:47 +03:00
}
2014-05-11 19:53:46 +03:00
/* L0s has caused packet drops. No power saving, thank you. */
pci_disable_link_state ( pdev , PCIE_LINK_STATE_L0S ) ;
2013-06-24 18:55:47 +03:00
if ( ! ( pci_resource_flags ( pdev , 0 ) & IORESOURCE_MEM ) ) {
2013-10-19 01:02:26 +03:00
dev_err ( endpoint - > dev ,
" Incorrect BAR configuration. Aborting. \n " ) ;
2014-05-11 19:53:46 +03:00
return - ENODEV ;
2013-06-24 18:55:47 +03:00
}
2014-05-11 19:53:46 +03:00
rc = pcim_iomap_regions ( pdev , 0x01 , xillyname ) ;
2013-06-24 18:55:47 +03:00
if ( rc ) {
2013-10-19 01:02:26 +03:00
dev_err ( endpoint - > dev ,
2014-05-11 19:53:46 +03:00
" pcim_iomap_regions() failed. Aborting. \n " ) ;
return rc ;
2013-06-24 18:55:47 +03:00
}
2014-05-11 19:53:46 +03:00
endpoint - > registers = pcim_iomap_table ( pdev ) [ 0 ] ;
2013-06-24 18:55:47 +03:00
pci_set_master ( pdev ) ;
/* Set up a single MSI interrupt */
if ( pci_enable_msi ( pdev ) ) {
2013-10-19 01:02:26 +03:00
dev_err ( endpoint - > dev ,
" Failed to enable MSI interrupts. Aborting. \n " ) ;
2014-05-11 19:53:46 +03:00
return - ENODEV ;
2013-06-24 18:55:47 +03:00
}
2014-05-11 19:53:46 +03:00
rc = devm_request_irq ( & pdev - > dev , pdev - > irq , xillybus_isr , 0 ,
xillyname , endpoint ) ;
2013-06-24 18:55:47 +03:00
if ( rc ) {
2013-10-19 01:02:26 +03:00
dev_err ( endpoint - > dev ,
" Failed to register MSI handler. Aborting. \n " ) ;
2014-05-11 19:53:46 +03:00
return - ENODEV ;
2013-06-24 18:55:47 +03:00
}
/*
2015-08-05 13:03:26 +03:00
* Some ( old and buggy ? ) hardware drops 64 - bit addressed PCIe packets ,
* even when the PCIe driver claims that a 64 - bit mask is OK . On the
* other hand , on some architectures , 64 - bit addressing is mandatory .
* So go for the 64 - bit mask only when failing is the other option .
2013-06-24 18:55:47 +03:00
*/
2021-08-27 19:17:33 +02:00
if ( ! dma_set_mask ( & pdev - > dev , DMA_BIT_MASK ( 32 ) ) ) {
2013-06-24 18:55:47 +03:00
endpoint - > dma_using_dac = 0 ;
2021-08-27 19:17:33 +02:00
} else if ( ! dma_set_mask ( & pdev - > dev , DMA_BIT_MASK ( 64 ) ) ) {
2015-08-05 13:03:26 +03:00
endpoint - > dma_using_dac = 1 ;
2014-09-04 17:47:51 +03:00
} else {
2013-10-19 01:02:26 +03:00
dev_err ( endpoint - > dev , " Failed to set DMA mask. Aborting. \n " ) ;
2014-05-11 19:53:46 +03:00
return - ENODEV ;
2013-06-24 18:55:47 +03:00
}
2014-06-21 14:07:12 +03:00
return xillybus_endpoint_discovery ( endpoint ) ;
2013-06-24 18:55:47 +03:00
}
static void xilly_remove ( struct pci_dev * pdev )
{
struct xilly_endpoint * endpoint = pci_get_drvdata ( pdev ) ;
xillybus_endpoint_remove ( endpoint ) ;
}
MODULE_DEVICE_TABLE ( pci , xillyids ) ;
static struct pci_driver xillybus_driver = {
. name = xillyname ,
. id_table = xillyids ,
. probe = xilly_probe ,
. remove = xilly_remove ,
} ;
module_pci_driver ( xillybus_driver ) ;