aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c171
1 files changed, 103 insertions, 68 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 206c834d263a..84c757ba0664 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -392,6 +392,14 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
392 if (state > PCI_D3hot) 392 if (state > PCI_D3hot)
393 state = PCI_D3hot; 393 state = PCI_D3hot;
394 394
395 /*
396 * If the device or the parent bridge can't support PCI PM, ignore
397 * the request if we're doing anything besides putting it into D0
398 * (which would only happen on boot).
399 */
400 if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev))
401 return 0;
402
395 /* Validate current state: 403 /* Validate current state:
396 * Can enter D0 from any state, but if we can only go deeper 404 * Can enter D0 from any state, but if we can only go deeper
397 * to sleep if we're already in a low power state 405 * to sleep if we're already in a low power state
@@ -403,13 +411,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
403 } else if (dev->current_state == state) 411 } else if (dev->current_state == state)
404 return 0; /* we're already there */ 412 return 0; /* we're already there */
405 413
406 /*
407 * If the device or the parent bridge can't support PCI PM, ignore
408 * the request if we're doing anything besides putting it into D0
409 * (which would only happen on boot).
410 */
411 if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev))
412 return 0;
413 414
414 /* find PCI PM capability in list */ 415 /* find PCI PM capability in list */
415 pm = pci_find_capability(dev, PCI_CAP_ID_PM); 416 pm = pci_find_capability(dev, PCI_CAP_ID_PM);
@@ -633,8 +634,6 @@ pci_save_state(struct pci_dev *dev)
633 pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); 634 pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
634 if ((i = pci_save_msi_state(dev)) != 0) 635 if ((i = pci_save_msi_state(dev)) != 0)
635 return i; 636 return i;
636 if ((i = pci_save_msix_state(dev)) != 0)
637 return i;
638 if ((i = pci_save_pcie_state(dev)) != 0) 637 if ((i = pci_save_pcie_state(dev)) != 0)
639 return i; 638 return i;
640 if ((i = pci_save_pcix_state(dev)) != 0) 639 if ((i = pci_save_pcix_state(dev)) != 0)
@@ -672,22 +671,11 @@ pci_restore_state(struct pci_dev *dev)
672 } 671 }
673 pci_restore_pcix_state(dev); 672 pci_restore_pcix_state(dev);
674 pci_restore_msi_state(dev); 673 pci_restore_msi_state(dev);
675 pci_restore_msix_state(dev); 674
676 return 0; 675 return 0;
677} 676}
678 677
679/** 678static int do_pci_enable_device(struct pci_dev *dev, int bars)
680 * pci_enable_device_bars - Initialize some of a device for use
681 * @dev: PCI device to be initialized
682 * @bars: bitmask of BAR's that must be configured
683 *
684 * Initialize device before it's used by a driver. Ask low-level code
685 * to enable selected I/O and memory resources. Wake up the device if it
686 * was suspended. Beware, this function can fail.
687 */
688
689int
690pci_enable_device_bars(struct pci_dev *dev, int bars)
691{ 679{
692 int err; 680 int err;
693 681
@@ -697,30 +685,47 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
697 err = pcibios_enable_device(dev, bars); 685 err = pcibios_enable_device(dev, bars);
698 if (err < 0) 686 if (err < 0)
699 return err; 687 return err;
688 pci_fixup_device(pci_fixup_enable, dev);
689
700 return 0; 690 return 0;
701} 691}
702 692
703/** 693/**
704 * __pci_enable_device - Initialize device before it's used by a driver. 694 * __pci_reenable_device - Resume abandoned device
695 * @dev: PCI device to be resumed
696 *
697 * Note this function is a backend of pci_default_resume and is not supposed
698 * to be called by normal code, write proper resume handler and use it instead.
699 */
700int
701__pci_reenable_device(struct pci_dev *dev)
702{
703 if (atomic_read(&dev->enable_cnt))
704 return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1);
705 return 0;
706}
707
708/**
709 * pci_enable_device_bars - Initialize some of a device for use
705 * @dev: PCI device to be initialized 710 * @dev: PCI device to be initialized
711 * @bars: bitmask of BAR's that must be configured
706 * 712 *
707 * Initialize device before it's used by a driver. Ask low-level code 713 * Initialize device before it's used by a driver. Ask low-level code
708 * to enable I/O and memory. Wake up the device if it was suspended. 714 * to enable selected I/O and memory resources. Wake up the device if it
709 * Beware, this function can fail. 715 * was suspended. Beware, this function can fail.
710 *
711 * Note this function is a backend and is not supposed to be called by
712 * normal code, use pci_enable_device() instead.
713 */ 716 */
714int 717int
715__pci_enable_device(struct pci_dev *dev) 718pci_enable_device_bars(struct pci_dev *dev, int bars)
716{ 719{
717 int err; 720 int err;
718 721
719 err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); 722 if (atomic_add_return(1, &dev->enable_cnt) > 1)
720 if (err) 723 return 0; /* already enabled */
721 return err; 724
722 pci_fixup_device(pci_fixup_enable, dev); 725 err = do_pci_enable_device(dev, bars);
723 return 0; 726 if (err < 0)
727 atomic_dec(&dev->enable_cnt);
728 return err;
724} 729}
725 730
726/** 731/**
@@ -736,13 +741,7 @@ __pci_enable_device(struct pci_dev *dev)
736 */ 741 */
737int pci_enable_device(struct pci_dev *dev) 742int pci_enable_device(struct pci_dev *dev)
738{ 743{
739 int result; 744 return pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
740 if (atomic_add_return(1, &dev->enable_cnt) > 1)
741 return 0; /* already enabled */
742 result = __pci_enable_device(dev);
743 if (result < 0)
744 atomic_dec(&dev->enable_cnt);
745 return result;
746} 745}
747 746
748/** 747/**
@@ -921,6 +920,47 @@ err_out:
921 return -EBUSY; 920 return -EBUSY;
922} 921}
923 922
923/**
924 * pci_release_selected_regions - Release selected PCI I/O and memory resources
925 * @pdev: PCI device whose resources were previously reserved
926 * @bars: Bitmask of BARs to be released
927 *
928 * Release selected PCI I/O and memory resources previously reserved.
929 * Call this function only after all use of the PCI regions has ceased.
930 */
931void pci_release_selected_regions(struct pci_dev *pdev, int bars)
932{
933 int i;
934
935 for (i = 0; i < 6; i++)
936 if (bars & (1 << i))
937 pci_release_region(pdev, i);
938}
939
940/**
941 * pci_request_selected_regions - Reserve selected PCI I/O and memory resources
942 * @pdev: PCI device whose resources are to be reserved
943 * @bars: Bitmask of BARs to be requested
944 * @res_name: Name to be associated with resource
945 */
946int pci_request_selected_regions(struct pci_dev *pdev, int bars,
947 const char *res_name)
948{
949 int i;
950
951 for (i = 0; i < 6; i++)
952 if (bars & (1 << i))
953 if(pci_request_region(pdev, i, res_name))
954 goto err_out;
955 return 0;
956
957err_out:
958 while(--i >= 0)
959 if (bars & (1 << i))
960 pci_release_region(pdev, i);
961
962 return -EBUSY;
963}
924 964
925/** 965/**
926 * pci_release_regions - Release reserved PCI I/O and memory resources 966 * pci_release_regions - Release reserved PCI I/O and memory resources
@@ -933,10 +973,7 @@ err_out:
933 973
934void pci_release_regions(struct pci_dev *pdev) 974void pci_release_regions(struct pci_dev *pdev)
935{ 975{
936 int i; 976 pci_release_selected_regions(pdev, (1 << 6) - 1);
937
938 for (i = 0; i < 6; i++)
939 pci_release_region(pdev, i);
940} 977}
941 978
942/** 979/**
@@ -954,18 +991,7 @@ void pci_release_regions(struct pci_dev *pdev)
954 */ 991 */
955int pci_request_regions(struct pci_dev *pdev, const char *res_name) 992int pci_request_regions(struct pci_dev *pdev, const char *res_name)
956{ 993{
957 int i; 994 return pci_request_selected_regions(pdev, ((1 << 6) - 1), res_name);
958
959 for (i = 0; i < 6; i++)
960 if(pci_request_region(pdev, i, res_name))
961 goto err_out;
962 return 0;
963
964err_out:
965 while(--i >= 0)
966 pci_release_region(pdev, i);
967
968 return -EBUSY;
969} 995}
970 996
971/** 997/**
@@ -1148,7 +1174,23 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
1148 return 0; 1174 return 0;
1149} 1175}
1150#endif 1176#endif
1151 1177
1178/**
1179 * pci_select_bars - Make BAR mask from the type of resource
1180 * @pdev: the PCI device for which BAR mask is made
1181 * @flags: resource type mask to be selected
1182 *
1183 * This helper routine makes bar mask from the type of resource.
1184 */
1185int pci_select_bars(struct pci_dev *dev, unsigned long flags)
1186{
1187 int i, bars = 0;
1188 for (i = 0; i < PCI_NUM_RESOURCES; i++)
1189 if (pci_resource_flags(dev, i) & flags)
1190 bars |= (1 << i);
1191 return bars;
1192}
1193
1152static int __devinit pci_init(void) 1194static int __devinit pci_init(void)
1153{ 1195{
1154 struct pci_dev *dev = NULL; 1196 struct pci_dev *dev = NULL;
@@ -1181,12 +1223,6 @@ early_param("pci", pci_setup);
1181 1223
1182device_initcall(pci_init); 1224device_initcall(pci_init);
1183 1225
1184#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
1185/* FIXME: Some boxes have multiple ISA bridges! */
1186struct pci_dev *isa_bridge;
1187EXPORT_SYMBOL(isa_bridge);
1188#endif
1189
1190EXPORT_SYMBOL_GPL(pci_restore_bars); 1226EXPORT_SYMBOL_GPL(pci_restore_bars);
1191EXPORT_SYMBOL(pci_enable_device_bars); 1227EXPORT_SYMBOL(pci_enable_device_bars);
1192EXPORT_SYMBOL(pci_enable_device); 1228EXPORT_SYMBOL(pci_enable_device);
@@ -1197,6 +1233,8 @@ EXPORT_SYMBOL(pci_release_regions);
1197EXPORT_SYMBOL(pci_request_regions); 1233EXPORT_SYMBOL(pci_request_regions);
1198EXPORT_SYMBOL(pci_release_region); 1234EXPORT_SYMBOL(pci_release_region);
1199EXPORT_SYMBOL(pci_request_region); 1235EXPORT_SYMBOL(pci_request_region);
1236EXPORT_SYMBOL(pci_release_selected_regions);
1237EXPORT_SYMBOL(pci_request_selected_regions);
1200EXPORT_SYMBOL(pci_set_master); 1238EXPORT_SYMBOL(pci_set_master);
1201EXPORT_SYMBOL(pci_set_mwi); 1239EXPORT_SYMBOL(pci_set_mwi);
1202EXPORT_SYMBOL(pci_clear_mwi); 1240EXPORT_SYMBOL(pci_clear_mwi);
@@ -1205,13 +1243,10 @@ EXPORT_SYMBOL(pci_set_dma_mask);
1205EXPORT_SYMBOL(pci_set_consistent_dma_mask); 1243EXPORT_SYMBOL(pci_set_consistent_dma_mask);
1206EXPORT_SYMBOL(pci_assign_resource); 1244EXPORT_SYMBOL(pci_assign_resource);
1207EXPORT_SYMBOL(pci_find_parent_resource); 1245EXPORT_SYMBOL(pci_find_parent_resource);
1246EXPORT_SYMBOL(pci_select_bars);
1208 1247
1209EXPORT_SYMBOL(pci_set_power_state); 1248EXPORT_SYMBOL(pci_set_power_state);
1210EXPORT_SYMBOL(pci_save_state); 1249EXPORT_SYMBOL(pci_save_state);
1211EXPORT_SYMBOL(pci_restore_state); 1250EXPORT_SYMBOL(pci_restore_state);
1212EXPORT_SYMBOL(pci_enable_wake); 1251EXPORT_SYMBOL(pci_enable_wake);
1213 1252
1214/* Quirk info */
1215
1216EXPORT_SYMBOL(isa_dma_bridge_buggy);
1217EXPORT_SYMBOL(pci_pci_problems);