2010-05-17 17:08:21 +01:00
/******************************************************************************
* platform - pci . c
*
* Xen platform PCI device driver
2016-02-21 19:06:08 -05:00
*
* Authors : ssmith @ xensource . com and stefano . stabellini @ eu . citrix . com
*
2010-05-17 17:08:21 +01:00
* Copyright ( c ) 2005 , Intel Corporation .
* Copyright ( c ) 2007 , XenSource Inc .
* Copyright ( c ) 2010 , Citrix
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms and conditions of the GNU General Public License ,
* version 2 , as published by the Free Software Foundation .
*
* This program is distributed in the hope it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License along with
* this program ; if not , write to the Free Software Foundation , Inc . , 59 Temple
* Place - Suite 330 , Boston , MA 02111 - 1307 USA .
*
*/
# include <linux/interrupt.h>
# include <linux/io.h>
2016-02-21 19:06:08 -05:00
# include <linux/init.h>
2010-05-17 17:08:21 +01:00
# include <linux/pci.h>
2010-05-14 12:44:30 +01:00
# include <xen/platform_pci.h>
2010-05-17 17:08:21 +01:00
# include <xen/grant_table.h>
# include <xen/xenbus.h>
# include <xen/events.h>
# include <xen/hvm.h>
2010-05-14 12:45:07 +01:00
# include <xen/xen-ops.h>
2010-05-17 17:08:21 +01:00
# define DRV_NAME "xen-platform-pci"
static unsigned long platform_mmio ;
static unsigned long platform_mmio_alloc ;
static unsigned long platform_mmiolen ;
2014-02-09 16:29:30 +05:30
static unsigned long alloc_xen_mmio ( unsigned long len )
2010-05-17 17:08:21 +01:00
{
unsigned long addr ;
addr = platform_mmio + platform_mmio_alloc ;
platform_mmio_alloc + = len ;
BUG_ON ( platform_mmio_alloc > platform_mmiolen ) ;
return addr ;
}
2016-02-21 19:06:08 -05:00
static int platform_pci_probe ( struct pci_dev * pdev ,
const struct pci_device_id * ent )
2010-05-17 17:08:21 +01:00
{
int i , ret ;
2011-01-11 11:50:28 +00:00
long ioaddr ;
2010-05-17 17:08:21 +01:00
long mmio_addr , mmio_len ;
unsigned int max_nr_gframes ;
2014-01-06 10:40:36 -05:00
unsigned long grant_frames ;
2010-05-17 17:08:21 +01:00
2012-07-10 15:31:39 +02:00
if ( ! xen_domain ( ) )
return - ENODEV ;
2010-05-17 17:08:21 +01:00
i = pci_enable_device ( pdev ) ;
if ( i )
return i ;
ioaddr = pci_resource_start ( pdev , 0 ) ;
mmio_addr = pci_resource_start ( pdev , 1 ) ;
mmio_len = pci_resource_len ( pdev , 1 ) ;
if ( mmio_addr = = 0 | | ioaddr = = 0 ) {
dev_err ( & pdev - > dev , " no resources found \n " ) ;
ret = - ENOENT ;
goto pci_out ;
}
2011-01-11 11:50:28 +00:00
ret = pci_request_region ( pdev , 1 , DRV_NAME ) ;
if ( ret < 0 )
2010-05-17 17:08:21 +01:00
goto pci_out ;
2011-01-11 11:50:28 +00:00
ret = pci_request_region ( pdev , 0 , DRV_NAME ) ;
if ( ret < 0 )
2010-05-17 17:08:21 +01:00
goto mem_out ;
platform_mmio = mmio_addr ;
platform_mmiolen = mmio_len ;
max_nr_gframes = gnttab_max_grant_frames ( ) ;
2014-01-06 10:40:36 -05:00
grant_frames = alloc_xen_mmio ( PAGE_SIZE * max_nr_gframes ) ;
2014-01-07 21:11:05 +08:00
ret = gnttab_setup_auto_xlat_frames ( grant_frames ) ;
if ( ret )
2014-01-06 10:40:36 -05:00
goto out ;
2010-05-17 17:08:21 +01:00
ret = gnttab_init ( ) ;
if ( ret )
2014-01-06 10:40:36 -05:00
goto grant_out ;
2010-05-17 17:08:21 +01:00
xenbus_probe ( NULL ) ;
return 0 ;
2014-01-06 10:40:36 -05:00
grant_out :
gnttab_free_auto_xlat_frames ( ) ;
2010-05-17 17:08:21 +01:00
out :
2011-01-11 11:50:28 +00:00
pci_release_region ( pdev , 0 ) ;
2010-05-17 17:08:21 +01:00
mem_out :
2011-01-11 11:50:28 +00:00
pci_release_region ( pdev , 1 ) ;
2010-05-17 17:08:21 +01:00
pci_out :
pci_disable_device ( pdev ) ;
return ret ;
}
2012-12-21 13:00:00 -08:00
static struct pci_device_id platform_pci_tbl [ ] = {
2010-05-17 17:08:21 +01:00
{ PCI_VENDOR_ID_XEN , PCI_DEVICE_ID_XEN_PLATFORM ,
PCI_ANY_ID , PCI_ANY_ID , 0 , 0 , 0 } ,
{ 0 , }
} ;
static struct pci_driver platform_driver = {
. name = DRV_NAME ,
2016-02-21 19:06:08 -05:00
. probe = platform_pci_probe ,
2010-05-17 17:08:21 +01:00
. id_table = platform_pci_tbl ,
} ;
2016-11-14 20:52:26 +08:00
builtin_pci_driver ( platform_driver ) ;