2005-04-16 15:20:36 -07:00
/*
* File : portdrv_pci . c
* Purpose : PCI Express Port Bus Driver
*
* Copyright ( C ) 2004 Intel
* Copyright ( C ) Tom Long Nguyen ( tom . l . nguyen @ intel . com )
*/
# include <linux/module.h>
# include <linux/pci.h>
# include <linux/kernel.h>
# include <linux/errno.h>
# include <linux/pm.h>
# include <linux/init.h>
2005-10-30 15:03:48 -08:00
# include <linux/slab.h>
2005-04-16 15:20:36 -07:00
# include <linux/pcieport_if.h>
# include "portdrv.h"
/*
* Version Information
*/
# define DRIVER_VERSION "v1.0"
# define DRIVER_AUTHOR "tom.l.nguyen@intel.com"
# define DRIVER_DESC "PCIE Port Bus Driver"
MODULE_AUTHOR ( DRIVER_AUTHOR ) ;
MODULE_DESCRIPTION ( DRIVER_DESC ) ;
MODULE_LICENSE ( " GPL " ) ;
/* global data */
static const char device_name [ ] = " pcieport-driver " ;
/*
* pcie_portdrv_probe - Probe PCI - Express port devices
* @ dev : PCI - Express port device being probed
*
* If detected invokes the pcie_port_device_register ( ) method for
* this port device .
*
*/
static int __devinit pcie_portdrv_probe ( struct pci_dev * dev ,
const struct pci_device_id * id )
{
int status ;
status = pcie_port_device_probe ( dev ) ;
if ( status )
return status ;
if ( pci_enable_device ( dev ) < 0 )
return - ENODEV ;
pci_set_master ( dev ) ;
if ( ! dev - > irq ) {
printk ( KERN_WARNING
" %s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS \n " ,
__FUNCTION__ , dev - > device , dev - > vendor ) ;
}
2006-07-06 21:36:01 -07:00
if ( pcie_port_device_register ( dev ) ) {
pci_disable_device ( dev ) ;
2005-04-16 15:20:36 -07:00
return - ENOMEM ;
2006-07-06 21:36:01 -07:00
}
2005-04-16 15:20:36 -07:00
return 0 ;
}
static void pcie_portdrv_remove ( struct pci_dev * dev )
{
pcie_port_device_remove ( dev ) ;
2005-06-22 09:09:54 -07:00
kfree ( pci_get_drvdata ( dev ) ) ;
2005-04-16 15:20:36 -07:00
}
# ifdef CONFIG_PM
2006-07-06 18:05:51 +04:00
static int pcie_portdrv_save_config ( struct pci_dev * dev )
{
return pci_save_state ( dev ) ;
}
static int pcie_portdrv_restore_config ( struct pci_dev * dev )
{
int retval ;
pci_restore_state ( dev ) ;
retval = pci_enable_device ( dev ) ;
if ( retval )
return retval ;
pci_set_master ( dev ) ;
return 0 ;
}
2005-04-16 15:25:33 -07:00
static int pcie_portdrv_suspend ( struct pci_dev * dev , pm_message_t state )
2005-04-16 15:20:36 -07:00
{
2005-06-22 09:09:54 -07:00
int ret = pcie_port_device_suspend ( dev , state ) ;
2006-02-08 17:11:40 +08:00
if ( ! ret )
ret = pcie_portdrv_save_config ( dev ) ;
2005-06-22 09:09:54 -07:00
return ret ;
2005-04-16 15:20:36 -07:00
}
static int pcie_portdrv_resume ( struct pci_dev * dev )
{
2005-06-22 09:09:54 -07:00
pcie_portdrv_restore_config ( dev ) ;
2005-04-16 15:20:36 -07:00
return pcie_port_device_resume ( dev ) ;
}
# endif
/*
* LINUX Device Driver Model
*/
static const struct pci_device_id port_pci_ids [ ] = { {
/* handle any PCI-Express port */
PCI_DEVICE_CLASS ( ( ( PCI_CLASS_BRIDGE_PCI < < 8 ) | 0x00 ) , ~ 0 ) ,
} , { /* end: all zeroes */ }
} ;
MODULE_DEVICE_TABLE ( pci , port_pci_ids ) ;
static struct pci_driver pcie_portdrv = {
. name = ( char * ) device_name ,
. id_table = & port_pci_ids [ 0 ] ,
. probe = pcie_portdrv_probe ,
. remove = pcie_portdrv_remove ,
# ifdef CONFIG_PM
. suspend = pcie_portdrv_suspend ,
. resume = pcie_portdrv_resume ,
# endif /* PM */
} ;
static int __init pcie_portdrv_init ( void )
{
int retval = 0 ;
pcie_port_bus_register ( ) ;
retval = pci_register_driver ( & pcie_portdrv ) ;
if ( retval )
pcie_port_bus_unregister ( ) ;
return retval ;
}
static void __exit pcie_portdrv_exit ( void )
{
pci_unregister_driver ( & pcie_portdrv ) ;
pcie_port_bus_unregister ( ) ;
}
module_init ( pcie_portdrv_init ) ;
module_exit ( pcie_portdrv_exit ) ;