s390/pci: add zpci_set_irq()/zpci_clear_irq()

Pull the directed vs floating IRQ check into common
zpci_set_irq()/zpci_clear_irq() functions and expose them for the rest
of the zPCI subsystem. Furthermore we add a zdev flag bit to easily
check if IRQs are registered. This is needed for use in resetting a zPCI
function.

Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
Niklas Schnelle 2020-12-10 15:28:05 +01:00 committed by Vasily Gorbik
parent e2bc3e91d9
commit c1e18c17bd
2 changed files with 42 additions and 11 deletions

View File

@ -133,7 +133,8 @@ struct zpci_dev {
u8 has_resources : 1;
u8 is_physfn : 1;
u8 util_str_avail : 1;
u8 reserved : 3;
u8 irqs_registered : 1;
u8 reserved : 2;
unsigned int devfn; /* DEVFN part of the RID*/
struct mutex lock;
@ -271,9 +272,13 @@ struct zpci_dev *get_zdev_by_fid(u32);
int zpci_dma_init(void);
void zpci_dma_exit(void);
/* IRQ */
int __init zpci_irq_init(void);
void __init zpci_irq_exit(void);
int zpci_set_irq(struct zpci_dev *zdev);
int zpci_clear_irq(struct zpci_dev *zdev);
/* FMB */
int zpci_fmb_enable_device(struct zpci_dev *);
int zpci_fmb_disable_device(struct zpci_dev *);

View File

@ -35,7 +35,7 @@ static struct airq_iv *zpci_sbv;
*/
static struct airq_iv **zpci_ibv;
/* Modify PCI: Register adapter interruptions */
/* Modify PCI: Register floating adapter interruptions */
static int zpci_set_airq(struct zpci_dev *zdev)
{
u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT);
@ -53,7 +53,7 @@ static int zpci_set_airq(struct zpci_dev *zdev)
return zpci_mod_fc(req, &fib, &status) ? -EIO : 0;
}
/* Modify PCI: Unregister adapter interruptions */
/* Modify PCI: Unregister floating adapter interruptions */
static int zpci_clear_airq(struct zpci_dev *zdev)
{
u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_DEREG_INT);
@ -98,6 +98,38 @@ static int zpci_clear_directed_irq(struct zpci_dev *zdev)
return cc ? -EIO : 0;
}
/* Register adapter interruptions */
int zpci_set_irq(struct zpci_dev *zdev)
{
int rc;
if (irq_delivery == DIRECTED)
rc = zpci_set_directed_irq(zdev);
else
rc = zpci_set_airq(zdev);
if (!rc)
zdev->irqs_registered = 1;
return rc;
}
/* Clear adapter interruptions */
int zpci_clear_irq(struct zpci_dev *zdev)
{
int rc;
if (irq_delivery == DIRECTED)
rc = zpci_clear_directed_irq(zdev);
else
rc = zpci_clear_airq(zdev);
if (!rc)
zdev->irqs_registered = 0;
return rc;
}
static int zpci_set_irq_affinity(struct irq_data *data, const struct cpumask *dest,
bool force)
{
@ -311,10 +343,7 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
zdev->msi_first_bit = bit;
zdev->msi_nr_irqs = msi_vecs;
if (irq_delivery == DIRECTED)
rc = zpci_set_directed_irq(zdev);
else
rc = zpci_set_airq(zdev);
rc = zpci_set_irq(zdev);
if (rc)
return rc;
@ -328,10 +357,7 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
int rc;
/* Disable interrupts */
if (irq_delivery == DIRECTED)
rc = zpci_clear_directed_irq(zdev);
else
rc = zpci_clear_airq(zdev);
rc = zpci_clear_irq(zdev);
if (rc)
return;