2009-12-03 04:06:15 +03:00
/*
Mantis PCI bridge driver
2009-12-15 15:13:49 +03:00
Copyright ( C ) Manu Abraham ( abraham . manu @ gmail . com )
2009-12-03 04:06:15 +03:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that 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 . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
2009-12-04 11:41:11 +03:00
# include <linux/module.h>
# include <linux/moduleparam.h>
# include <linux/kernel.h>
2009-12-03 04:06:15 +03:00
# include <asm/io.h>
# include <asm/pgtable.h>
# include <asm/page.h>
# include <linux/kmod.h>
# include <linux/vmalloc.h>
# include <linux/init.h>
# include <linux/device.h>
2009-12-04 11:41:11 +03:00
# include <linux/pci.h>
2009-12-03 04:06:15 +03:00
# include <asm/irq.h>
# include <linux/signal.h>
# include <linux/sched.h>
# include <linux/interrupt.h>
2009-12-04 11:41:11 +03:00
# include "dmxdev.h"
# include "dvbdev.h"
# include "dvb_demux.h"
# include "dvb_frontend.h"
# include "dvb_net.h"
2009-12-04 11:26:46 +03:00
2009-12-04 11:41:11 +03:00
# include <asm/irq.h>
# include <linux/signal.h>
# include <linux/sched.h>
# include <linux/interrupt.h>
2009-12-03 04:06:15 +03:00
2009-12-04 11:41:11 +03:00
# include "mantis_common.h"
# include "mantis_reg.h"
# include "mantis_pci.h"
2009-12-03 04:06:15 +03:00
2009-12-04 11:41:11 +03:00
# define DRIVER_NAME "Mantis Core"
2009-12-03 04:06:15 +03:00
2009-12-04 11:41:11 +03:00
int __devinit mantis_pci_init ( struct mantis_pci * mantis )
2009-12-03 04:06:15 +03:00
{
u8 revision , latency ;
2009-12-04 11:41:11 +03:00
struct mantis_hwconfig * config = mantis - > hwconfig ;
struct pci_dev * pdev = mantis - > pdev ;
int err , ret = 0 ;
dprintk ( MANTIS_ERROR , 0 , " found a %s PCI %s device on (%02x:%02x.%x), \n " ,
config - > model_name ,
config - > dev_type ,
mantis - > pdev - > bus - > number ,
PCI_SLOT ( mantis - > pdev - > devfn ) ,
PCI_FUNC ( mantis - > pdev - > devfn ) ) ;
err = pci_enable_device ( pdev ) ;
if ( err ! = 0 ) {
ret = - ENODEV ;
dprintk ( MANTIS_ERROR , 1 , " ERROR: PCI enable failed <%i> " , err ) ;
goto fail0 ;
}
2009-12-03 04:06:15 +03:00
2009-12-17 05:06:04 +03:00
err = pci_set_consistent_dma_mask ( pdev , DMA_BIT_MASK ( 32 ) ) ;
2009-12-04 11:41:11 +03:00
if ( err ! = 0 ) {
dprintk ( MANTIS_ERROR , 1 , " ERROR: Unable to obtain 32 bit DMA <%i> " , err ) ;
2009-12-03 04:06:15 +03:00
ret = - ENOMEM ;
2009-12-04 11:41:11 +03:00
goto fail1 ;
2009-12-03 04:06:15 +03:00
}
2009-12-03 04:07:24 +03:00
2009-12-04 11:41:11 +03:00
pci_set_master ( pdev ) ;
2009-12-03 04:06:15 +03:00
2009-12-04 11:41:11 +03:00
if ( ! request_mem_region ( pci_resource_start ( pdev , 0 ) ,
pci_resource_len ( pdev , 0 ) ,
DRIVER_NAME ) ) {
2009-12-04 11:32:51 +03:00
2009-12-04 11:41:11 +03:00
dprintk ( MANTIS_ERROR , 1 , " ERROR: BAR0 Request failed ! " ) ;
2009-12-03 04:06:15 +03:00
ret = - ENODEV ;
2009-12-04 11:41:11 +03:00
goto fail1 ;
2009-12-03 04:06:15 +03:00
}
2009-12-04 11:41:11 +03:00
mantis - > mmio = ioremap ( pci_resource_start ( pdev , 0 ) ,
pci_resource_len ( pdev , 0 ) ) ;
2009-12-03 04:06:15 +03:00
2009-12-04 11:41:11 +03:00
if ( ! mantis - > mmio ) {
dprintk ( MANTIS_ERROR , 1 , " ERROR: BAR0 remap failed ! " ) ;
2009-12-03 04:06:15 +03:00
ret = - ENODEV ;
2009-12-04 11:41:11 +03:00
goto fail2 ;
2009-12-03 04:06:15 +03:00
}
2009-12-04 11:41:11 +03:00
2009-12-03 04:06:15 +03:00
pci_read_config_byte ( pdev , PCI_LATENCY_TIMER , & latency ) ;
pci_read_config_byte ( pdev , PCI_CLASS_REVISION , & revision ) ;
mantis - > latency = latency ;
mantis - > revision = revision ;
2009-12-04 11:41:11 +03:00
dprintk ( MANTIS_ERROR , 0 , " Mantis Rev %d [%04x:%04x], " ,
mantis - > revision ,
mantis - > pdev - > subsystem_vendor ,
mantis - > pdev - > subsystem_device ) ;
dprintk ( MANTIS_ERROR , 0 ,
" irq: %d, latency: %d \n memory: 0x%lx, mmio: 0x%p \n " ,
mantis - > pdev - > irq ,
mantis - > latency ,
mantis - > mantis_addr ,
mantis - > mmio ) ;
2009-12-03 04:06:15 +03:00
2009-12-04 11:41:11 +03:00
err = request_irq ( pdev - > irq ,
config - > irq_handler ,
IRQF_SHARED ,
DRIVER_NAME ,
mantis ) ;
2009-12-03 04:06:15 +03:00
2009-12-04 11:41:11 +03:00
if ( err ! = 0 ) {
2009-12-03 04:06:15 +03:00
2009-12-04 11:41:11 +03:00
dprintk ( MANTIS_ERROR , 1 , " ERROR: IRQ registration failed ! <%d> " , err ) ;
2009-12-03 04:06:15 +03:00
ret = - ENODEV ;
2009-12-04 11:41:11 +03:00
goto fail3 ;
2009-12-03 04:06:15 +03:00
}
2009-12-04 11:41:11 +03:00
pci_set_drvdata ( pdev , mantis ) ;
return ret ;
2009-12-03 04:06:15 +03:00
2009-12-04 11:41:11 +03:00
/* Error conditions */
fail3 :
dprintk ( MANTIS_ERROR , 1 , " ERROR: <%d> I/O unmap " , ret ) ;
if ( mantis - > mmio )
iounmap ( mantis - > mmio ) ;
fail2 :
dprintk ( MANTIS_ERROR , 1 , " ERROR: <%d> releasing regions " , ret ) ;
2009-12-03 04:06:15 +03:00
release_mem_region ( pci_resource_start ( pdev , 0 ) ,
2009-12-04 11:41:11 +03:00
pci_resource_len ( pdev , 0 ) ) ;
fail1 :
dprintk ( MANTIS_ERROR , 1 , " ERROR: <%d> disabling device " , ret ) ;
2009-12-03 04:06:15 +03:00
pci_disable_device ( pdev ) ;
2009-12-04 11:41:11 +03:00
fail0 :
dprintk ( MANTIS_ERROR , 1 , " ERROR: <%d> exiting " , ret ) ;
pci_set_drvdata ( pdev , NULL ) ;
2009-12-03 04:06:15 +03:00
return ret ;
}
2009-12-04 11:41:11 +03:00
EXPORT_SYMBOL_GPL ( mantis_pci_init ) ;
2009-12-03 04:06:15 +03:00
2009-12-18 14:58:46 +03:00
void mantis_pci_exit ( struct mantis_pci * mantis )
2009-12-03 04:06:15 +03:00
{
2009-12-04 11:41:11 +03:00
struct pci_dev * pdev = mantis - > pdev ;
2009-12-03 04:06:15 +03:00
2009-12-04 11:41:11 +03:00
dprintk ( MANTIS_NOTICE , 1 , " mem: 0x%p " , mantis - > mmio ) ;
2009-12-03 04:06:15 +03:00
free_irq ( pdev - > irq , mantis ) ;
2009-12-04 11:41:11 +03:00
if ( mantis - > mmio ) {
iounmap ( mantis - > mmio ) ;
release_mem_region ( pci_resource_start ( pdev , 0 ) ,
pci_resource_len ( pdev , 0 ) ) ;
}
2009-12-03 04:06:15 +03:00
pci_disable_device ( pdev ) ;
2009-12-04 11:41:11 +03:00
pci_set_drvdata ( pdev , NULL ) ;
2009-12-03 04:06:15 +03:00
}
2009-12-04 11:41:11 +03:00
EXPORT_SYMBOL_GPL ( mantis_pci_exit ) ;
2009-12-03 04:06:15 +03:00
MODULE_DESCRIPTION ( " Mantis PCI DTV bridge driver " ) ;
MODULE_AUTHOR ( " Manu Abraham " ) ;
MODULE_LICENSE ( " GPL " ) ;