Commit e724385a authored by Corey Minyard's avatar Corey Minyard Committed by Paolo Bonzini
Browse files

i2c: pm_smbus: Add interrupt handling



Add the necessary code so that interrupts actually work from
the pm_smbus device.

Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <1534796770-10295-7-git-send-email-minyard@acm.org>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 38ad4fae
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -214,6 +214,12 @@ static void smb_transaction_start(PMSMBus *s)
    s->smb_stat |= STS_HOST_BUSY;
}

static bool
smb_irq_value(PMSMBus *s)
{
    return ((s->smb_stat & ~STS_HOST_BUSY) != 0) && (s->smb_ctl & CTL_INTREN);
}

static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
                              unsigned width)
{
@@ -309,7 +315,9 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
    }

 out:
    return;
    if (s->set_irq) {
        s->set_irq(s, smb_irq_value(s));
    }
}

static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
@@ -365,6 +373,10 @@ static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
    SMBUS_DPRINTF("SMB readb port=0x%04" HWADDR_PRIx " val=0x%02x\n",
                  addr, val);

    if (s->set_irq) {
        s->set_irq(s, smb_irq_value(s));
    }

    return val;
}

+16 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@
typedef struct ICH9SMBState {
    PCIDevice dev;

    bool irq_enabled;

    PMSMBus smb;
} ICH9SMBState;

@@ -109,11 +111,25 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data)
    dc->user_creatable = false;
}

static void ich9_smb_set_irq(PMSMBus *pmsmb, bool enabled)
{
    ICH9SMBState *s = pmsmb->opaque;

    if (enabled == s->irq_enabled) {
        return;
    }

    s->irq_enabled = enabled;
    pci_set_irq(&s->dev, enabled);
}

I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
{
    PCIDevice *d =
        pci_create_simple_multifunction(bus, devfn, true, TYPE_ICH9_SMB_DEVICE);
    ICH9SMBState *s = ICH9_SMB_DEVICE(d);
    s->smb.set_irq = ich9_smb_set_irq;
    s->smb.opaque = s;
    return s->smb.smbus;
}

+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ typedef struct PMSMBus {

    /* Set by the user. */
    bool i2c_enable;
    void (*set_irq)(struct PMSMBus *s, bool enabled);
    void *opaque;

    /* Internally used by pm_smbus. */