2012-11-29 12:50:30 +01:00
/*
* Copyright IBM Corp . 2012
*
* Author ( s ) :
* Jan Glauber < jang @ linux . vnet . ibm . com >
*
* The System z PCI code is a rewrite from a prototype by
* the following people ( Kudoz ! ) :
2012-12-06 14:06:28 +01:00
* Alexander Schmidt
* Christoph Raisch
* Hannes Hering
* Hoang - Nam Nguyen
* Jan - Bernd Themann
* Stefan Roscher
* Thomas Klein
2012-11-29 12:50:30 +01:00
*/
2014-07-16 17:21:01 +02:00
# define KMSG_COMPONENT "zpci"
# define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
2012-11-29 12:50:30 +01:00
# include <linux/kernel.h>
# include <linux/slab.h>
# include <linux/err.h>
# include <linux/export.h>
# include <linux/delay.h>
2012-11-29 13:05:05 +01:00
# include <linux/irq.h>
# include <linux/kernel_stat.h>
2012-11-29 12:50:30 +01:00
# include <linux/seq_file.h>
# include <linux/pci.h>
# include <linux/msi.h>
2012-11-29 13:05:05 +01:00
# include <asm/isc.h>
# include <asm/airq.h>
2012-11-29 12:50:30 +01:00
# include <asm/facility.h>
# include <asm/pci_insn.h>
2012-11-29 12:55:21 +01:00
# include <asm/pci_clp.h>
2012-11-29 14:33:30 +01:00
# include <asm/pci_dma.h>
2012-11-29 12:50:30 +01:00
# define DEBUG /* enable pr_debug */
2012-11-29 13:05:05 +01:00
# define SIC_IRQ_MODE_ALL 0
# define SIC_IRQ_MODE_SINGLE 1
2012-11-29 12:50:30 +01:00
# define ZPCI_NR_DMA_SPACES 1
# define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS
/* list of all detected zpci devices */
2013-08-29 19:33:16 +02:00
static LIST_HEAD ( zpci_list ) ;
2013-08-29 19:40:01 +02:00
static DEFINE_SPINLOCK ( zpci_list_lock ) ;
2012-11-29 12:50:30 +01:00
2013-06-27 09:01:09 +02:00
static struct irq_chip zpci_irq_chip = {
. name = " zPCI " ,
2014-11-23 12:23:20 +01:00
. irq_unmask = pci_msi_unmask_irq ,
. irq_mask = pci_msi_mask_irq ,
2012-11-29 13:05:05 +01:00
} ;
2013-06-27 09:01:09 +02:00
static DECLARE_BITMAP ( zpci_domain , ZPCI_NR_DEVICES ) ;
static DEFINE_SPINLOCK ( zpci_domain_lock ) ;
2012-11-29 13:05:05 +01:00
2013-06-25 16:36:29 +02:00
static struct airq_iv * zpci_aisb_iv ;
2013-06-27 09:01:09 +02:00
static struct airq_iv * zpci_aibv [ ZPCI_NR_DEVICES ] ;
2012-11-29 13:05:05 +01:00
2013-06-24 10:30:41 +02:00
/* Adapter interrupt definitions */
static void zpci_irq_handler ( struct airq_struct * airq ) ;
static struct airq_struct zpci_airq = {
. handler = zpci_irq_handler ,
. isc = PCI_ISC ,
} ;
2012-11-29 13:05:05 +01:00
2016-01-22 14:01:44 +01:00
# define ZPCI_IOMAP_ENTRIES \
min ( ( ( unsigned long ) CONFIG_PCI_NR_FUNCTIONS * PCI_BAR_COUNT ) , \
ZPCI_IOMAP_MAX_ENTRIES )
2012-11-29 12:50:30 +01:00
static DEFINE_SPINLOCK ( zpci_iomap_lock ) ;
2016-01-22 14:01:44 +01:00
static unsigned long * zpci_iomap_bitmap ;
2012-11-29 12:50:30 +01:00
struct zpci_iomap_entry * zpci_iomap_start ;
EXPORT_SYMBOL_GPL ( zpci_iomap_start ) ;
2012-12-11 14:53:35 +01:00
static struct kmem_cache * zdev_fmb_cache ;
2012-11-29 12:50:30 +01:00
struct zpci_dev * get_zdev_by_fid ( u32 fid )
{
struct zpci_dev * tmp , * zdev = NULL ;
2013-08-29 19:40:01 +02:00
spin_lock ( & zpci_list_lock ) ;
2012-11-29 12:50:30 +01:00
list_for_each_entry ( tmp , & zpci_list , entry ) {
if ( tmp - > fid = = fid ) {
zdev = tmp ;
break ;
}
}
2013-08-29 19:40:01 +02:00
spin_unlock ( & zpci_list_lock ) ;
2012-11-29 12:50:30 +01:00
return zdev ;
}
static struct zpci_dev * get_zdev_by_bus ( struct pci_bus * bus )
{
return ( bus & & bus - > sysdata ) ? ( struct zpci_dev * ) bus - > sysdata : NULL ;
}
int pci_domain_nr ( struct pci_bus * bus )
{
return ( ( struct zpci_dev * ) bus - > sysdata ) - > domain ;
}
EXPORT_SYMBOL_GPL ( pci_domain_nr ) ;
int pci_proc_domain ( struct pci_bus * bus )
{
return pci_domain_nr ( bus ) ;
}
EXPORT_SYMBOL_GPL ( pci_proc_domain ) ;
2012-11-29 13:05:05 +01:00
/* Modify PCI: Register adapter interruptions */
2013-06-25 16:36:29 +02:00
static int zpci_set_airq ( struct zpci_dev * zdev )
2012-11-29 13:05:05 +01:00
{
u64 req = ZPCI_CREATE_REQ ( zdev - > fh , 0 , ZPCI_MOD_FC_REG_INT ) ;
2013-10-22 15:19:24 +02:00
struct zpci_fib fib = { 0 } ;
2012-11-29 13:05:05 +01:00
2013-10-22 15:19:24 +02:00
fib . isc = PCI_ISC ;
fib . sum = 1 ; /* enable summary notifications */
fib . noi = airq_iv_end ( zdev - > aibv ) ;
fib . aibv = ( unsigned long ) zdev - > aibv - > vector ;
fib . aibvo = 0 ; /* each zdev has its own interrupt vector */
fib . aisb = ( unsigned long ) zpci_aisb_iv - > vector + ( zdev - > aisb / 64 ) * 8 ;
fib . aisbo = zdev - > aisb & 63 ;
2012-11-29 13:05:05 +01:00
2013-10-22 15:19:24 +02:00
return zpci_mod_fc ( req , & fib ) ;
2012-11-29 13:05:05 +01:00
}
struct mod_pci_args {
u64 base ;
u64 limit ;
u64 iota ;
2012-12-11 14:53:35 +01:00
u64 fmb_addr ;
2012-11-29 13:05:05 +01:00
} ;
static int mod_pci ( struct zpci_dev * zdev , int fn , u8 dmaas , struct mod_pci_args * args )
{
u64 req = ZPCI_CREATE_REQ ( zdev - > fh , dmaas , fn ) ;
2013-10-22 15:19:24 +02:00
struct zpci_fib fib = { 0 } ;
fib . pba = args - > base ;
fib . pal = args - > limit ;
fib . iota = args - > iota ;
fib . fmb_addr = args - > fmb_addr ;
return zpci_mod_fc ( req , & fib ) ;
2012-11-29 13:05:05 +01:00
}
2012-11-29 14:33:30 +01:00
/* Modify PCI: Register I/O address translation parameters */
int zpci_register_ioat ( struct zpci_dev * zdev , u8 dmaas ,
u64 base , u64 limit , u64 iota )
{
2012-12-11 14:53:35 +01:00
struct mod_pci_args args = { base , limit , iota , 0 } ;
2012-11-29 14:33:30 +01:00
WARN_ON_ONCE ( iota & 0x3fff ) ;
args . iota | = ZPCI_IOTA_RTTO_FLAG ;
return mod_pci ( zdev , ZPCI_MOD_FC_REG_IOAT , dmaas , & args ) ;
}
/* Modify PCI: Unregister I/O address translation parameters */
int zpci_unregister_ioat ( struct zpci_dev * zdev , u8 dmaas )
{
2012-12-11 14:53:35 +01:00
struct mod_pci_args args = { 0 , 0 , 0 , 0 } ;
2012-11-29 14:33:30 +01:00
return mod_pci ( zdev , ZPCI_MOD_FC_DEREG_IOAT , dmaas , & args ) ;
}
2012-11-29 13:05:05 +01:00
/* Modify PCI: Unregister adapter interruptions */
2013-06-25 16:36:29 +02:00
static int zpci_clear_airq ( struct zpci_dev * zdev )
2012-11-29 13:05:05 +01:00
{
2012-12-11 14:53:35 +01:00
struct mod_pci_args args = { 0 , 0 , 0 , 0 } ;
2012-11-29 13:05:05 +01:00
return mod_pci ( zdev , ZPCI_MOD_FC_DEREG_INT , 0 , & args ) ;
}
2012-12-11 14:53:35 +01:00
/* Modify PCI: Set PCI function measurement parameters */
int zpci_fmb_enable_device ( struct zpci_dev * zdev )
{
struct mod_pci_args args = { 0 , 0 , 0 , 0 } ;
if ( zdev - > fmb )
return - EINVAL ;
2013-02-25 22:09:25 +08:00
zdev - > fmb = kmem_cache_zalloc ( zdev_fmb_cache , GFP_KERNEL ) ;
2012-12-11 14:53:35 +01:00
if ( ! zdev - > fmb )
return - ENOMEM ;
WARN_ON ( ( u64 ) zdev - > fmb & 0xf ) ;
2015-04-10 14:33:08 +02:00
/* reset software counters */
atomic64_set ( & zdev - > allocated_pages , 0 ) ;
atomic64_set ( & zdev - > mapped_pages , 0 ) ;
atomic64_set ( & zdev - > unmapped_pages , 0 ) ;
2012-12-11 14:53:35 +01:00
args . fmb_addr = virt_to_phys ( zdev - > fmb ) ;
return mod_pci ( zdev , ZPCI_MOD_FC_SET_MEASURE , 0 , & args ) ;
}
/* Modify PCI: Disable PCI function measurement */
int zpci_fmb_disable_device ( struct zpci_dev * zdev )
{
struct mod_pci_args args = { 0 , 0 , 0 , 0 } ;
int rc ;
if ( ! zdev - > fmb )
return - EINVAL ;
/* Function measurement is disabled if fmb address is zero */
rc = mod_pci ( zdev , ZPCI_MOD_FC_SET_MEASURE , 0 , & args ) ;
kmem_cache_free ( zdev_fmb_cache , zdev - > fmb ) ;
zdev - > fmb = NULL ;
return rc ;
}
2012-11-29 12:50:30 +01:00
# define ZPCI_PCIAS_CFGSPC 15
static int zpci_cfg_load ( struct zpci_dev * zdev , int offset , u32 * val , u8 len )
{
u64 req = ZPCI_CREATE_REQ ( zdev - > fh , ZPCI_PCIAS_CFGSPC , len ) ;
u64 data ;
int rc ;
2013-06-25 14:52:23 +02:00
rc = zpci_load ( & data , req , offset ) ;
2013-04-16 14:17:15 +02:00
if ( ! rc ) {
data = data < < ( ( 8 - len ) * 8 ) ;
data = le64_to_cpu ( data ) ;
2012-11-29 12:50:30 +01:00
* val = ( u32 ) data ;
2013-04-16 14:17:15 +02:00
} else
2012-11-29 12:50:30 +01:00
* val = 0xffffffff ;
return rc ;
}
static int zpci_cfg_store ( struct zpci_dev * zdev , int offset , u32 val , u8 len )
{
u64 req = ZPCI_CREATE_REQ ( zdev - > fh , ZPCI_PCIAS_CFGSPC , len ) ;
u64 data = val ;
int rc ;
data = cpu_to_le64 ( data ) ;
data = data > > ( ( 8 - len ) * 8 ) ;
2013-06-25 14:52:23 +02:00
rc = zpci_store ( data , req , offset ) ;
2012-11-29 12:50:30 +01:00
return rc ;
}
2012-12-21 14:06:37 -08:00
void pcibios_fixup_bus ( struct pci_bus * bus )
2012-11-29 12:50:30 +01:00
{
}
resource_size_t pcibios_align_resource ( void * data , const struct resource * res ,
resource_size_t size ,
resource_size_t align )
{
return 0 ;
}
2012-12-06 14:30:28 +01:00
/* combine single writes by using store-block insn */
void __iowrite64_copy ( void __iomem * to , const void * from , size_t count )
{
zpci_memcpy_toio ( to , from , count ) ;
}
2012-11-29 12:50:30 +01:00
/* Create a virtual mapping cookie for a PCI BAR */
2013-05-29 11:52:21 +09:30
void __iomem * pci_iomap_range ( struct pci_dev * pdev ,
int bar ,
unsigned long offset ,
unsigned long max )
2012-11-29 12:50:30 +01:00
{
2015-06-23 14:06:35 +02:00
struct zpci_dev * zdev = to_zpci ( pdev ) ;
2012-11-29 12:50:30 +01:00
int idx ;
2016-01-22 14:03:06 +01:00
if ( ! pci_resource_len ( pdev , bar ) )
2012-11-29 12:50:30 +01:00
return NULL ;
idx = zdev - > bars [ bar ] . map_idx ;
spin_lock ( & zpci_iomap_lock ) ;
2013-05-29 11:52:21 +09:30
/* Detect overrun */
2016-01-22 14:11:21 +01:00
WARN_ON ( ! + + zpci_iomap_start [ idx ] . count ) ;
zpci_iomap_start [ idx ] . fh = zdev - > fh ;
zpci_iomap_start [ idx ] . bar = bar ;
2012-11-29 12:50:30 +01:00
spin_unlock ( & zpci_iomap_lock ) ;
2016-01-22 13:58:42 +01:00
return ( void __iomem * ) ZPCI_ADDR ( idx ) + offset ;
2012-11-29 12:50:30 +01:00
}
2015-02-27 16:43:55 +01:00
EXPORT_SYMBOL ( pci_iomap_range ) ;
2013-05-29 11:52:21 +09:30
void __iomem * pci_iomap ( struct pci_dev * dev , int bar , unsigned long maxlen )
{
return pci_iomap_range ( dev , bar , 0 , maxlen ) ;
}
EXPORT_SYMBOL ( pci_iomap ) ;
2012-11-29 12:50:30 +01:00
void pci_iounmap ( struct pci_dev * pdev , void __iomem * addr )
{
2016-01-22 13:58:42 +01:00
unsigned int idx = ZPCI_IDX ( addr ) ;
2012-11-29 12:50:30 +01:00
spin_lock ( & zpci_iomap_lock ) ;
2013-05-29 11:52:21 +09:30
/* Detect underrun */
2016-01-22 14:11:21 +01:00
WARN_ON ( ! zpci_iomap_start [ idx ] . count ) ;
2013-05-29 11:52:21 +09:30
if ( ! - - zpci_iomap_start [ idx ] . count ) {
zpci_iomap_start [ idx ] . fh = 0 ;
zpci_iomap_start [ idx ] . bar = 0 ;
}
2012-11-29 12:50:30 +01:00
spin_unlock ( & zpci_iomap_lock ) ;
}
2015-02-27 16:43:55 +01:00
EXPORT_SYMBOL ( pci_iounmap ) ;
2012-11-29 12:50:30 +01:00
static int pci_read ( struct pci_bus * bus , unsigned int devfn , int where ,
int size , u32 * val )
{
struct zpci_dev * zdev = get_zdev_by_bus ( bus ) ;
2013-04-16 14:18:41 +02:00
int ret ;
2012-11-29 12:50:30 +01:00
if ( ! zdev | | devfn ! = ZPCI_DEVFN )
2013-04-16 14:18:41 +02:00
ret = - ENODEV ;
else
ret = zpci_cfg_load ( zdev , where , val , size ) ;
return ret ;
2012-11-29 12:50:30 +01:00
}
static int pci_write ( struct pci_bus * bus , unsigned int devfn , int where ,
int size , u32 val )
{
struct zpci_dev * zdev = get_zdev_by_bus ( bus ) ;
2013-04-16 14:18:41 +02:00
int ret ;
2012-11-29 12:50:30 +01:00
if ( ! zdev | | devfn ! = ZPCI_DEVFN )
2013-04-16 14:18:41 +02:00
ret = - ENODEV ;
else
ret = zpci_cfg_store ( zdev , where , val , size ) ;
return ret ;
2012-11-29 12:50:30 +01:00
}
static struct pci_ops pci_root_ops = {
. read = pci_read ,
. write = pci_write ,
} ;
2013-06-24 10:30:41 +02:00
static void zpci_irq_handler ( struct airq_struct * airq )
2012-11-29 13:05:05 +01:00
{
2013-06-25 16:36:29 +02:00
unsigned long si , ai ;
2013-06-27 09:01:09 +02:00
struct airq_iv * aibv ;
2013-06-25 16:36:29 +02:00
int irqs_on = 0 ;
2012-11-29 13:05:05 +01:00
2013-01-02 15:18:18 +01:00
inc_irq_stat ( IRQIO_PCI ) ;
2013-06-25 16:36:29 +02:00
for ( si = 0 ; ; ) {
/* Scan adapter summary indicator bit vector */
si = airq_iv_scan ( zpci_aisb_iv , si , airq_iv_end ( zpci_aisb_iv ) ) ;
if ( si = = - 1UL ) {
if ( irqs_on + + )
/* End of second scan with interrupts on. */
break ;
/* First scan complete, reenable interrupts. */
zpci_set_irq_ctrl ( SIC_IRQ_MODE_SINGLE , NULL , PCI_ISC ) ;
si = 0 ;
continue ;
}
2012-11-29 13:05:05 +01:00
2013-06-25 16:36:29 +02:00
/* Scan the adapter interrupt vector for this device. */
2013-06-27 09:01:09 +02:00
aibv = zpci_aibv [ si ] ;
2013-06-25 16:36:29 +02:00
for ( ai = 0 ; ; ) {
2013-06-27 09:01:09 +02:00
ai = airq_iv_scan ( aibv , ai , airq_iv_end ( aibv ) ) ;
2013-06-25 16:36:29 +02:00
if ( ai = = - 1UL )
break ;
2013-01-02 15:18:18 +01:00
inc_irq_stat ( IRQIO_MSI ) ;
2013-06-27 09:01:09 +02:00
airq_iv_lock ( aibv , ai ) ;
generic_handle_irq ( airq_iv_get_data ( aibv , ai ) ) ;
airq_iv_unlock ( aibv , ai ) ;
2012-11-29 13:05:05 +01:00
}
}
2013-06-25 16:36:29 +02:00
}
2012-11-29 13:05:05 +01:00
2013-06-25 16:36:29 +02:00
int arch_setup_msi_irqs ( struct pci_dev * pdev , int nvec , int type )
2012-11-29 13:05:05 +01:00
{
2015-06-23 14:06:35 +02:00
struct zpci_dev * zdev = to_zpci ( pdev ) ;
2014-05-07 15:44:19 +00:00
unsigned int hwirq , msi_vecs ;
2013-06-25 16:36:29 +02:00
unsigned long aisb ;
2012-11-29 13:05:05 +01:00
struct msi_desc * msi ;
2013-06-27 09:01:09 +02:00
struct msi_msg msg ;
2014-05-07 15:44:19 +00:00
int rc , irq ;
2012-11-29 13:05:05 +01:00
2013-12-16 09:34:54 +01:00
if ( type = = PCI_CAP_ID_MSI & & nvec > 1 )
return 1 ;
2014-10-29 19:12:04 +01:00
msi_vecs = min_t ( unsigned int , nvec , zdev - > max_msi ) ;
2012-11-29 13:05:05 +01:00
2013-06-25 16:36:29 +02:00
/* Allocate adapter summary indicator bit */
rc = - EIO ;
aisb = airq_iv_alloc_bit ( zpci_aisb_iv ) ;
if ( aisb = = - 1UL )
goto out ;
2012-11-29 13:05:05 +01:00
zdev - > aisb = aisb ;
2013-06-25 16:36:29 +02:00
/* Create adapter interrupt vector */
rc = - ENOMEM ;
2013-06-27 09:01:09 +02:00
zdev - > aibv = airq_iv_create ( msi_vecs , AIRQ_IV_DATA | AIRQ_IV_BITLOCK ) ;
2013-06-25 16:36:29 +02:00
if ( ! zdev - > aibv )
goto out_si ;
2012-11-29 13:05:05 +01:00
2013-06-25 16:36:29 +02:00
/* Wire up shortcut pointer */
2013-06-27 09:01:09 +02:00
zpci_aibv [ aisb ] = zdev - > aibv ;
2013-06-25 16:36:29 +02:00
2013-06-27 09:01:09 +02:00
/* Request MSI interrupts */
hwirq = 0 ;
2015-07-09 16:00:39 +08:00
for_each_pci_msi_entry ( msi , pdev ) {
2013-06-27 09:01:09 +02:00
rc = - EIO ;
irq = irq_alloc_desc ( 0 ) ; /* Alloc irq on node 0 */
2014-05-07 15:44:19 +00:00
if ( irq < 0 )
2013-06-27 09:01:09 +02:00
goto out_msi ;
rc = irq_set_msi_desc ( irq , msi ) ;
2012-11-29 13:05:05 +01:00
if ( rc )
2013-06-25 16:36:29 +02:00
goto out_msi ;
2013-06-27 09:01:09 +02:00
irq_set_chip_and_handler ( irq , & zpci_irq_chip ,
handle_simple_irq ) ;
msg . data = hwirq ;
msg . address_lo = zdev - > msi_addr & 0xffffffff ;
msg . address_hi = zdev - > msi_addr > > 32 ;
2014-11-09 23:10:34 +08:00
pci_write_msi_msg ( irq , & msg ) ;
2013-06-27 09:01:09 +02:00
airq_iv_set_data ( zdev - > aibv , hwirq , irq ) ;
hwirq + + ;
2012-11-29 13:05:05 +01:00
}
2013-06-25 16:36:29 +02:00
/* Enable adapter interrupts */
rc = zpci_set_airq ( zdev ) ;
if ( rc )
goto out_msi ;
return ( msi_vecs = = nvec ) ? 0 : msi_vecs ;
out_msi :
2015-07-09 16:00:39 +08:00
for_each_pci_msi_entry ( msi , pdev ) {
2013-06-27 09:01:09 +02:00
if ( hwirq - - = = 0 )
2013-06-25 16:36:29 +02:00
break ;
2013-06-27 09:01:09 +02:00
irq_set_msi_desc ( msi - > irq , NULL ) ;
irq_free_desc ( msi - > irq ) ;
msi - > msg . address_lo = 0 ;
msi - > msg . address_hi = 0 ;
msi - > msg . data = 0 ;
msi - > irq = 0 ;
2012-11-29 13:05:05 +01:00
}
2013-06-27 09:01:09 +02:00
zpci_aibv [ aisb ] = NULL ;
2013-06-25 16:36:29 +02:00
airq_iv_release ( zdev - > aibv ) ;
out_si :
airq_iv_free_bit ( zpci_aisb_iv , aisb ) ;
out :
return rc ;
2012-11-29 13:05:05 +01:00
}
2013-06-25 16:36:29 +02:00
void arch_teardown_msi_irqs ( struct pci_dev * pdev )
2012-11-29 13:05:05 +01:00
{
2015-06-23 14:06:35 +02:00
struct zpci_dev * zdev = to_zpci ( pdev ) ;
2012-11-29 13:05:05 +01:00
struct msi_desc * msi ;
2013-06-25 16:36:29 +02:00
int rc ;
/* Disable adapter interrupts */
rc = zpci_clear_airq ( zdev ) ;
2013-10-22 15:17:19 +02:00
if ( rc )
2012-11-29 13:05:05 +01:00
return ;
2013-06-27 09:01:09 +02:00
/* Release MSI interrupts */
2015-07-09 16:00:39 +08:00
for_each_pci_msi_entry ( msi , pdev ) {
2014-07-08 10:08:05 +08:00
if ( msi - > msi_attrib . is_msix )
2014-11-23 11:55:58 +01:00
__pci_msix_desc_mask_irq ( msi , 1 ) ;
2014-07-08 10:08:05 +08:00
else
2014-11-23 11:55:58 +01:00
__pci_msi_desc_mask_irq ( msi , 1 , 1 ) ;
2013-06-27 09:01:09 +02:00
irq_set_msi_desc ( msi - > irq , NULL ) ;
irq_free_desc ( msi - > irq ) ;
msi - > msg . address_lo = 0 ;
msi - > msg . address_hi = 0 ;
msi - > msg . data = 0 ;
msi - > irq = 0 ;
}
2012-11-29 13:05:05 +01:00
2013-06-27 09:01:09 +02:00
zpci_aibv [ zdev - > aisb ] = NULL ;
2013-06-25 16:36:29 +02:00
airq_iv_release ( zdev - > aibv ) ;
airq_iv_free_bit ( zpci_aisb_iv , zdev - > aisb ) ;
2012-11-29 13:05:05 +01:00
}
2015-02-27 16:43:21 +01:00
static void zpci_map_resources ( struct pci_dev * pdev )
2012-11-29 12:50:30 +01:00
{
resource_size_t len ;
int i ;
for ( i = 0 ; i < PCI_BAR_COUNT ; i + + ) {
len = pci_resource_len ( pdev , i ) ;
if ( ! len )
continue ;
2014-10-30 10:30:45 +01:00
pdev - > resource [ i ] . start =
( resource_size_t __force ) pci_iomap ( pdev , i , 0 ) ;
2012-11-29 12:50:30 +01:00
pdev - > resource [ i ] . end = pdev - > resource [ i ] . start + len - 1 ;
}
2013-06-05 16:06:16 +02:00
}
2015-02-27 16:43:21 +01:00
static void zpci_unmap_resources ( struct pci_dev * pdev )
2013-06-05 16:06:16 +02:00
{
resource_size_t len ;
int i ;
for ( i = 0 ; i < PCI_BAR_COUNT ; i + + ) {
len = pci_resource_len ( pdev , i ) ;
if ( ! len )
continue ;
2014-10-30 10:30:45 +01:00
pci_iounmap ( pdev , ( void __iomem __force * )
pdev - > resource [ i ] . start ) ;
2013-06-05 16:06:16 +02:00
}
}
2012-11-29 12:50:30 +01:00
2012-11-29 13:05:05 +01:00
static int __init zpci_irq_init ( void )
{
2013-06-25 16:36:29 +02:00
int rc ;
2012-11-29 13:05:05 +01:00
2013-06-24 10:30:41 +02:00
rc = register_adapter_interrupt ( & zpci_airq ) ;
if ( rc )
2013-06-25 16:36:29 +02:00
goto out ;
2013-06-24 10:30:41 +02:00
/* Set summary to 1 to be called every time for the ISC. */
* zpci_airq . lsi_ptr = 1 ;
2012-11-29 13:05:05 +01:00
2013-06-25 16:36:29 +02:00
rc = - ENOMEM ;
zpci_aisb_iv = airq_iv_create ( ZPCI_NR_DEVICES , AIRQ_IV_ALLOC ) ;
if ( ! zpci_aisb_iv )
goto out_airq ;
2012-11-29 13:05:05 +01:00
2013-06-25 14:52:23 +02:00
zpci_set_irq_ctrl ( SIC_IRQ_MODE_SINGLE , NULL , PCI_ISC ) ;
2012-11-29 13:05:05 +01:00
return 0 ;
2013-06-25 16:36:29 +02:00
out_airq :
unregister_adapter_interrupt ( & zpci_airq ) ;
out :
2012-11-29 13:05:05 +01:00
return rc ;
}
static void zpci_irq_exit ( void )
{
2013-06-25 16:36:29 +02:00
airq_iv_release ( zpci_aisb_iv ) ;
2013-06-24 10:30:41 +02:00
unregister_adapter_interrupt ( & zpci_airq ) ;
2012-11-29 13:05:05 +01:00
}
2012-11-29 12:50:30 +01:00
static int zpci_alloc_iomap ( struct zpci_dev * zdev )
{
2016-01-22 13:59:35 +01:00
unsigned long entry ;
2012-11-29 12:50:30 +01:00
spin_lock ( & zpci_iomap_lock ) ;
2016-01-22 14:01:44 +01:00
entry = find_first_zero_bit ( zpci_iomap_bitmap , ZPCI_IOMAP_ENTRIES ) ;
if ( entry = = ZPCI_IOMAP_ENTRIES ) {
2012-11-29 12:50:30 +01:00
spin_unlock ( & zpci_iomap_lock ) ;
return - ENOSPC ;
}
2016-01-22 14:01:44 +01:00
set_bit ( entry , zpci_iomap_bitmap ) ;
2012-11-29 12:50:30 +01:00
spin_unlock ( & zpci_iomap_lock ) ;
return entry ;
}
static void zpci_free_iomap ( struct zpci_dev * zdev , int entry )
{
spin_lock ( & zpci_iomap_lock ) ;
memset ( & zpci_iomap_start [ entry ] , 0 , sizeof ( struct zpci_iomap_entry ) ) ;
2016-01-22 14:01:44 +01:00
clear_bit ( entry , zpci_iomap_bitmap ) ;
2012-11-29 12:50:30 +01:00
spin_unlock ( & zpci_iomap_lock ) ;
}
2013-11-12 19:33:06 +01:00
static struct resource * __alloc_res ( struct zpci_dev * zdev , unsigned long start ,
unsigned long size , unsigned long flags )
{
struct resource * r ;
r = kzalloc ( sizeof ( * r ) , GFP_KERNEL ) ;
if ( ! r )
return NULL ;
r - > start = start ;
r - > end = r - > start + size - 1 ;
r - > flags = flags ;
r - > name = zdev - > res_name ;
if ( request_resource ( & iomem_resource , r ) ) {
kfree ( r ) ;
return NULL ;
}
return r ;
}
static int zpci_setup_bus_resources ( struct zpci_dev * zdev ,
struct list_head * resources )
{
unsigned long addr , size , flags ;
struct resource * res ;
int i , entry ;
snprintf ( zdev - > res_name , sizeof ( zdev - > res_name ) ,
" PCI Bus %04x:%02x " , zdev - > domain , ZPCI_BUS_NR ) ;
for ( i = 0 ; i < PCI_BAR_COUNT ; i + + ) {
if ( ! zdev - > bars [ i ] . size )
continue ;
entry = zpci_alloc_iomap ( zdev ) ;
if ( entry < 0 )
return entry ;
zdev - > bars [ i ] . map_idx = entry ;
/* only MMIO is supported */
flags = IORESOURCE_MEM ;
if ( zdev - > bars [ i ] . val & 8 )
flags | = IORESOURCE_PREFETCH ;
if ( zdev - > bars [ i ] . val & 4 )
flags | = IORESOURCE_MEM_64 ;
2016-01-22 13:58:42 +01:00
addr = ZPCI_ADDR ( entry ) ;
2013-11-12 19:33:06 +01:00
size = 1UL < < zdev - > bars [ i ] . size ;
res = __alloc_res ( zdev , addr , size , flags ) ;
if ( ! res ) {
zpci_free_iomap ( zdev , entry ) ;
return - ENOMEM ;
}
zdev - > bars [ i ] . res = res ;
pci_add_resource ( resources , res ) ;
}
return 0 ;
}
static void zpci_cleanup_bus_resources ( struct zpci_dev * zdev )
{
int i ;
for ( i = 0 ; i < PCI_BAR_COUNT ; i + + ) {
2015-07-28 19:10:45 +02:00
if ( ! zdev - > bars [ i ] . size | | ! zdev - > bars [ i ] . res )
2013-11-12 19:33:06 +01:00
continue ;
zpci_free_iomap ( zdev , zdev - > bars [ i ] . map_idx ) ;
release_resource ( zdev - > bars [ i ] . res ) ;
kfree ( zdev - > bars [ i ] . res ) ;
}
}
2013-04-16 14:13:21 +02:00
int pcibios_add_device ( struct pci_dev * pdev )
{
2013-08-29 19:34:37 +02:00
struct resource * res ;
int i ;
2014-04-30 14:50:09 -06:00
pdev - > dev . groups = zpci_attr_groups ;
2016-02-02 21:46:34 -08:00
pdev - > dev . archdata . dma_ops = & s390_pci_dma_ops ;
2015-02-27 16:43:21 +01:00
zpci_map_resources ( pdev ) ;
2013-08-29 19:34:37 +02:00
for ( i = 0 ; i < PCI_BAR_COUNT ; i + + ) {
res = & pdev - > resource [ i ] ;
if ( res - > parent | | ! res - > flags )
continue ;
pci_claim_resource ( pdev , i ) ;
}
return 0 ;
}
2015-02-27 16:43:21 +01:00
void pcibios_release_device ( struct pci_dev * pdev )
{
zpci_unmap_resources ( pdev ) ;
}
2013-08-29 19:34:37 +02:00
int pcibios_enable_device ( struct pci_dev * pdev , int mask )
{
2015-06-23 14:06:35 +02:00
struct zpci_dev * zdev = to_zpci ( pdev ) ;
2013-04-16 14:13:21 +02:00
2016-01-29 15:13:30 +01:00
zpci_debug_init_device ( zdev , dev_name ( & pdev - > dev ) ) ;
2013-04-16 14:13:21 +02:00
zpci_fmb_enable_device ( zdev ) ;
2014-02-26 15:30:24 -07:00
return pci_enable_resources ( pdev , mask ) ;
2013-04-16 14:13:21 +02:00
}
2013-08-29 19:34:37 +02:00
void pcibios_disable_device ( struct pci_dev * pdev )
2013-06-05 16:06:16 +02:00
{
2015-06-23 14:06:35 +02:00
struct zpci_dev * zdev = to_zpci ( pdev ) ;
2013-06-05 16:06:16 +02:00
zpci_fmb_disable_device ( zdev ) ;
zpci_debug_exit_device ( zdev ) ;
}
2013-09-25 12:27:43 +02:00
# ifdef CONFIG_HIBERNATE_CALLBACKS
static int zpci_restore ( struct device * dev )
{
2015-02-27 16:43:21 +01:00
struct pci_dev * pdev = to_pci_dev ( dev ) ;
2015-06-23 14:06:35 +02:00
struct zpci_dev * zdev = to_zpci ( pdev ) ;
2013-09-25 12:27:43 +02:00
int ret = 0 ;
if ( zdev - > state ! = ZPCI_FN_STATE_ONLINE )
goto out ;
ret = clp_enable_fh ( zdev , ZPCI_NR_DMA_SPACES ) ;
if ( ret )
goto out ;
2015-02-27 16:43:21 +01:00
zpci_map_resources ( pdev ) ;
2015-11-16 14:35:48 +01:00
zpci_register_ioat ( zdev , 0 , zdev - > start_dma , zdev - > end_dma ,
2013-09-25 12:27:43 +02:00
( u64 ) zdev - > dma_table ) ;
out :
return ret ;
}
static int zpci_freeze ( struct device * dev )
{
2015-02-27 16:43:21 +01:00
struct pci_dev * pdev = to_pci_dev ( dev ) ;
2015-06-23 14:06:35 +02:00
struct zpci_dev * zdev = to_zpci ( pdev ) ;
2013-09-25 12:27:43 +02:00
if ( zdev - > state ! = ZPCI_FN_STATE_ONLINE )
return 0 ;
zpci_unregister_ioat ( zdev , 0 ) ;
2015-02-27 16:43:21 +01:00
zpci_unmap_resources ( pdev ) ;
2013-09-25 12:27:43 +02:00
return clp_disable_fh ( zdev ) ;
}
struct dev_pm_ops pcibios_pm_ops = {
. thaw_noirq = zpci_restore ,
. freeze_noirq = zpci_freeze ,
. restore_noirq = zpci_restore ,
. poweroff_noirq = zpci_freeze ,
} ;
# endif /* CONFIG_HIBERNATE_CALLBACKS */
2012-11-29 12:50:30 +01:00
static int zpci_alloc_domain ( struct zpci_dev * zdev )
{
spin_lock ( & zpci_domain_lock ) ;
zdev - > domain = find_first_zero_bit ( zpci_domain , ZPCI_NR_DEVICES ) ;
if ( zdev - > domain = = ZPCI_NR_DEVICES ) {
spin_unlock ( & zpci_domain_lock ) ;
return - ENOSPC ;
}
set_bit ( zdev - > domain , zpci_domain ) ;
spin_unlock ( & zpci_domain_lock ) ;
return 0 ;
}
static void zpci_free_domain ( struct zpci_dev * zdev )
{
spin_lock ( & zpci_domain_lock ) ;
clear_bit ( zdev - > domain , zpci_domain ) ;
spin_unlock ( & zpci_domain_lock ) ;
}
2013-11-12 19:35:01 +01:00
void pcibios_remove_bus ( struct pci_bus * bus )
{
struct zpci_dev * zdev = get_zdev_by_bus ( bus ) ;
zpci_exit_slot ( zdev ) ;
zpci_cleanup_bus_resources ( zdev ) ;
zpci_free_domain ( zdev ) ;
spin_lock ( & zpci_list_lock ) ;
list_del ( & zdev - > entry ) ;
spin_unlock ( & zpci_list_lock ) ;
kfree ( zdev ) ;
}
static int zpci_scan_bus ( struct zpci_dev * zdev )
{
LIST_HEAD ( resources ) ;
int ret ;
ret = zpci_setup_bus_resources ( zdev , & resources ) ;
if ( ret )
2015-07-28 19:10:45 +02:00
goto error ;
2013-11-12 19:35:01 +01:00
zdev - > bus = pci_scan_root_bus ( NULL , ZPCI_BUS_NR , & pci_root_ops ,
zdev , & resources ) ;
if ( ! zdev - > bus ) {
2015-07-28 19:10:45 +02:00
ret = - EIO ;
goto error ;
2013-11-12 19:35:01 +01:00
}
zdev - > bus - > max_bus_speed = zdev - > max_bus_speed ;
PCI: Assign resources before drivers claim devices (pci_scan_root_bus())
Previously, pci_scan_root_bus() created a root PCI bus, enumerated the
devices on it, and called pci_bus_add_devices(), which made the devices
available for drivers to claim them.
Most callers assigned resources to devices after pci_scan_root_bus()
returns, which may be after drivers have claimed the devices. This is
incorrect; the PCI core should not change device resources while a driver
is managing the device.
Remove pci_bus_add_devices() from pci_scan_root_bus() and do it after any
resource assignment in the callers.
Note that ARM's pci_common_init_dev() already called pci_bus_add_devices()
after pci_scan_root_bus(), so we only need to remove the first call:
pci_common_init_dev
pcibios_init_hw
pci_scan_root_bus
pci_bus_add_devices # first call
pci_bus_assign_resources
pci_bus_add_devices # second call
[bhelgaas: changelog, drop "root_bus" var in alpha common_init_pci(),
return failure earlier in mn10300, add "return" in x86 pcibios_scan_root(),
return early if xtensa platform_pcibios_fixup() fails]
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Richard Henderson <rth@twiddle.net>
CC: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
CC: Matt Turner <mattst88@gmail.com>
CC: David Howells <dhowells@redhat.com>
CC: Tony Luck <tony.luck@intel.com>
CC: Michal Simek <monstr@monstr.eu>
CC: Ralf Baechle <ralf@linux-mips.org>
CC: Koichi Yasutake <yasutake.koichi@jp.panasonic.com>
CC: Sebastian Ott <sebott@linux.vnet.ibm.com>
CC: "David S. Miller" <davem@davemloft.net>
CC: Chris Metcalf <cmetcalf@ezchip.com>
CC: Chris Zankel <chris@zankel.net>
CC: Max Filippov <jcmvbkbc@gmail.com>
CC: Thomas Gleixner <tglx@linutronix.de>
2015-03-16 11:18:56 +08:00
pci_bus_add_devices ( zdev - > bus ) ;
2013-11-12 19:35:01 +01:00
return 0 ;
2015-07-28 19:10:45 +02:00
error :
zpci_cleanup_bus_resources ( zdev ) ;
pci_free_resource_list ( & resources ) ;
return ret ;
2013-11-12 19:35:01 +01:00
}
2012-11-29 12:55:21 +01:00
int zpci_enable_device ( struct zpci_dev * zdev )
{
int rc ;
rc = clp_enable_fh ( zdev , ZPCI_NR_DMA_SPACES ) ;
if ( rc )
goto out ;
2012-11-29 14:33:30 +01:00
rc = zpci_dma_init_device ( zdev ) ;
if ( rc )
goto out_dma ;
2013-08-29 19:35:19 +02:00
zdev - > state = ZPCI_FN_STATE_ONLINE ;
2012-11-29 12:55:21 +01:00
return 0 ;
2012-11-29 14:33:30 +01:00
out_dma :
clp_disable_fh ( zdev ) ;
2012-11-29 12:55:21 +01:00
out :
return rc ;
}
EXPORT_SYMBOL_GPL ( zpci_enable_device ) ;
2013-04-16 14:12:17 +02:00
int zpci_disable_device ( struct zpci_dev * zdev )
{
zpci_dma_exit_device ( zdev ) ;
return clp_disable_fh ( zdev ) ;
}
EXPORT_SYMBOL_GPL ( zpci_disable_device ) ;
2012-11-29 12:50:30 +01:00
int zpci_create_device ( struct zpci_dev * zdev )
{
int rc ;
rc = zpci_alloc_domain ( zdev ) ;
if ( rc )
goto out ;
2015-04-10 14:34:33 +02:00
mutex_init ( & zdev - > lock ) ;
2013-04-25 14:49:48 +02:00
if ( zdev - > state = = ZPCI_FN_STATE_CONFIGURED ) {
rc = zpci_enable_device ( zdev ) ;
if ( rc )
goto out_free ;
}
rc = zpci_scan_bus ( zdev ) ;
2012-11-29 12:50:30 +01:00
if ( rc )
2013-04-25 14:49:48 +02:00
goto out_disable ;
2012-11-29 12:50:30 +01:00
2013-08-29 19:40:01 +02:00
spin_lock ( & zpci_list_lock ) ;
2012-11-29 12:50:30 +01:00
list_add_tail ( & zdev - > entry , & zpci_list ) ;
2013-08-29 19:40:01 +02:00
spin_unlock ( & zpci_list_lock ) ;
2012-11-29 12:50:30 +01:00
2013-08-29 19:33:16 +02:00
zpci_init_slot ( zdev ) ;
2012-11-29 12:50:30 +01:00
return 0 ;
2013-04-25 14:49:48 +02:00
out_disable :
if ( zdev - > state = = ZPCI_FN_STATE_ONLINE )
zpci_disable_device ( zdev ) ;
out_free :
2012-11-29 12:50:30 +01:00
zpci_free_domain ( zdev ) ;
out :
return rc ;
}
void zpci_stop_device ( struct zpci_dev * zdev )
{
2012-11-29 14:33:30 +01:00
zpci_dma_exit_device ( zdev ) ;
2012-11-29 12:50:30 +01:00
/*
* Note : SCLP disables fh via set - pci - fn so don ' t
* do that here .
*/
}
EXPORT_SYMBOL_GPL ( zpci_stop_device ) ;
2016-07-18 14:05:21 +02:00
int zpci_report_error ( struct pci_dev * pdev ,
struct zpci_report_error_header * report )
{
struct zpci_dev * zdev = to_zpci ( pdev ) ;
return sclp_pci_report ( report , zdev - > fh , zdev - > fid ) ;
}
EXPORT_SYMBOL ( zpci_report_error ) ;
2012-11-29 12:50:30 +01:00
static inline int barsize ( u8 size )
{
return ( size ) ? ( 1 < < size ) > > 10 : 0 ;
}
static int zpci_mem_init ( void )
{
2016-03-14 15:47:23 +01:00
BUILD_BUG_ON ( ! is_power_of_2 ( __alignof__ ( struct zpci_fmb ) ) | |
__alignof__ ( struct zpci_fmb ) < sizeof ( struct zpci_fmb ) ) ;
2012-12-11 14:53:35 +01:00
zdev_fmb_cache = kmem_cache_create ( " PCI_FMB_cache " , sizeof ( struct zpci_fmb ) ,
2016-03-14 15:47:23 +01:00
__alignof__ ( struct zpci_fmb ) , 0 , NULL ) ;
2012-12-11 14:53:35 +01:00
if ( ! zdev_fmb_cache )
2016-01-22 14:01:44 +01:00
goto error_fmb ;
2012-12-11 14:53:35 +01:00
2016-01-22 14:01:44 +01:00
zpci_iomap_start = kcalloc ( ZPCI_IOMAP_ENTRIES ,
sizeof ( * zpci_iomap_start ) , GFP_KERNEL ) ;
2012-11-29 12:50:30 +01:00
if ( ! zpci_iomap_start )
2012-11-29 13:05:05 +01:00
goto error_iomap ;
2012-11-29 12:50:30 +01:00
2016-01-22 14:01:44 +01:00
zpci_iomap_bitmap = kcalloc ( BITS_TO_LONGS ( ZPCI_IOMAP_ENTRIES ) ,
sizeof ( * zpci_iomap_bitmap ) , GFP_KERNEL ) ;
if ( ! zpci_iomap_bitmap )
goto error_iomap_bitmap ;
return 0 ;
error_iomap_bitmap :
kfree ( zpci_iomap_start ) ;
2012-11-29 13:05:05 +01:00
error_iomap :
2012-12-11 14:53:35 +01:00
kmem_cache_destroy ( zdev_fmb_cache ) ;
2016-01-22 14:01:44 +01:00
error_fmb :
2012-11-29 12:50:30 +01:00
return - ENOMEM ;
}
static void zpci_mem_exit ( void )
{
2016-01-22 14:01:44 +01:00
kfree ( zpci_iomap_bitmap ) ;
2012-11-29 12:50:30 +01:00
kfree ( zpci_iomap_start ) ;
2012-12-11 14:53:35 +01:00
kmem_cache_destroy ( zdev_fmb_cache ) ;
2012-11-29 12:50:30 +01:00
}
2013-12-12 17:55:22 +01:00
static unsigned int s390_pci_probe = 1 ;
2013-12-12 17:48:32 +01:00
static unsigned int s390_pci_initialized ;
2012-11-29 12:50:30 +01:00
char * __init pcibios_setup ( char * str )
{
2013-12-12 17:55:22 +01:00
if ( ! strcmp ( str , " off " ) ) {
s390_pci_probe = 0 ;
2012-11-29 12:50:30 +01:00
return NULL ;
}
return str ;
}
2013-12-12 17:48:32 +01:00
bool zpci_is_enabled ( void )
{
return s390_pci_initialized ;
}
2012-11-29 12:50:30 +01:00
static int __init pci_base_init ( void )
{
int rc ;
2013-01-30 15:52:16 +01:00
if ( ! s390_pci_probe )
2012-11-29 12:50:30 +01:00
return 0 ;
2015-02-14 11:23:21 +01:00
if ( ! test_facility ( 69 ) | | ! test_facility ( 71 ) | | ! test_facility ( 72 ) )
2012-11-29 12:50:30 +01:00
return 0 ;
2012-12-11 14:53:35 +01:00
rc = zpci_debug_init ( ) ;
if ( rc )
2013-06-27 09:01:09 +02:00
goto out ;
2012-12-11 14:53:35 +01:00
2012-11-29 12:50:30 +01:00
rc = zpci_mem_init ( ) ;
if ( rc )
goto out_mem ;
2012-11-29 13:05:05 +01:00
rc = zpci_irq_init ( ) ;
if ( rc )
goto out_irq ;
2012-11-29 14:33:30 +01:00
rc = zpci_dma_init ( ) ;
if ( rc )
goto out_dma ;
2013-08-29 19:37:28 +02:00
rc = clp_scan_pci_devices ( ) ;
2012-11-29 12:55:21 +01:00
if ( rc )
goto out_find ;
2013-12-12 17:48:32 +01:00
s390_pci_initialized = 1 ;
2012-11-29 12:50:30 +01:00
return 0 ;
2012-11-29 12:55:21 +01:00
out_find :
2012-11-29 14:33:30 +01:00
zpci_dma_exit ( ) ;
out_dma :
2012-11-29 13:05:05 +01:00
zpci_irq_exit ( ) ;
out_irq :
2012-11-29 12:50:30 +01:00
zpci_mem_exit ( ) ;
out_mem :
2012-12-11 14:53:35 +01:00
zpci_debug_exit ( ) ;
2013-06-27 09:01:09 +02:00
out :
2012-11-29 12:50:30 +01:00
return rc ;
}
2013-08-29 19:33:16 +02:00
subsys_initcall_sync ( pci_base_init ) ;
2013-08-29 19:40:01 +02:00
void zpci_rescan ( void )
{
2013-12-12 17:48:32 +01:00
if ( zpci_is_enabled ( ) )
clp_rescan_pci_devices_simple ( ) ;
2013-08-29 19:40:01 +02:00
}