On Wed, Sep 19, 2012 at 12:54 PM, Yinghai Lu <yinghai@xxxxxxxxxx> wrote: > when __ARCH_HAS_VGA_DEFAULT_DEVICE is not defined, aka EFIFB is not used, > for static path, vga_default setting is through vga_arbiter_add_pci_device. > and later x86 pci_fixup_video, will skip setting again. > - subsys_initcall(vga_arb_device_init) come first to call vga_arbiter_add_pci_device. It will call pci_get_dev to hold one reference. > > for hotplug add path, even vga_arbiter_add_pci_device is called via notifier, > but it will check VGA_RSRC_LEGACY_MASK that is not set for hotplug path. > So x86 pci_fixup_video will take over to call vga_set_default_device(). > It will not hold one refrence. > > Later for hotplug remove path, vga_arbiter_del_pci_device that does not check > VGA_RSRC_LEGACY_MASK will call put_device and it will cause ref_count to > decrease extra. that will have that pci device get deleted early wrongly. > > Need to make get/put balance for both cases. > > -v2: According to Bjorn, update vga_set_default_device instead... > > Signed-off-by: Yinghai Lu <yinghai@xxxxxxxxxx> > Cc: x86@xxxxxxxxxx > Cc: Dave Airlie <airlied@xxxxxxxxxx> > Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> > Cc: Julia Lawall <julia@xxxxxxx> > Cc: Matthew Garrett <mjg@xxxxxxxxxx> > --- > drivers/gpu/vga/vgaarb.c | 14 +++++++++----- > 1 files changed, 9 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c > index b6852b7..0888951e 100644 > --- a/drivers/gpu/vga/vgaarb.c > +++ b/drivers/gpu/vga/vgaarb.c > @@ -141,6 +141,12 @@ EXPORT_SYMBOL_GPL(vga_default_device); > > void vga_set_default_device(struct pci_dev *pdev) > { > + if (vga_default) > + pci_dev_put(vga_default); > + > + if (pdev) > + pdev = pci_dev_get(pdev); > + > vga_default = pdev; I think this is equivalent to: pci_dev_put(vga_default); vga_default = pci_dev_get(pdev); I haven't seen an answer to Matthew's question about whether we want to check for "vga_default == pdev". > } > #endif > @@ -577,7 +583,7 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev) > #ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE > if (vga_default == NULL && > ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) > - vga_default = pci_dev_get(pdev); > + vga_set_default_device(pdev); > #endif > > vga_arbiter_check_bridge_sharing(vgadev); > @@ -613,10 +619,8 @@ static bool vga_arbiter_del_pci_device(struct pci_dev *pdev) > } > > #ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE > - if (vga_default == pdev) { > - pci_dev_put(vga_default); > - vga_default = NULL; > - } > + if (vga_default == pdev) > + vga_set_default_device(NULL); > #endif > > if (vgadev->decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)) > -- > 1.7.7 > -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html