diff options
author | Len Brown <len.brown@intel.com> | 2009-09-19 01:56:39 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-09-19 01:56:39 -0400 |
commit | 3b87bb640e77023c97cf209e3dd85887a1113ad0 (patch) | |
tree | c4531d2c954bcc28706837cc67a8865677e51fbf /drivers/acpi/processor_core.c | |
parent | 7a92d803227a523a9a5546e4e0dce1325a4b5926 (diff) | |
parent | dcf52fb71d988ba945054308f661bddf9b2455fb (diff) |
Merge branch 'bjorn-start-stop-2.6.32' into release
Diffstat (limited to 'drivers/acpi/processor_core.c')
-rw-r--r-- | drivers/acpi/processor_core.c | 219 |
1 files changed, 95 insertions, 124 deletions
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index b4a1ab297e7b..b972107a1ef2 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -81,7 +81,6 @@ MODULE_DESCRIPTION("ACPI Processor Driver"); | |||
81 | MODULE_LICENSE("GPL"); | 81 | MODULE_LICENSE("GPL"); |
82 | 82 | ||
83 | static int acpi_processor_add(struct acpi_device *device); | 83 | static int acpi_processor_add(struct acpi_device *device); |
84 | static int acpi_processor_start(struct acpi_device *device); | ||
85 | static int acpi_processor_remove(struct acpi_device *device, int type); | 84 | static int acpi_processor_remove(struct acpi_device *device, int type); |
86 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); | 85 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); |
87 | static void acpi_processor_notify(struct acpi_device *device, u32 event); | 86 | static void acpi_processor_notify(struct acpi_device *device, u32 event); |
@@ -103,7 +102,6 @@ static struct acpi_driver acpi_processor_driver = { | |||
103 | .ops = { | 102 | .ops = { |
104 | .add = acpi_processor_add, | 103 | .add = acpi_processor_add, |
105 | .remove = acpi_processor_remove, | 104 | .remove = acpi_processor_remove, |
106 | .start = acpi_processor_start, | ||
107 | .suspend = acpi_processor_suspend, | 105 | .suspend = acpi_processor_suspend, |
108 | .resume = acpi_processor_resume, | 106 | .resume = acpi_processor_resume, |
109 | .notify = acpi_processor_notify, | 107 | .notify = acpi_processor_notify, |
@@ -700,92 +698,6 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
700 | 698 | ||
701 | static DEFINE_PER_CPU(void *, processor_device_array); | 699 | static DEFINE_PER_CPU(void *, processor_device_array); |
702 | 700 | ||
703 | static int __cpuinit acpi_processor_start(struct acpi_device *device) | ||
704 | { | ||
705 | int result = 0; | ||
706 | struct acpi_processor *pr; | ||
707 | struct sys_device *sysdev; | ||
708 | |||
709 | pr = acpi_driver_data(device); | ||
710 | |||
711 | result = acpi_processor_get_info(device); | ||
712 | if (result) { | ||
713 | /* Processor is physically not present */ | ||
714 | return 0; | ||
715 | } | ||
716 | |||
717 | BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); | ||
718 | |||
719 | /* | ||
720 | * Buggy BIOS check | ||
721 | * ACPI id of processors can be reported wrongly by the BIOS. | ||
722 | * Don't trust it blindly | ||
723 | */ | ||
724 | if (per_cpu(processor_device_array, pr->id) != NULL && | ||
725 | per_cpu(processor_device_array, pr->id) != device) { | ||
726 | printk(KERN_WARNING "BIOS reported wrong ACPI id " | ||
727 | "for the processor\n"); | ||
728 | return -ENODEV; | ||
729 | } | ||
730 | per_cpu(processor_device_array, pr->id) = device; | ||
731 | |||
732 | per_cpu(processors, pr->id) = pr; | ||
733 | |||
734 | result = acpi_processor_add_fs(device); | ||
735 | if (result) | ||
736 | goto end; | ||
737 | |||
738 | sysdev = get_cpu_sysdev(pr->id); | ||
739 | if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) | ||
740 | return -EFAULT; | ||
741 | |||
742 | /* _PDC call should be done before doing anything else (if reqd.). */ | ||
743 | arch_acpi_processor_init_pdc(pr); | ||
744 | acpi_processor_set_pdc(pr); | ||
745 | arch_acpi_processor_cleanup_pdc(pr); | ||
746 | |||
747 | #ifdef CONFIG_CPU_FREQ | ||
748 | acpi_processor_ppc_has_changed(pr); | ||
749 | #endif | ||
750 | acpi_processor_get_throttling_info(pr); | ||
751 | acpi_processor_get_limit_info(pr); | ||
752 | |||
753 | |||
754 | acpi_processor_power_init(pr, device); | ||
755 | |||
756 | pr->cdev = thermal_cooling_device_register("Processor", device, | ||
757 | &processor_cooling_ops); | ||
758 | if (IS_ERR(pr->cdev)) { | ||
759 | result = PTR_ERR(pr->cdev); | ||
760 | goto end; | ||
761 | } | ||
762 | |||
763 | dev_info(&device->dev, "registered as cooling_device%d\n", | ||
764 | pr->cdev->id); | ||
765 | |||
766 | result = sysfs_create_link(&device->dev.kobj, | ||
767 | &pr->cdev->device.kobj, | ||
768 | "thermal_cooling"); | ||
769 | if (result) | ||
770 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
771 | result = sysfs_create_link(&pr->cdev->device.kobj, | ||
772 | &device->dev.kobj, | ||
773 | "device"); | ||
774 | if (result) | ||
775 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
776 | |||
777 | if (pr->flags.throttling) { | ||
778 | printk(KERN_INFO PREFIX "%s [%s] (supports", | ||
779 | acpi_device_name(device), acpi_device_bid(device)); | ||
780 | printk(" %d throttling states", pr->throttling.state_count); | ||
781 | printk(")\n"); | ||
782 | } | ||
783 | |||
784 | end: | ||
785 | |||
786 | return result; | ||
787 | } | ||
788 | |||
789 | static void acpi_processor_notify(struct acpi_device *device, u32 event) | 701 | static void acpi_processor_notify(struct acpi_device *device, u32 event) |
790 | { | 702 | { |
791 | struct acpi_processor *pr = acpi_driver_data(device); | 703 | struct acpi_processor *pr = acpi_driver_data(device); |
@@ -848,10 +760,8 @@ static struct notifier_block acpi_cpu_notifier = | |||
848 | static int acpi_processor_add(struct acpi_device *device) | 760 | static int acpi_processor_add(struct acpi_device *device) |
849 | { | 761 | { |
850 | struct acpi_processor *pr = NULL; | 762 | struct acpi_processor *pr = NULL; |
851 | 763 | int result = 0; | |
852 | 764 | struct sys_device *sysdev; | |
853 | if (!device) | ||
854 | return -EINVAL; | ||
855 | 765 | ||
856 | pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); | 766 | pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); |
857 | if (!pr) | 767 | if (!pr) |
@@ -867,7 +777,100 @@ static int acpi_processor_add(struct acpi_device *device) | |||
867 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); | 777 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); |
868 | device->driver_data = pr; | 778 | device->driver_data = pr; |
869 | 779 | ||
780 | result = acpi_processor_get_info(device); | ||
781 | if (result) { | ||
782 | /* Processor is physically not present */ | ||
783 | return 0; | ||
784 | } | ||
785 | |||
786 | BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); | ||
787 | |||
788 | /* | ||
789 | * Buggy BIOS check | ||
790 | * ACPI id of processors can be reported wrongly by the BIOS. | ||
791 | * Don't trust it blindly | ||
792 | */ | ||
793 | if (per_cpu(processor_device_array, pr->id) != NULL && | ||
794 | per_cpu(processor_device_array, pr->id) != device) { | ||
795 | printk(KERN_WARNING "BIOS reported wrong ACPI id " | ||
796 | "for the processor\n"); | ||
797 | result = -ENODEV; | ||
798 | goto err_free_cpumask; | ||
799 | } | ||
800 | per_cpu(processor_device_array, pr->id) = device; | ||
801 | |||
802 | per_cpu(processors, pr->id) = pr; | ||
803 | |||
804 | result = acpi_processor_add_fs(device); | ||
805 | if (result) | ||
806 | goto err_free_cpumask; | ||
807 | |||
808 | sysdev = get_cpu_sysdev(pr->id); | ||
809 | if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) { | ||
810 | result = -EFAULT; | ||
811 | goto err_remove_fs; | ||
812 | } | ||
813 | |||
814 | /* _PDC call should be done before doing anything else (if reqd.). */ | ||
815 | arch_acpi_processor_init_pdc(pr); | ||
816 | acpi_processor_set_pdc(pr); | ||
817 | arch_acpi_processor_cleanup_pdc(pr); | ||
818 | |||
819 | #ifdef CONFIG_CPU_FREQ | ||
820 | acpi_processor_ppc_has_changed(pr); | ||
821 | #endif | ||
822 | acpi_processor_get_throttling_info(pr); | ||
823 | acpi_processor_get_limit_info(pr); | ||
824 | |||
825 | |||
826 | acpi_processor_power_init(pr, device); | ||
827 | |||
828 | pr->cdev = thermal_cooling_device_register("Processor", device, | ||
829 | &processor_cooling_ops); | ||
830 | if (IS_ERR(pr->cdev)) { | ||
831 | result = PTR_ERR(pr->cdev); | ||
832 | goto err_power_exit; | ||
833 | } | ||
834 | |||
835 | dev_info(&device->dev, "registered as cooling_device%d\n", | ||
836 | pr->cdev->id); | ||
837 | |||
838 | result = sysfs_create_link(&device->dev.kobj, | ||
839 | &pr->cdev->device.kobj, | ||
840 | "thermal_cooling"); | ||
841 | if (result) { | ||
842 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
843 | goto err_thermal_unregister; | ||
844 | } | ||
845 | result = sysfs_create_link(&pr->cdev->device.kobj, | ||
846 | &device->dev.kobj, | ||
847 | "device"); | ||
848 | if (result) { | ||
849 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
850 | goto err_remove_sysfs; | ||
851 | } | ||
852 | |||
853 | if (pr->flags.throttling) { | ||
854 | printk(KERN_INFO PREFIX "%s [%s] (supports", | ||
855 | acpi_device_name(device), acpi_device_bid(device)); | ||
856 | printk(" %d throttling states", pr->throttling.state_count); | ||
857 | printk(")\n"); | ||
858 | } | ||
859 | |||
870 | return 0; | 860 | return 0; |
861 | |||
862 | err_remove_sysfs: | ||
863 | sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); | ||
864 | err_thermal_unregister: | ||
865 | thermal_cooling_device_unregister(pr->cdev); | ||
866 | err_power_exit: | ||
867 | acpi_processor_power_exit(pr, device); | ||
868 | err_remove_fs: | ||
869 | acpi_processor_remove_fs(device); | ||
870 | err_free_cpumask: | ||
871 | free_cpumask_var(pr->throttling.shared_cpu_map); | ||
872 | |||
873 | return result; | ||
871 | } | 874 | } |
872 | 875 | ||
873 | static int acpi_processor_remove(struct acpi_device *device, int type) | 876 | static int acpi_processor_remove(struct acpi_device *device, int type) |
@@ -944,7 +947,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) | |||
944 | { | 947 | { |
945 | acpi_handle phandle; | 948 | acpi_handle phandle; |
946 | struct acpi_device *pdev; | 949 | struct acpi_device *pdev; |
947 | struct acpi_processor *pr; | ||
948 | 950 | ||
949 | 951 | ||
950 | if (acpi_get_parent(handle, &phandle)) { | 952 | if (acpi_get_parent(handle, &phandle)) { |
@@ -959,15 +961,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) | |||
959 | return -ENODEV; | 961 | return -ENODEV; |
960 | } | 962 | } |
961 | 963 | ||
962 | acpi_bus_start(*device); | ||
963 | |||
964 | pr = acpi_driver_data(*device); | ||
965 | if (!pr) | ||
966 | return -ENODEV; | ||
967 | |||
968 | if ((pr->id >= 0) && (pr->id < nr_cpu_ids)) { | ||
969 | kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE); | ||
970 | } | ||
971 | return 0; | 964 | return 0; |
972 | } | 965 | } |
973 | 966 | ||
@@ -997,25 +990,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle, | |||
997 | "Unable to add the device\n"); | 990 | "Unable to add the device\n"); |
998 | break; | 991 | break; |
999 | } | 992 | } |
1000 | |||
1001 | pr = acpi_driver_data(device); | ||
1002 | if (!pr) { | ||
1003 | printk(KERN_ERR PREFIX "Driver data is NULL\n"); | ||
1004 | break; | ||
1005 | } | ||
1006 | |||
1007 | if (pr->id >= 0 && (pr->id < nr_cpu_ids)) { | ||
1008 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | ||
1009 | break; | ||
1010 | } | ||
1011 | |||
1012 | result = acpi_processor_start(device); | ||
1013 | if ((!result) && ((pr->id >= 0) && (pr->id < nr_cpu_ids))) { | ||
1014 | kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); | ||
1015 | } else { | ||
1016 | printk(KERN_ERR PREFIX "Device [%s] failed to start\n", | ||
1017 | acpi_device_bid(device)); | ||
1018 | } | ||
1019 | break; | 993 | break; |
1020 | case ACPI_NOTIFY_EJECT_REQUEST: | 994 | case ACPI_NOTIFY_EJECT_REQUEST: |
1021 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 995 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -1032,9 +1006,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle, | |||
1032 | "Driver data is NULL, dropping EJECT\n"); | 1006 | "Driver data is NULL, dropping EJECT\n"); |
1033 | return; | 1007 | return; |
1034 | } | 1008 | } |
1035 | |||
1036 | if ((pr->id < nr_cpu_ids) && (cpu_present(pr->id))) | ||
1037 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | ||
1038 | break; | 1009 | break; |
1039 | default: | 1010 | default: |
1040 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1011 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |