aboutsummaryrefslogtreecommitdiff
path: root/hw/lpc_ich9.c
diff options
context:
space:
mode:
authorJason Baron <jbaron@redhat.com>2013-01-22 19:11:37 -0700
committerMichael S. Tsirkin <mst@redhat.com>2013-01-30 01:31:09 +0200
commit91c3f2f00810a9ba5e4404c9611197efd8f694c8 (patch)
tree317b938e539954fda77f338ad20aeab4e3dcdaa3 /hw/lpc_ich9.c
parentdd23454ba2c83168b453155365671e67723b881f (diff)
ich9: add support for pci assignment
Fills out support for the pci assignment API. Added: PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin) Add calls to pci_bus_fire_intx_routing_notifier() when routing changes are made. Signed-off-by: Jason Baron <jbaron@redhat.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/lpc_ich9.c')
-rw-r--r--hw/lpc_ich9.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c
index 16843d76bc..e25689bf87 100644
--- a/hw/lpc_ich9.c
+++ b/hw/lpc_ich9.c
@@ -158,6 +158,7 @@ static void ich9_cc_write(void *opaque, hwaddr addr,
ich9_cc_addr_len(&addr, &len);
memcpy(lpc->chip_config + addr, &val, len);
+ pci_bus_fire_intx_routing_notifier(lpc->d.bus);
ich9_cc_update(lpc);
}
@@ -286,6 +287,32 @@ int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx)
return lpc->irr[PCI_SLOT(pci_dev->devfn)][intx];
}
+PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin)
+{
+ ICH9LPCState *lpc = opaque;
+ PCIINTxRoute route;
+ int pic_irq;
+ int pic_dis;
+
+ assert(0 <= pirq_pin);
+ assert(pirq_pin < ICH9_LPC_NB_PIRQS);
+
+ route.mode = PCI_INTX_ENABLED;
+ ich9_lpc_pic_irq(lpc, pirq_pin, &pic_irq, &pic_dis);
+ if (!pic_dis) {
+ if (pic_irq < ICH9_LPC_PIC_NUM_PINS) {
+ route.irq = pic_irq;
+ } else {
+ route.mode = PCI_INTX_DISABLED;
+ route.irq = -1;
+ }
+ } else {
+ route.irq = ich9_pirq_to_gsi(pirq_pin);
+ }
+
+ return route;
+}
+
static int ich9_lpc_sci_irq(ICH9LPCState *lpc)
{
switch (lpc->d.config[ICH9_LPC_ACPI_CTRL] &
@@ -405,6 +432,12 @@ static void ich9_lpc_config_write(PCIDevice *d,
if (ranges_overlap(addr, len, ICH9_LPC_RCBA, 4)) {
ich9_lpc_rcba_update(lpc, rbca_old);
}
+ if (ranges_overlap(addr, len, ICH9_LPC_PIRQA_ROUT, 4)) {
+ pci_bus_fire_intx_routing_notifier(lpc->d.bus);
+ }
+ if (ranges_overlap(addr, len, ICH9_LPC_PIRQE_ROUT, 4)) {
+ pci_bus_fire_intx_routing_notifier(lpc->d.bus);
+ }
}
static void ich9_lpc_reset(DeviceState *qdev)